Beispiel #1
0
static int
check_test_sweeper(eventer_t e, int mask, void *closure,
                   struct timeval *now) {
  int left = 0;
  noit_skiplist_node *iter = NULL;
  sweeper_event = NULL;
  iter = noit_skiplist_getlist(&in_progress);
  while(iter) {
    struct check_test_closure *cl = iter->data;
    /* advance here, we might delete */
    noit_skiplist_next(&in_progress,&iter);
    if(NOIT_CHECK_DISABLED(cl->check)) {
      if(NOIT_CHECK_SHOULD_RESOLVE(cl->check))
        noit_check_resolve(cl->check);
      if(NOIT_CHECK_RESOLVED(cl->check)) {
        noit_module_t *m = noit_module_lookup(cl->check->module);
        cl->check->flags &= ~NP_DISABLED;
        if(NOIT_CHECK_SHOULD_RESOLVE(cl->check))
          noitL(nldeb, "translated to %s\n", cl->check->target_ip);
        if(m) m->initiate_check(m, cl->check, 1, NULL);
      }
      left++;
    }
    else if(NOIT_CHECK_RUNNING(cl->check)) left++;
    else
      noit_skiplist_remove(&in_progress, cl->restc,
                           (noit_freefunc_t)rest_test_check_result);
  }

  if(left) check_test_schedule_sweeper();
  return 0;
}
int
noit_check_schedule_next(noit_module_t *self,
                         struct timeval *last_check, noit_check_t *check,
                         struct timeval *now, dispatch_func_t dispatch,
                         noit_check_t *cause) {
  eventer_t newe;
  struct timeval period, earliest;
  recur_closure_t *rcl;

  assert(cause == NULL);
  assert(check->fire_event == NULL);
  if(check->period == 0) return 0;
  if(NOIT_CHECK_DISABLED(check) || NOIT_CHECK_KILLED(check)) {
    if(!(check->flags & NP_TRANSIENT)) check_slots_dec_tv(last_check);
    return 0;
  }

  /* If we have an event, we know when we intended it to fire.  This means
   * we should schedule that point + period.
   */
  if(now)
    memcpy(&earliest, now, sizeof(earliest));
  else
    gettimeofday(&earliest, NULL);

  /* If the check is unconfigured and needs resolving, we'll set the
   * period down a bit lower so we can pick up the resolution quickly.
   */
  if(!NOIT_CHECK_RESOLVED(check) && NOIT_CHECK_SHOULD_RESOLVE(check) &&
      check->period > 1000) {
    period.tv_sec = 1;
    period.tv_usec = 0;
  }
  else {
    period.tv_sec = check->period / 1000;
    period.tv_usec = (check->period % 1000) * 1000;
  }

  newe = eventer_alloc();
  memcpy(&newe->whence, last_check, sizeof(*last_check));
  add_timeval(newe->whence, period, &newe->whence);
  if(compare_timeval(newe->whence, earliest) < 0)
    memcpy(&newe->whence, &earliest, sizeof(earliest));
  newe->mask = EVENTER_TIMER;
  newe->callback = noit_check_recur_handler;
  rcl = calloc(1, sizeof(*rcl));
  rcl->self = self;
  rcl->check = check;
  rcl->cause = cause;
  rcl->dispatch = dispatch;
  newe->closure = rcl;

  eventer_add(newe);
  check->fire_event = newe;
  return 0;
}
Beispiel #3
0
noit_check_t *
noit_fire_check(xmlNodePtr attr, xmlNodePtr config, const char **error) {
  char *target = NULL, *name = NULL, *module = NULL, *filterset = NULL;
  int timeout = 0;
  noit_module_t *m;
  noit_check_t *c = NULL;
  xmlNodePtr a, co;
  noit_hash_table *conf_hash = NULL;

  for(a = attr->children; a; a = a->next) {
    if(!strcmp((char *)a->name, "target"))
      target = (char *)xmlNodeGetContent(a);
    else if(!strcmp((char *)a->name, "name"))
      name = (char *)xmlNodeGetContent(a);
    else if(!strcmp((char *)a->name, "module"))
      module = (char *)xmlNodeGetContent(a);
    else if(!strcmp((char *)a->name, "filterset"))
      filterset = (char *)xmlNodeGetContent(a);
    else if(!strcmp((char *)a->name, "timeout")) {
      char *timeout_str = (char *)xmlNodeGetContent(a);
      timeout = atoi(timeout_str);
      free(timeout_str);
    }
  }
  m = noit_module_lookup(module);
  if(!m) {
    *error = "cannot find requested module";
    goto error;
  }
  conf_hash = calloc(1, sizeof(*conf_hash));
  for(co = config->children; co; co = co->next) {
    char *name, *val;
    xmlChar *tmp_val;
    name = strdup((char *)co->name);
    tmp_val = xmlNodeGetContent(co);
    val = strdup(tmp_val ? (char *)tmp_val : "");
    noit_hash_replace(conf_hash, name, strlen(name), val, free, free);
    xmlFree(tmp_val);
  }
  if(!m->initiate_check) {
    *error = "that module cannot run checks";
    goto error;
  }
  c = calloc(1, sizeof(*c));
  noit_check_update(c, target, name, filterset,
                    conf_hash, 0, timeout, NULL, NP_TRANSIENT);
  c->module = strdup(module);
  uuid_generate(c->checkid);
  c->flags |= NP_DISABLED; /* this is hack to know we haven't run it yet */
  if(NOIT_CHECK_SHOULD_RESOLVE(c))
    noit_check_resolve(c);

 error:
  if(conf_hash) {
    noit_hash_destroy(conf_hash, free, free);
    free(conf_hash);
  }
  if(target) xmlFree(target);
  if(name) xmlFree(name);
  if(module) xmlFree(module);
  if(filterset) xmlFree(filterset);
  return c;
}
Beispiel #4
0
noit_check_t *
noit_fire_check(xmlNodePtr attr, xmlNodePtr config, const char **error) {
  char *target = NULL, *name = NULL, *module = NULL, *filterset = NULL;
  char *resolve_rtype = NULL;
  int timeout = 0, flags = NP_TRANSIENT, i, mod_cnt;
  noit_module_t *m;
  noit_check_t *c = NULL;
  xmlNodePtr a, co;
  noit_hash_table *conf_hash = NULL;
  noit_hash_table **moptions = NULL;

  for(a = attr->children; a; a = a->next) {
    if(!strcmp((char *)a->name, "target"))
      target = (char *)xmlNodeGetContent(a);
    else if(!strcmp((char *)a->name, "name"))
      name = (char *)xmlNodeGetContent(a);
    else if(!strcmp((char *)a->name, "module"))
      module = (char *)xmlNodeGetContent(a);
    else if(!strcmp((char *)a->name, "filterset"))
      filterset = (char *)xmlNodeGetContent(a);
    else if(!strcmp((char *)a->name, "timeout")) {
      char *timeout_str = (char *)xmlNodeGetContent(a);
      timeout = atoi(timeout_str);
      free(timeout_str);
    } else if(!strcmp((char *)a->name, "resolve_rtype")) 
      resolve_rtype = (char *)xmlNodeGetContent(a);
  }
  m = noit_module_lookup(module);
  if(!m) {
    *error = "cannot find requested module";
    goto error;
  }
  conf_hash = calloc(1, sizeof(*conf_hash));
  if(config) {
    for(co = config->children; co; co = co->next) {
      char *name, *val;
      xmlChar *tmp_val;
      name = strdup((char *)co->name);
      tmp_val = xmlNodeGetContent(co);
      val = strdup(tmp_val ? (char *)tmp_val : "");
      noit_hash_replace(conf_hash, name, strlen(name), val, free, free);
      xmlFree(tmp_val);
    }
  }
  mod_cnt = noit_check_registered_module_cnt();
  if(mod_cnt > 0) {
    moptions = alloca(mod_cnt * sizeof(*moptions));
    memset(moptions, 0, mod_cnt * sizeof(*moptions));
    for(i=0; i<mod_cnt; i++) {
      const char *name;
      noit_conf_section_t checks;
      name = noit_check_registered_module(i);
      checks = noit_conf_get_section(NULL, "/noit/checks");
      if(name) moptions[i] = noit_conf_get_namespaced_hash(checks, "config", name);
    }
  }
  if(!m->initiate_check) {
    *error = "that module cannot run checks";
    goto error;
  }
  flags |= noit_calc_rtype_flag(resolve_rtype);
  c = calloc(1, sizeof(*c));
  noit_check_update(c, target, name, filterset,
                    conf_hash, moptions, 0, timeout, NULL, flags);
  c->module = strdup(module);
  uuid_generate(c->checkid);
  c->flags |= NP_DISABLED; /* this is hack to know we haven't run it yet */
  if(NOIT_CHECK_SHOULD_RESOLVE(c))
    noit_check_resolve(c);

 error:
  if(conf_hash) {
    noit_hash_destroy(conf_hash, free, free);
    free(conf_hash);
  }
  if(moptions) {
    for(i=0; i<mod_cnt; i++) {
      if(moptions[i]) {
        noit_hash_destroy(moptions[i], free, free);
        free(moptions[i]);
      }
    }
  }
  if(target) xmlFree(target);
  if(name) xmlFree(name);
  if(module) xmlFree(module);
  if(filterset) xmlFree(filterset);
  if (resolve_rtype) xmlFree(resolve_rtype);
  return c;
}
Beispiel #5
0
int
noit_check_schedule_next(noit_module_t *self,
                         struct timeval *last_check, noit_check_t *check,
                         struct timeval *now, dispatch_func_t dispatch,
                         noit_check_t *cause) {
  eventer_t newe;
  struct timeval period, earliest, diff;
  int64_t diffms, periodms, offsetms;
  recur_closure_t *rcl;
  int initial = last_check ? 1 : 0;

  assert(cause == NULL);
  assert(check->fire_event == NULL);
  if(check->period == 0) return 0;

  /* if last_check is not passed, we use the initial_schedule_time
   * otherwise, we set the initial_schedule_time
   */
  if(!last_check) last_check = &check->initial_schedule_time;
  else memcpy(&check->initial_schedule_time, last_check, sizeof(*last_check));

  if(NOIT_CHECK_DISABLED(check) || NOIT_CHECK_KILLED(check)) {
    if(!(check->flags & NP_TRANSIENT)) check_slots_dec_tv(last_check);
    memset(&check->initial_schedule_time, 0, sizeof(struct timeval));
    return 0;
  }

  /* If we have an event, we know when we intended it to fire.  This means
   * we should schedule that point + period.
   */
  if(now)
    memcpy(&earliest, now, sizeof(earliest));
  else
    gettimeofday(&earliest, NULL);

  /* If the check is unconfigured and needs resolving, we'll set the
   * period down a bit lower so we can pick up the resolution quickly.
   * The one exception is if this is the initial run.
   */
  if(!initial &&
     !NOIT_CHECK_RESOLVED(check) && NOIT_CHECK_SHOULD_RESOLVE(check) &&
     check->period > 1000) {
    period.tv_sec = 1;
    period.tv_usec = 0;
  }
  else {
    period.tv_sec = check->period / 1000;
    period.tv_usec = (check->period % 1000) * 1000;
  }
  periodms = period.tv_sec * 1000 + period.tv_usec / 1000;

  newe = eventer_alloc();
  /* calculate the differnet between the initial schedule time and "now" */
  if(compare_timeval(earliest, *last_check) >= 0) {
    sub_timeval(earliest, *last_check, &diff);
    diffms = (int64_t)diff.tv_sec * 1000 + diff.tv_usec / 1000;
  }
  else {
    noitL(noit_error, "time is going backwards. abort.\n");
    abort();
  }
  /* determine the offset from initial schedule time that would place
   * us at the next period-aligned point past "now" */
  offsetms = ((diffms / periodms) + 1) * periodms;
  diff.tv_sec = offsetms / 1000;
  diff.tv_usec = (offsetms % 1000) * 1000;

  memcpy(&newe->whence, last_check, sizeof(*last_check));
  add_timeval(newe->whence, diff, &newe->whence);

  sub_timeval(newe->whence, earliest, &diff);
  diffms = (int64_t)diff.tv_sec * 1000 + (int)diff.tv_usec / 1000;
  assert(compare_timeval(newe->whence, earliest) > 0);
  newe->mask = EVENTER_TIMER;
  newe->callback = noit_check_recur_handler;
  rcl = calloc(1, sizeof(*rcl));
  rcl->self = self;
  rcl->check = check;
  rcl->cause = cause;
  rcl->dispatch = dispatch;
  newe->closure = rcl;

  eventer_add(newe);
  check->fire_event = newe;
  return diffms;
}