Пример #1
0
void
noit_lua_check_deregister_event(noit_lua_check_info_t *ci, eventer_t e,
                                int tofree) {
  assert(ci->events);
  assert(noit_hash_delete(ci->events, (const char *)&e, sizeof(e),
                          NULL, tofree ? noit_event_dispose : free));
}
Пример #2
0
static void __deactivate_ci(struct dns_check_info *ci) {
  pthread_mutex_lock(&active_events_lock);
  assert(noit_hash_delete(&active_events, (void *)&ci, sizeof(ci), free, NULL));
  pthread_mutex_unlock(&active_events_lock);
  ci->check->flags &= ~NP_RUNNING;
  if(ci->h != NULL) {
    dns_module_dns_ctx_release(ci->h);
    ci->h = NULL;
  }
}
Пример #3
0
void
cancel_coro(noit_lua_check_info_t *ci) {
  lua_getglobal(ci->lmc->lua_state, "noit_coros");
  luaL_unref(ci->lmc->lua_state, -1, ci->coro_state_ref);
  lua_pop(ci->lmc->lua_state, 1);
  lua_gc(ci->lmc->lua_state, LUA_GCCOLLECT, 0);
  noit_hash_delete(&noit_coros,
                   (const char *)&ci->coro_state, sizeof(ci->coro_state),
                   NULL, NULL);
}
Пример #4
0
int
noit_filter_remove(noit_conf_section_t vnode) {
  int removed;
  char *name = (char *)xmlGetProp(vnode, (xmlChar *)"name");
  if(!name) return 0;
  LOCKFS();
  removed = noit_hash_delete(filtersets, name, strlen(name),
                             NULL, filterset_free);
  UNLOCKFS();
  return removed;
}
Пример #5
0
static void dns_ctx_release(dns_ctx_handle_t *h) {
  if(h->ns == NULL) {
    /* Special case for the default */
    noit_atomic_dec32(&h->refcnt);
    return;
  }
  pthread_mutex_lock(&dns_ctx_store_lock);
  if(noit_atomic_dec32(&h->refcnt) == 0) {
    /* I was the last one */
    assert(noit_hash_delete(&dns_ctx_store, h->ns, strlen(h->ns),
                            NULL, dns_ctx_handle_free));
  }
  pthread_mutex_unlock(&dns_ctx_store_lock);
}
Пример #6
0
static noit_hash_table *
stratcon_datastore_journal_remove(struct sockaddr *remote,
                                  const char *remote_cn) {
  void *vhash = NULL;
  if(noit_hash_retrieve(&working_sets, remote_cn, strlen(remote_cn), &vhash)) {
    /* pluck it out */
    noit_hash_delete(&working_sets, remote_cn, strlen(remote_cn), free, NULL);
  }
  else {
    noitL(noit_error, "attempted checkpoint on non-existing workingset: '%s'\n",
          remote_cn);
  }
  return vhash;
}
Пример #7
0
int
noit_poller_deschedule(uuid_t in) {
  void *vcheck;
  noit_check_t *checker;
  if(noit_hash_retrieve(&polls,
                        (char *)in, UUID_SIZE,
                        &vcheck) == 0) {
    return -1;
  }
  checker = (noit_check_t *)vcheck;
  checker->flags |= (NP_DISABLED|NP_KILLED);

  noit_skiplist_remove(&polls_by_name, checker, NULL);
  noit_hash_delete(&polls, (char *)in, UUID_SIZE, NULL, NULL);

  noit_poller_free_check(checker);
  return 0;
}
Пример #8
0
static int dns_module_dns_ctx_release(dns_ctx_handle_t *h) {
  int rv = 0, last;
  if(h->ns == NULL) {
    /* Special case for the default */
    noit_atomic_dec32(&h->refcnt);
    return rv;
  }
  pthread_mutex_lock(&dns_ctx_store_lock);
  last = noit_atomic_dec32(&h->refcnt);
  if(last == 0) {
    /* I was the last one */
    assert(noit_hash_delete(&dns_ctx_store, h->hkey, strlen(h->hkey),
                            NULL, dns_module_dns_ctx_handle_free));
    rv = 1;
  }
  pthread_mutex_unlock(&dns_ctx_store_lock);
  return rv;
}
Пример #9
0
static int ping_icmp_timeout(eventer_t e, int mask,
                             void *closure, struct timeval *now) {
  struct ping_closure *pcl = (struct ping_closure *)closure;
  struct ping_session_key k;
  struct check_info *data;
  ping_icmp_data_t *ping_data;

  if(!NOIT_CHECK_KILLED(pcl->check) && !NOIT_CHECK_DISABLED(pcl->check)) {
    ping_icmp_log_results(pcl->self, pcl->check);
  }
  data = (struct check_info *)pcl->check->closure;
  data->timeout_event = NULL;
  pcl->check->flags &= ~NP_RUNNING;
  ping_data = noit_module_get_userdata(pcl->self);
  k.addr_of_check = pcl->check;
  uuid_copy(k.checkid, pcl->check->checkid);
  noit_hash_delete(ping_data->in_flight, (const char *)&k, sizeof(k),
                   free, NULL);
  free(pcl);
  return 0;
}
Пример #10
0
void
noit_log_stream_remove(const char *name) {
  noit_hash_delete(&noit_loggers, name, strlen(name), NULL, NULL);
}
Пример #11
0
static int external_handler(eventer_t e, int mask,
                            void *closure, struct timeval *now) {
  noit_module_t *self = (noit_module_t *)closure;
  external_data_t *data;

  data = noit_module_get_userdata(self);
  while(1) {
    int inlen, expectlen;
    noit_check_t *check;
    struct check_info *ci;
    void *vci;

    if(!data->cr) {
      struct external_response r;
      struct msghdr msg;
      struct iovec v[3];
      memset(&r, 0, sizeof(r));
      v[0].iov_base = (char *)&r.check_no;
      v[0].iov_len = sizeof(r.check_no);
      v[1].iov_base = (char *)&r.exit_code;
      v[1].iov_len = sizeof(r.exit_code);
      v[2].iov_base = (char *)&r.stdoutlen;
      v[2].iov_len = sizeof(r.stdoutlen);
      expectlen = v[0].iov_len + v[1].iov_len + v[2].iov_len;

      /* Make this into a recv'ble message so we can PEEK */
      memset(&msg, 0, sizeof(msg));
      msg.msg_iov = v;
      msg.msg_iovlen = 3;
      inlen = recvmsg(e->fd, &msg, MSG_PEEK);
      if(inlen == 0) goto widowed;
      if((inlen == -1 && errno == EAGAIN) ||
         (inlen > 0 && inlen < expectlen))
        return EVENTER_READ | EVENTER_EXCEPTION;
      if(inlen == -1)
        noitL(noit_error, "recvmsg() failed: %s\n", strerror(errno));
      assert(inlen == expectlen);
      while(-1 == (inlen = recvmsg(e->fd, &msg, 0)) && errno == EINTR);
      assert(inlen == expectlen);
      data->cr = calloc(sizeof(*data->cr), 1);
      memcpy(data->cr, &r, sizeof(r));
      data->cr->stdoutbuff = malloc(data->cr->stdoutlen);
    }
    if(data->cr) {
      while(data->cr->stdoutlen_sofar < data->cr->stdoutlen) {
        while((inlen =
                 read(e->fd,
                      data->cr->stdoutbuff + data->cr->stdoutlen_sofar,
                      data->cr->stdoutlen - data->cr->stdoutlen_sofar)) == -1 &&
               errno == EINTR);
        if(inlen == -1 && errno == EAGAIN)
          return EVENTER_READ | EVENTER_EXCEPTION;
        if(inlen == 0) goto widowed;
        data->cr->stdoutlen_sofar += inlen;
      }
      assert(data->cr->stdoutbuff[data->cr->stdoutlen-1] == '\0');
      if(!data->cr->stderrbuff) {
        while((inlen = read(e->fd, &data->cr->stderrlen,
                            sizeof(data->cr->stderrlen))) == -1 &&
              errno == EINTR);
        if(inlen == -1 && errno == EAGAIN)
          return EVENTER_READ | EVENTER_EXCEPTION;
        if(inlen == 0) goto widowed;
        assert(inlen == sizeof(data->cr->stderrlen));
        data->cr->stderrbuff = malloc(data->cr->stderrlen);
      }
      while(data->cr->stderrlen_sofar < data->cr->stderrlen) {
        while((inlen =
                 read(e->fd,
                      data->cr->stderrbuff + data->cr->stderrlen_sofar,
                      data->cr->stderrlen - data->cr->stderrlen_sofar)) == -1 &&
               errno == EINTR);
        if(inlen == -1 && errno == EAGAIN)
          return EVENTER_READ | EVENTER_EXCEPTION;
        if(inlen == 0) goto widowed;
        data->cr->stderrlen_sofar += inlen;
      }
      assert(data->cr->stderrbuff[data->cr->stderrlen-1] == '\0');
    }
    assert(data->cr && data->cr->stdoutbuff && data->cr->stderrbuff);

    gettimeofday(now, NULL); /* set it, as we care about accuracy */

    /* Lookup data in check_no hash */
    if(noit_hash_retrieve(&data->external_checks,
                          (const char *)&data->cr->check_no,
                          sizeof(data->cr->check_no),
                          &vci) == 0)
      vci = NULL;
    ci = (struct check_info *)vci;

    /* We've seen it, it ain't coming again...
     * remove it, we'll free it ourselves */
    noit_hash_delete(&data->external_checks,
                     (const char *)&data->cr->check_no,
                     sizeof(data->cr->check_no), NULL, NULL);

    /* If there is no timeout_event, the check must have completed.
     * We have nothing to do. */
    if(!ci || !ci->timeout_event) {
      free(data->cr->stdoutbuff);
      free(data->cr->stderrbuff);
      free(data->cr);
      data->cr = NULL;
      continue;
    }
    ci->exit_code = data->cr->exit_code;
    ci->output = data->cr->stdoutbuff;
    ci->error = data->cr->stderrbuff;
    free(data->cr);
    data->cr = NULL;
    check = ci->check;
    external_log_results(self, check);
    eventer_remove(ci->timeout_event);
    free(ci->timeout_event->closure);
    eventer_free(ci->timeout_event);
    ci->timeout_event = NULL;
    check->flags &= ~NP_RUNNING;
  }

 widowed:
  noitL(noit_error, "external module terminated, must restart.\n");
  exit(1);
}
Пример #12
0
static void __deactivate_ci(struct dns_check_info *ci) {
  pthread_mutex_lock(&active_events_lock);
  assert(noit_hash_delete(&active_events, (void *)&ci, sizeof(ci), free, NULL));
  pthread_mutex_unlock(&active_events_lock);
}
Пример #13
0
static int ping_icmp_handler(eventer_t e, int mask,
                             void *closure, struct timeval *now) {
  noit_module_t *self = (noit_module_t *)closure;
  ping_icmp_data_t *ping_data;
  struct check_info *data;
  char packet[1500];
  int packet_len = sizeof(packet);
  union {
   struct sockaddr_in  in4;
   struct sockaddr_in6 in6;
  } from;
  unsigned int from_len;
  struct ip *ip = (struct ip *)packet;
  struct icmp *icp;
  struct ping_payload *payload;

  ping_data = noit_module_get_userdata(self);
  while(1) {
    struct ping_session_key k;
    int inlen, iphlen;
    void *vcheck;
    noit_check_t *check;
    struct timeval tt;

    from_len = sizeof(from);

    inlen = recvfrom(e->fd, packet, packet_len, 0,
                     (struct sockaddr *)&from, &from_len);
    gettimeofday(now, NULL); /* set it, as we care about accuracy */

    if(inlen < 0) {
      if(errno == EAGAIN || errno == EINTR) break;
      noitLT(nlerr, now, "ping_icmp recvfrom: %s\n", strerror(errno));
      break;
    }
    iphlen = ip->ip_hl << 2;
    if((inlen-iphlen) != (sizeof(struct icmp)+sizeof(struct ping_payload))) {
      noitLT(nldeb, now,
             "ping_icmp bad size: %d+%d\n", iphlen, inlen-iphlen); 
      continue;
    }
    icp = (struct icmp *)(packet + iphlen);
    payload = (struct ping_payload *)(icp + 1);
    if(icp->icmp_type != ICMP_ECHOREPLY) {
      continue;
    }
    if(icp->icmp_id != (((vpsized_uint)self) & 0xffff)) {
      noitLT(nlerr, now,
               "ping_icmp not sent from this instance (%d:%d) vs. %lu\n",
               icp->icmp_id, ntohs(icp->icmp_seq),
               (unsigned long)(((vpsized_uint)self) & 0xffff));
      continue;
    }
    check = NULL;
    k.addr_of_check = payload->addr_of_check;
    uuid_copy(k.checkid, payload->checkid);
    if(noit_hash_retrieve(ping_data->in_flight,
                          (const char *)&k, sizeof(k),
                          &vcheck))
      check = vcheck;

    /* make sure this check is from this generation! */
    if(!check) {
      char uuid_str[37];
      uuid_unparse_lower(payload->checkid, uuid_str);
      noitLT(nldeb, now,
             "ping_icmp response for unknown check '%s'\n", uuid_str);
      continue;
    }
    if(check->generation != payload->generation) {
      noitLT(nldeb, now,
             "ping_icmp response in generation gap\n");
      continue;
    }
    data = (struct check_info *)check->closure;

    /* If there is no timeout_event, the check must have completed.
     * We have nothing to do. */
    if(!data->timeout_event) continue;

    /* Sanity check the payload */
    if(payload->check_no != data->check_no) continue;
    if(payload->check_pack_cnt != data->expected_count) continue;
    if(payload->check_pack_no < 0 ||
       payload->check_pack_no >= data->expected_count) continue;

    sub_timeval(*now, payload->whence, &tt);
    data->turnaround[payload->check_pack_no] =
      (float)tt.tv_sec + (float)tt.tv_usec / 1000000.0;
    if(ping_icmp_is_complete(self, check)) {
      ping_icmp_log_results(self, check);
      eventer_remove(data->timeout_event);
      free(data->timeout_event->closure);
      eventer_free(data->timeout_event);
      data->timeout_event = NULL;
      check->flags &= ~NP_RUNNING;
      k.addr_of_check = check;
      uuid_copy(k.checkid, check->checkid);
      noit_hash_delete(ping_data->in_flight, (const char *)&k,
                       sizeof(k), free, NULL);
    }
  }
  return EVENTER_READ;
}
Пример #14
0
static void remove_check(struct check_info *c) {
  noit_hash_delete(&active_checks, (char *)&c->reqid, sizeof(c->reqid),
                   NULL, NULL);
}