示例#1
0
void
noit_lua_check_clean_events(noit_lua_check_info_t *ci) {
  if(ci->events == NULL) return;
  noit_hash_destroy(ci->events, NULL, noit_event_dispose);
  free(ci->events);
  ci->events = NULL;
}
示例#2
0
void
noit_console_closure_free(void *vncct) {
  noit_console_closure_t ncct = (noit_console_closure_t) vncct;
  noit_log_stream_t lf;
  noitL(noit_debug, "ncct free(%p)\n", (void *)ncct);
  if(ncct->el) el_end(ncct->el);
  if(ncct->hist) {
    history_end(ncct->hist);
    noitL(noit_debug, "ncct free->hist(%p)\n", (void *)ncct->hist);
    free(ncct->hist);
  }
  if(ncct->pty_master >= 0) close(ncct->pty_master);
  if(ncct->pty_slave >= 0) close(ncct->pty_slave);
  if(ncct->outbuf) free(ncct->outbuf);
  if(ncct->telnet) noit_console_telnet_free(ncct->telnet);
  noit_hash_destroy(&ncct->userdata, NULL, noit_console_userdata_free);
  while(ncct->state_stack) {
    noit_console_state_stack_t *tmp;
    tmp = ncct->state_stack;
    ncct->state_stack = tmp->last;
    if(tmp->name) free(tmp->name);
    free(tmp);
  }
  lf = noit_log_stream_find(ncct->feed_path);
  noit_log_stream_remove(ncct->feed_path);
  if(lf) {
    noit_log_stream_free(lf);
  }
  free(ncct);
}
示例#3
0
void
noit_poller_free_check(noit_check_t *checker) {
  noit_module_t *mod;

  if(checker->flags & NP_RUNNING) {
    recycle_check(checker);
    return;
  }

  mod = noit_module_lookup(checker->module);
  if(mod->cleanup) mod->cleanup(mod, checker);
  if(checker->fire_event) {
     eventer_remove(checker->fire_event);
     free(checker->fire_event->closure);
     eventer_free(checker->fire_event);
     checker->fire_event = NULL;
  }
  if(checker->closure) free(checker->closure);
  if(checker->target) free(checker->target);
  if(checker->module) free(checker->module);
  if(checker->name) free(checker->name);
  if(checker->config) {
    noit_hash_destroy(checker->config, free, free);
    free(checker->config);
    checker->config = NULL;
  }
  free(checker);
}
static int
stratcon_datastore_journal_sync(eventer_t e, int mask, void *closure,
                                struct timeval *now) {
  noit_hash_iter iter = NOIT_HASH_ITER_ZERO;
  const char *k;
  int klen;
  void *vij;
  interim_journal_t *ij;
  syncset_t *syncset = closure;

  if((mask & EVENTER_ASYNCH) == EVENTER_ASYNCH) {
    if(syncset->completion) {
      eventer_add(syncset->completion);
      eventer_trigger(syncset->completion, EVENTER_READ | EVENTER_WRITE);
    }
    free(syncset);
    return 0;
  }
  if(!((mask & EVENTER_ASYNCH_WORK) == EVENTER_ASYNCH_WORK)) return 0;

  noitL(ds_deb, "Syncing journal sets...\n");
  if (syncset->ws) {
    while(noit_hash_next(syncset->ws, &iter, &k, &klen, &vij)) {
      char tmppath[PATH_MAX], id_str[32];
      int suffix_idx;
      ij = vij;
      noitL(ds_deb, "Syncing journal set [%s,%s,%s]\n",
            ij->remote_str, ij->remote_cn, ij->fqdn);
      strlcpy(tmppath, ij->filename, sizeof(tmppath));
      suffix_idx = strlen(ij->filename) - 4; /* . t m p */
      ij->filename[suffix_idx] = '\0';
      if(rename(tmppath, ij->filename) != 0) {
        if(errno == EEXIST) {
          unlink(ij->filename);
          if(rename(tmppath, ij->filename) != 0) goto rename_failed;
        }
        else {
         rename_failed:
          noitL(noit_error, "rename failed(%s): (%s->%s)\n", strerror(errno),
                tmppath, ij->filename);
          exit(-1);
        }
      }
      fsync(ij->fd);
      close(ij->fd);
      ij->fd = -1;
      snprintf(id_str, sizeof(id_str), "%d", ij->storagenode_id);
      stratcon_ingest(ij->filename, ij->remote_str,
                      ij->remote_cn, id_str);
    }
    noit_hash_destroy(syncset->ws, free, interim_journal_free);
    free(syncset->ws);
  }
  else {
    noitL(noit_error, "attempted to sync non-existing working set\n");
  }

  return 0;
}
示例#5
0
void
noit_check_set_stats(struct _noit_module *module,
                     noit_check_t *check, stats_t *newstate) {
  int report_change = 0;
  dep_list_t *dep;
  if(check->stats.previous.status)
    free(check->stats.previous.status);
  noit_hash_destroy(&check->stats.previous.metrics, NULL, __free_metric);
  memcpy(&check->stats.previous, &check->stats.current, sizeof(stats_t));
  memcpy(&check->stats.current, newstate, sizeof(stats_t));
  if(check->stats.current.status)
    check->stats.current.status = strdup(check->stats.current.status);

  /* check for state changes */
  if(check->stats.current.available != NP_UNKNOWN &&
     check->stats.previous.available != NP_UNKNOWN &&
     check->stats.current.available != check->stats.previous.available)
    report_change = 1;
  if(check->stats.current.state != NP_UNKNOWN &&
     check->stats.previous.state != NP_UNKNOWN &&
     check->stats.current.state != check->stats.previous.state)
    report_change = 1;

  noitL(noit_debug, "%s`%s <- [%s]\n", check->target, check->name,
        check->stats.current.status);
  if(report_change) {
    noitL(noit_debug, "%s`%s -> [%s:%s]\n",
          check->target, check->name,
          noit_check_available_string(check->stats.current.available),
          noit_check_state_string(check->stats.current.state));
  }

  /* Write out our status */
  noit_check_log_status(check);
  /* Write out all metrics */
  noit_check_log_metrics(check);
  /* count the check as complete */
  check_completion_count++;

  for(dep = check->causal_checks; dep; dep = dep->next) {
    noit_module_t *mod;
    mod = noit_module_lookup(dep->check->module);
    assert(mod);
    noitL(noit_debug, "Firing %s`%s in response to %s`%s\n",
          dep->check->target, dep->check->name,
          check->target, check->name);
    if((dep->check->flags & NP_DISABLED) == 0)
      if(mod->initiate_check)
        mod->initiate_check(mod, dep->check, 1, check);
  }
}
示例#6
0
static int 
noit_lua_module_config(noit_module_t *mod,
                       noit_hash_table *options) {
  LMC_DECL(L, mod);
  SETUP_CALL(L, "config", return 0);

  noit_lua_setup_module(L, mod);
  noit_lua_hash_to_table(L, options);
  noit_hash_destroy(options, free, free);
  free(options);
  lua_pcall(L, 2, 1, 0);

  /* If rv == 0, the caller will free options. We've
   * already freed options, that would be bad. fudge -> 1 */
  RETURN_INT(L, "config", { rv = (rv == 0) ? 1 : rv; });
示例#7
0
static int noit_statsd_config(noit_module_t *self, noit_hash_table *options) {
  statsd_mod_config_t *conf;
  conf = noit_module_get_userdata(self);
  if(conf) {
    if(conf->options) {
      noit_hash_destroy(conf->options, free, free);
      free(conf->options);
    }
  }
  else
    conf = calloc(1, sizeof(*conf));
  conf->options = options;
  noit_module_set_userdata(self, conf);
  return 1;
}
示例#8
0
static int external_config(noit_module_t *self, noit_hash_table *options) {
  external_data_t *data;
  data = noit_module_get_userdata(self);
  if(data) {
    if(data->options) {
      noit_hash_destroy(data->options, free, free);
      free(data->options);
    }
  }
  else
    data = calloc(1, sizeof(*data));
  data->options = options;
  if(!data->options) data->options = calloc(1, sizeof(*data->options));
  noit_module_set_userdata(self, data);
  return 1;
}
示例#9
0
static
int configure_eventer() {
  int rv = 0;
  noit_hash_table *table;
  table = noit_conf_get_hash(NULL, "/" APPNAME "/eventer/config");
  if(table) {
    noit_hash_iter iter = NOIT_HASH_ITER_ZERO;
    const char *key, *value;
    int klen;
    while(noit_hash_next_str(table, &iter, &key, &klen, &value)) {
      int subrv;
      if((subrv = eventer_propset(key, value)) != 0)
        rv = subrv;
    }
    noit_hash_destroy(table, free, free);
    free(table);
  }
  return rv;
}
示例#10
0
void
noit_log_stream_free(noit_log_stream_t ls) {
  if(ls) {
    struct _noit_log_stream_outlet_list *node;
    if(ls->name) free(ls->name);
    if(ls->path) free(ls->path);
    while(ls->outlets) {
      node = ls->outlets->next;
      free(ls->outlets);
      ls->outlets = node;
    }
    if(ls->config) {
      noit_hash_destroy(ls->config, free, free);
      free(ls->config);
    }
    if(ls->lock) {
      pthread_rwlock_destroy(ls->lock);
      free(ls->lock);
    }
    free(ls);
  }
}
示例#11
0
static int
configure_eventer(const char *appname) {
  int rv = 0;
  noit_hash_table *table;
  char appscratch[1024];

  snprintf(appscratch, sizeof(appscratch), "/%s/eventer/config", appname);
  table = noit_conf_get_hash(NULL, appscratch);
  if(table) {
    noit_hash_iter iter = NOIT_HASH_ITER_ZERO;
    const char *key, *value;
    int klen;
    while(noit_hash_next_str(table, &iter, &key, &klen, &value)) {
      int subrv;
      if((subrv = eventer_propset(key, value)) != 0)
        rv = subrv;
    }
    noit_hash_destroy(table, free, free);
    free(table);
  }
  return rv;
}
示例#12
0
int
stratcon_line_to_javascript(noit_http_session_ctx *ctx, char *buff,
                            u_int32_t inc_id) {
  char buffer[1024];
  char *scp, *ecp, *token;
  int len;
  void *vcb;
  const char *v, *cb = NULL;
  noit_hash_table json = NOIT_HASH_EMPTY;
  char s_inc_id[42];

  snprintf(s_inc_id, sizeof(s_inc_id), "script-%08x", inc_id);
  if(noit_hash_retrieve(&ctx->req.querystring, "cb", strlen("cb"), &vcb))
    cb = vcb;
  for(v = cb; v && *v; v++)
    if(!((*v >= '0' && *v <= '9') ||
         (*v >= 'a' && *v <= 'z') ||
         (*v >= 'A' && *v <= 'Z') ||
         (*v == '_') || (*v == '.'))) {
      cb = NULL;
      break;
    }
  if(!cb) cb = "window.parent.plot_iframe_data";

#define BAIL_HTTP_WRITE do { \
  noit_hash_destroy(&json, NULL, free); \
  noitL(noit_error, "javascript emit failed: %s:%s:%d\n", \
        __FILE__, __FUNCTION__, __LINE__); \
  return -1; \
} while(0)

#define PROCESS_NEXT_FIELD(t,l) do { \
  if(!*scp) goto bad_row; \
  ecp = strchr(scp, '\t'); \
  if(!ecp) goto bad_row; \
  t = scp; \
  l = (ecp-scp); \
  scp = ecp + 1; \
} while(0)
#define PROCESS_LAST_FIELD(t,l) do { \
  if(!*scp) ecp = scp; \
  else { \
    ecp = scp + strlen(scp); /* Puts us at the '\0' */ \
    if(*(ecp-1) == '\n') ecp--; /* We back up on letter if we ended in \n */ \
  } \
  t = scp; \
  l = (ecp-scp); \
} while(0)

  scp = buff;
  PROCESS_NEXT_FIELD(token,len); /* Skip the leader */
  if(buff[0] == 'M') {
    noit_hash_iter iter = NOIT_HASH_ITER_ZERO;
    const char *key;
    int klen, i=0;
    void *vval;

#define ra_write(a,b) if(noit_http_response_append(ctx, a, b) == noit_false) BAIL_HTTP_WRITE

    snprintf(buffer, sizeof(buffer), "<script id=\"%s\">%s({", s_inc_id, cb);
    ra_write(buffer, strlen(buffer));

    while(noit_hash_next(&ctx->req.querystring, &iter, &key, &klen, &vval)) {
      if(!strcmp(key, "cb")) continue;
      noit_hash_store(&json, key, klen, strdup(vval ?(char *)vval : "true"));
    }
    /* Time */
    noit_hash_store(&json, "script_id", 9, strdup(s_inc_id));
    noit_hash_store(&json, "type", 4, strdup("M"));
    PROCESS_NEXT_FIELD(token,len);
    noit_hash_store(&json, "time", 4, noit__strndup(token, len));
    /* UUID */
    PROCESS_NEXT_FIELD(token,len);
    noit_hash_store(&json, "id", 2, noit__strndup(token, len));
    /* name */
    PROCESS_NEXT_FIELD(token,len);
    noit_hash_store(&json, "metric_name", 11, noit__strndup(token, len));
    /* type */
    PROCESS_NEXT_FIELD(token,len);
    noit_hash_store(&json, "metric_type", 11, noit__strndup(token, len));
    /* value */
    PROCESS_LAST_FIELD(token,len); /* value */
    noit_hash_store(&json, "value", 5, noit__strndup(token, len));

    memset(&iter, 0, sizeof(iter));
    while(noit_hash_next(&json, &iter, &key, &klen, &vval)) {
      char *val = (char *)vval;
      if(i++) ra_write(",", 1);
      ra_write("'", 1);
      ra_write(key, klen);
      ra_write("':\"", 3);
      while(*val) {
        if(*val == '\"' || *val == '\\') {
          ra_write((char *)"\\", 1);
        }
        if(isprint(*val)) {
          ra_write((char *)val, 1);
        }
        else {
          char od[5];
          snprintf(od, sizeof(od), "\\%03o", *((unsigned char *)val));
          ra_write(od, strlen(od));
        }
        val++;
      }
      ra_write("\"", 1);
    }
    snprintf(buffer, sizeof(buffer), "});</script>\n");
    ra_write(buffer, strlen(buffer));

    if(noit_http_response_flush(ctx, noit_false) == noit_false) BAIL_HTTP_WRITE;
  }

  noit_hash_destroy(&json, NULL, free);
  return 0;

 bad_row:
  BAIL_HTTP_WRITE;
}
示例#13
0
static int external_invoke(noit_module_t *self, noit_check_t *check,
                           noit_check_t *cause) {
  struct timeval when, p_int;
  external_closure_t *ecl;
  struct check_info *ci = (struct check_info *)check->closure;
  eventer_t newe;
  external_data_t *data;
  noit_hash_table check_attrs_hash = NOIT_HASH_EMPTY;
  int i, klen;
  noit_hash_iter iter = NOIT_HASH_ITER_ZERO;
  const char *name, *value;
  char interp_fmt[4096], interp_buff[4096];

  data = noit_module_get_userdata(self);

  check->flags |= NP_RUNNING;
  noitL(data->nldeb, "external_invoke(%p,%s)\n",
        self, check->target);

  /* remove a timeout if we still have one -- we should unless someone
   * has set a lower timeout than the period.
   */
  if(ci->timeout_event) {
    eventer_remove(ci->timeout_event);
    free(ci->timeout_event->closure);
    eventer_free(ci->timeout_event);
    ci->timeout_event = NULL;
  }

  check_info_clean(ci);

  gettimeofday(&when, NULL);
  memcpy(&check->last_fire_time, &when, sizeof(when));

  /* Setup all our check bits */
  ci->check_no = noit_atomic_inc64(&data->check_no_seq);
  ci->check = check;
  /* We might want to extract metrics */
  if(noit_hash_retr_str(check->config,
                        "output_extract", strlen("output_extract"),
                        &value) != 0) {
    const char *error;
    int erroffset;
    ci->matcher = pcre_compile(value, 0, &error, &erroffset, NULL);
    if(!ci->matcher) {
      noitL(data->nlerr, "external pcre /%s/ failed @ %d: %s\n",
            value, erroffset, error);
    }
  }

  noit_check_make_attrs(check, &check_attrs_hash);

  /* Count the args */
  i = 1;
  while(1) {
    char argname[10];
    snprintf(argname, sizeof(argname), "arg%d", i);
    if(noit_hash_retr_str(check->config, argname, strlen(argname),
                          &value) == 0) break;
    i++;
  }
  ci->argcnt = i + 1; /* path, arg0, (i-1 more args) */
  ci->arglens = calloc(ci->argcnt, sizeof(*ci->arglens));
  ci->args = calloc(ci->argcnt, sizeof(*ci->args));

  /* Make the command */
  if(noit_hash_retr_str(check->config, "command", strlen("command"),
                        &value) == 0) {
    value = "/bin/true";
  }
  ci->args[0] = strdup(value);
  ci->arglens[0] = strlen(ci->args[0]) + 1;

  i = 0;
  while(1) {
    char argname[10];
    snprintf(argname, sizeof(argname), "arg%d", i);
    if(noit_hash_retr_str(check->config, argname, strlen(argname),
                          &value) == 0) {
      if(i == 0) {
        /* if we don't have arg0, make it last element of path */
        char *cp = ci->args[0] + strlen(ci->args[0]);
        while(cp > ci->args[0] && *(cp-1) != '/') cp--;
        value = cp;
      }
      else break; /* if we don't have argn, we're done */
    }
    noit_check_interpolate(interp_buff, sizeof(interp_buff), value,
                           &check_attrs_hash, check->config);
    ci->args[i+1] = strdup(interp_buff);
    ci->arglens[i+1] = strlen(ci->args[i+1]) + 1;
    i++;
  }

  /* Make the environment */
  memset(&iter, 0, sizeof(iter));
  ci->envcnt = 0;
  while(noit_hash_next_str(check->config, &iter, &name, &klen, &value))
    if(!strncasecmp(name, "env_", 4))
      ci->envcnt++;
  memset(&iter, 0, sizeof(iter));
  ci->envlens = calloc(ci->envcnt, sizeof(*ci->envlens));
  ci->envs = calloc(ci->envcnt, sizeof(*ci->envs));
  ci->envcnt = 0;
  while(noit_hash_next_str(check->config, &iter, &name, &klen, &value))
    if(!strncasecmp(name, "env_", 4)) {
      snprintf(interp_fmt, sizeof(interp_fmt), "%s=%s", name+4, value);
      noit_check_interpolate(interp_buff, sizeof(interp_buff), interp_fmt,
                             &check_attrs_hash, check->config);
      ci->envs[ci->envcnt] = strdup(interp_buff);
      ci->envlens[ci->envcnt] = strlen(ci->envs[ci->envcnt]) + 1;
      ci->envcnt++;
    }

  noit_hash_destroy(&check_attrs_hash, NULL, NULL);

  noit_hash_store(&data->external_checks,
                  (const char *)&ci->check_no, sizeof(ci->check_no),
                  ci);

  /* Setup a timeout */
  newe = eventer_alloc();
  newe->mask = EVENTER_TIMER;
  gettimeofday(&when, NULL);
  p_int.tv_sec = check->timeout / 1000;
  p_int.tv_usec = (check->timeout % 1000) * 1000;
  add_timeval(when, p_int, &newe->whence);
  ecl = calloc(1, sizeof(*ecl));
  ecl->self = self;
  ecl->check = check;
  newe->closure = ecl;
  newe->callback = external_timeout;
  eventer_add(newe);
  ci->timeout_event = newe;

  /* Setup push */
  newe = eventer_alloc();
  newe->mask = EVENTER_ASYNCH;
  add_timeval(when, p_int, &newe->whence);
  ecl = calloc(1, sizeof(*ecl));
  ecl->self = self;
  ecl->check = check;
  newe->closure = ecl;
  newe->callback = external_enqueue;
  eventer_add(newe);

  return 0;
}
示例#14
0
void
noit_listener_reconfig(const char *toplevel) {
  int i, cnt = 0;
  noit_conf_section_t *listener_configs;
  char path[256];

  snprintf(path, sizeof(path), "/%s/listeners//listener",
           toplevel ? toplevel : "*");
  listener_configs = noit_conf_get_sections(NULL, path, &cnt);
  noitL(noit_debug, "Found %d %s stanzas\n", cnt, path);
  for(i=0; i<cnt; i++) {
    char address[256];
    char type[256];
    unsigned short port;
    int portint;
    int backlog;
    eventer_func_t f;
    noit_boolean ssl;
    noit_hash_table *sslconfig, *config;

    if(!noit_conf_get_stringbuf(listener_configs[i],
                                "ancestor-or-self::node()/@type",
                                type, sizeof(type))) {
      noitL(noit_error, "No type specified in listener stanza %d\n", i+1);
      continue;
    }
    f = eventer_callback_for_name(type);
    if(!f) {
      noitL(noit_error,
            "Cannot find handler for listener type: '%s'\n", type);
      continue;
    }
    if(!noit_conf_get_stringbuf(listener_configs[i],
                                "ancestor-or-self::node()/@address",
                                address, sizeof(address))) {
      address[0] = '*';
      address[1] = '\0';
    }
    if(!noit_conf_get_int(listener_configs[i],
                          "ancestor-or-self::node()/@port", &portint))
      portint = 0;
    port = (unsigned short) portint;
    if(address[0] != '/' && (portint == 0 || (port != portint))) {
      /* UNIX sockets don't require a port (they'll ignore it if specified */
      noitL(noit_error,
            "Invalid port [%d] specified in stanza %d\n", port, i+1);
      continue;
    }
    if(noit_listener_should_skip(address, port)) {
      if(port)
        noitL(noit_error, "Operator forced skipping listener %s:%d\n", address, port);
      else
        noitL(noit_error, "Operator forced skipping listener %s\n", address);
      continue;
    }
    if(!noit_conf_get_int(listener_configs[i],
                          "ancestor-or-self::node()/@backlog", &backlog))
      backlog = 5;

    if(!noit_conf_get_boolean(listener_configs[i],
                              "ancestor-or-self::node()/@ssl", &ssl))
     ssl = noit_false;

    sslconfig = ssl ?
                  noit_conf_get_hash(listener_configs[i], "sslconfig") :
                  NULL;
    config = noit_conf_get_hash(listener_configs[i], "config");

    if(noit_listener(address, port, SOCK_STREAM, backlog,
                     sslconfig, config, f, NULL) != 0) {
      noit_hash_destroy(config,free,free);
      free(config);
    }
    if(sslconfig) {
      /* A copy of this is made within noit_listener */
      noit_hash_destroy(sslconfig,free,free);
      free(sslconfig);
    }
  }
  free(listener_configs);
}
示例#15
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;
}
示例#16
0
static int
noit_console_config_show(noit_console_closure_t ncct,
                         int argc, char **argv,
                         noit_console_state_t *state, void *closure) {
  noit_hash_iter iter = NOIT_HASH_ITER_ZERO;
  const char *k;
  int klen;
  void *data;
  int i, cnt, titled = 0, cliplen = 0;
  const char *path = "", *basepath = NULL;
  char xpath[1024];
  noit_conf_t_userdata_t *info = NULL;
  noit_hash_table *config;
  xmlXPathObjectPtr pobj = NULL;
  xmlXPathContextPtr xpath_ctxt = NULL, current_ctxt;
  xmlDocPtr master_config = NULL;
  xmlNodePtr node = NULL;

  noit_conf_xml_xpath(&master_config, &xpath_ctxt);
  if(argc > 1) {
    nc_printf(ncct, "too many arguments\n");
    return -1;
  }

  info = noit_console_userdata_get(ncct, NOIT_CONF_T_USERDATA);
  if(info && info->path) path = basepath = info->path;
  if(!info && argc == 0) {
    nc_printf(ncct, "argument required when not in configuration mode\n");
    return -1;
  }

  if(argc == 1) path = argv[0];
  if(!basepath) basepath = path;

  /* { / } is a special case */
  if(!strcmp(basepath, "/")) basepath = "";
  if(!strcmp(path, "/")) path = "";

  if(!master_config) {
    nc_printf(ncct, "no config\n");
    return -1;
  }

  /* { / } is the only path that will end with a /
   * in XPath { / / * } means something _entirely different than { / * }
   * Ever notice how it is hard to describe xpath in C comments?
   */
  /* We don't want to show the root node */
  cliplen = strlen("/noit/");

  /* If we are in configuration mode
   * and we are without an argument or the argument is absolute,
   * clip the current path off */
  if(info && (argc == 0 || path[0] != '/')) cliplen += strlen(basepath);
  if(!path[0] || path[0] == '/') /* base only, or absolute path requested */
    snprintf(xpath, sizeof(xpath), "/noit%s/@*", path);
  else
    snprintf(xpath, sizeof(xpath), "/noit%s/%s/@*", basepath, path);

  current_ctxt = xpath_ctxt;
  pobj = xmlXPathEval((xmlChar *)xpath, current_ctxt);
  if(!pobj || pobj->type != XPATH_NODESET) {
    nc_printf(ncct, "no such object\n");
    goto bad;
  }
  cnt = xmlXPathNodeSetGetLength(pobj->nodesetval);
  titled = 0;
  for(i=0; i<cnt; i++) {
    node = (noit_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, i);
    if(!strcmp((char *)node->name, "check")) continue;
    if(node->children && node->children == xmlGetLastChild(node) &&
      xmlNodeIsText(node->children)) {
      if(!titled++) nc_printf(ncct, "== Section Settings ==\n");
      nc_printf(ncct, "%s: %s\n", xmlGetNodePath(node) + cliplen,
                xmlXPathCastNodeToString(node->children));
    }
  }
  xmlXPathFreeObject(pobj);

  /* Print out all the config settings */
  if(!path[0] || path[0] == '/') /* base only, or absolute path requested */
    snprintf(xpath, sizeof(xpath), "/noit%s", path);
  else
    snprintf(xpath, sizeof(xpath), "/noit%s/%s", basepath, path);
  pobj = xmlXPathEval((xmlChar *)xpath, current_ctxt);
  if(!pobj || pobj->type != XPATH_NODESET) {
    nc_printf(ncct, "no such object\n");
    goto bad;
  }
  cnt = xmlXPathNodeSetGetLength(pobj->nodesetval);
  if(cnt > 0) {
    node = (noit_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, 0);
    titled = 0;
    config = noit_conf_get_hash(node, "config");
    while(noit_hash_next(config, &iter, &k, &klen, &data)) {
      if(!titled++) nc_printf(ncct, "== Section [Aggregated] Config ==\n");
      nc_printf(ncct, "config::%s: %s\n", k, (const char *)data);
    }
    noit_hash_destroy(config, free, free);
    free(config);
  }
  xmlXPathFreeObject(pobj);

  /* _shorten string_ turning last { / @ * } to { / * } */
  if(!path[0] || path[0] == '/') /* base only, or absolute path requested */
    snprintf(xpath, sizeof(xpath), "/noit%s/*", path);
  else
    snprintf(xpath, sizeof(xpath), "/noit%s/%s/*", basepath, path);
  pobj = xmlXPathEval((xmlChar *)xpath, current_ctxt);
  if(!pobj || pobj->type != XPATH_NODESET) {
    nc_printf(ncct, "no such object\n");
    goto bad;
  }
  cnt = xmlXPathNodeSetGetLength(pobj->nodesetval);
  titled = 0;
  for(i=0; i<cnt; i++) {
    node = (noit_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, i);
    if(!strcmp((char *)node->name, "check")) continue;
    if(!strcmp((char *)node->name, "filterset")) continue;
    if(!strcmp((char *)xmlGetNodePath(node) + cliplen, "config")) continue;
    if(!(node->children && node->children == xmlGetLastChild(node) &&
         xmlNodeIsText(node->children))) {
      if(!titled++) nc_printf(ncct, "== Subsections ==\n");
      nc_printf(ncct, "%s\n", xmlGetNodePath(node) + cliplen);
    }
  }

  titled = 0;
  for(i=0; i<cnt; i++) {
    node = (noit_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, i);
    if(!strcmp((char *)node->name, "filterset")) {
      xmlAttr *attr;
      char *filter_name = NULL;
      for(attr=node->properties; attr; attr = attr->next) {
        if(!strcmp((char *)attr->name, "name"))
          filter_name = (char *)xmlXPathCastNodeToString(attr->children);
      }
      if(filter_name) {
        nc_printf(ncct, "filterset[@name=\"%s\"]\n", filter_name);
        xmlFree(filter_name);
      }
      else nc_printf(ncct, "fitlerset\n");
    }
    else if(!strcmp((char *)node->name, "check")) {
      int busted = 1;
      xmlAttr *attr;
      char *uuid_str = "undefined";

      if(!titled++) nc_printf(ncct, "== Checks ==\n");

      for(attr=node->properties; attr; attr = attr->next) {
        if(!strcmp((char *)attr->name, "uuid"))
          uuid_str = (char *)xmlXPathCastNodeToString(attr->children);
      }
      if(uuid_str) {
        uuid_t checkid;
        nc_printf(ncct, "check[@uuid=\"%s\"] ", uuid_str);
        if(uuid_parse(uuid_str, checkid) == 0) {
          noit_check_t *check;
          check = noit_poller_lookup(checkid);
          if(check) {
            busted = 0;
            nc_printf(ncct, "%s`%s`%s", check->target, check->module, check->name);
          }
        }
      }
      else
        nc_printf(ncct, "%s ", xmlGetNodePath(node) + cliplen);
      if(busted) nc_printf(ncct, "[check not in running system]");
      nc_write(ncct, "\n", 1);
    }
  }
  xmlXPathFreeObject(pobj);
  return 0;
 bad:
  if(pobj) xmlXPathFreeObject(pobj);
  return -1;
}
示例#17
0
static int
noit_console_show_check(noit_console_closure_t ncct,
                        int argc, char **argv,
                        noit_console_state_t *state, void *closure) {
  int i, cnt;
  noit_conf_t_userdata_t *info;
  char xpath[1024];
  xmlXPathObjectPtr pobj = NULL;
  xmlXPathContextPtr xpath_ctxt = NULL;

  noit_conf_xml_xpath(NULL, &xpath_ctxt);
  if(argc > 1) {
    nc_printf(ncct, "requires zero or one arguments\n");
    return -1;
  }

  info = noit_console_userdata_get(ncct, NOIT_CONF_T_USERDATA);
  /* We many not be in conf-t mode -- that's fine */
  if(noit_console_mkcheck_xpath(xpath, sizeof(xpath), info,
                                argc ? argv[0] : NULL)) {
    nc_printf(ncct, "could not find check '%s'\n", argv[0]);
    return -1;
  }

  pobj = xmlXPathEval((xmlChar *)xpath, xpath_ctxt);
  if(!pobj || pobj->type != XPATH_NODESET ||
     xmlXPathNodeSetIsEmpty(pobj->nodesetval)) {
    nc_printf(ncct, "no checks found\n");
    goto out;
  }
  cnt = xmlXPathNodeSetGetLength(pobj->nodesetval);
  if(info && cnt != 1) {
    nc_printf(ncct, "Ambiguous check specified\n");
    goto out;
  }
  for(i=0; i<cnt; i++) {
    noit_hash_iter iter = NOIT_HASH_ITER_ZERO;
    const char *k;
    int klen;
    void *data;
    uuid_t checkid;
    noit_check_t *check;
    noit_hash_table *config;
    xmlNodePtr node, anode, mnode = NULL;
    char *uuid_conf;
    char *module, *value;

    node = (noit_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, i);
    uuid_conf = (char *)xmlGetProp(node, (xmlChar *)"uuid");
    if(!uuid_conf || uuid_parse(uuid_conf, checkid)) {
      nc_printf(ncct, "%s has invalid or missing UUID!\n",
                (char *)xmlGetNodePath(node) + strlen("/noit"));
      continue;
    }
    nc_printf(ncct, "==== %s ====\n", uuid_conf);

#define MYATTR(a,n,b) _noit_conf_get_string(node, &(n), "@" #a, &(b))
#define INHERIT(a,n,b) \
  _noit_conf_get_string(node, &(n), "ancestor-or-self::node()/@" #a, &(b))
#define SHOW_ATTR(a) do { \
  anode = NULL; \
  value = NULL; \
  INHERIT(a, anode, value); \
  nc_attr_show(ncct, #a, node, anode, value); \
} while(0)

    if(!INHERIT(module, mnode, module)) module = NULL;
    if(MYATTR(name, anode, value))
      nc_printf(ncct, " name: %s\n", value);
    else
      nc_printf(ncct, " name: %s [from module]\n", module ? module : "[undef]");
    nc_attr_show(ncct, "module", node, mnode, module);
    SHOW_ATTR(target);
    SHOW_ATTR(period);
    SHOW_ATTR(timeout);
    SHOW_ATTR(oncheck);
    SHOW_ATTR(filterset);
    SHOW_ATTR(disable);
    /* Print out all the config settings */
    config = noit_conf_get_hash(node, "config");
    while(noit_hash_next(config, &iter, &k, &klen, &data)) {
      nc_printf(ncct, " config::%s: %s\n", k, (const char *)data);
    }
    noit_hash_destroy(config, free, free);
    free(config);

    check = noit_poller_lookup(checkid);
    if(!check) {
      nc_printf(ncct, " ERROR: not in running system\n");
    }
    else {
      int idx = 0;
      nc_printf(ncct, " currently: ");
      if(NOIT_CHECK_RUNNING(check)) nc_printf(ncct, "%srunning", idx++?",":"");
      if(NOIT_CHECK_KILLED(check)) nc_printf(ncct, "%skilled", idx++?",":"");
      if(!NOIT_CHECK_CONFIGURED(check)) nc_printf(ncct, "%sunconfig", idx++?",":"");
      if(NOIT_CHECK_DISABLED(check)) nc_printf(ncct, "%sdisabled", idx++?",":"");
      if(!idx) nc_printf(ncct, "idle");
      nc_write(ncct, "\n", 1);
      if(check->stats.current.whence.tv_sec == 0) {
        nc_printf(ncct, " last run: never\n");
      }
      else {
        stats_t *c = &check->stats.current;
        struct timeval now, diff;
        gettimeofday(&now, NULL);
        sub_timeval(now, c->whence, &diff);
        nc_printf(ncct, " last run: %0.3f seconds ago\n",
                  diff.tv_sec + (diff.tv_usec / 1000000.0));
        nc_printf(ncct, " availability/state: %s/%s\n",
                  noit_check_available_string(c->available),
                  noit_check_state_string(c->state));
        nc_printf(ncct, " status: %s\n", c->status ? c->status : "[[null]]");
        nc_printf(ncct, " metrics:\n");
        memset(&iter, 0, sizeof(iter));
        while(noit_hash_next(&c->metrics, &iter, &k, &klen, &data)) {
          char buff[256];
          noit_boolean filtered;
          noit_stats_snprint_metric(buff, sizeof(buff), (metric_t *)data);
          filtered = !noit_apply_filterset(check->filterset, check, (metric_t *)data);
          nc_printf(ncct, "  %c%s\n", filtered ? '*' : ' ', buff);
        }
      }
    }
  }
 out:
  if(pobj) xmlXPathFreeObject(pobj);
  return 0;
}
int
stratcon_line_to_javascript(noit_http_session_ctx *ctx, char *in_buff,
                            u_int32_t *inc_id) {
  char buffer[1024];
  char *scp, *ecp, *token, *buff;
  int i, len, cnt;
  const char *v, *cb = NULL;
  noit_hash_table json = NOIT_HASH_EMPTY;
  noit_http_request *req = noit_http_session_request(ctx);
  char s_inc_id[42];
  char **outrows = NULL;

  cb = noit_http_request_querystring(req, "cb"); 
  for(v = cb; v && *v; v++)
    if(!((*v >= '0' && *v <= '9') ||
         (*v >= 'a' && *v <= 'z') ||
         (*v >= 'A' && *v <= 'Z') ||
         (*v == '_') || (*v == '.'))) {
      cb = NULL;
      break;
    }
  if(!cb) cb = "window.parent.plot_iframe_data";

#define BAIL_HTTP_WRITE do { \
  if(outrows) { \
    for(i=0;i<cnt;i++) if(outrows[i]) free(outrows[i]); \
    free(outrows); \
  } \
  noit_hash_destroy(&json, NULL, free); \
  noitL(noit_error, "javascript emit failed: %s:%s:%d\n", \
        __FILE__, __FUNCTION__, __LINE__); \
  return -1; \
} while(0)

#define PROCESS_NEXT_FIELD(t,l) do { \
  if(!*scp) goto bad_row; \
  ecp = strchr(scp, '\t'); \
  if(!ecp) goto bad_row; \
  t = scp; \
  l = (ecp-scp); \
  scp = ecp + 1; \
} while(0)
#define PROCESS_LAST_FIELD(t,l) do { \
  if(!*scp) ecp = scp; \
  else { \
    ecp = scp + strlen(scp); /* Puts us at the '\0' */ \
    if(*(ecp-1) == '\n') ecp--; /* We back up on letter if we ended in \n */ \
  } \
  t = scp; \
  l = (ecp-scp); \
} while(0)

  noitL(noit_error, "recv(%s)\n", in_buff);
  if(in_buff[0] == 'B' && in_buff[1] != '\0' && in_buff[2] == '\t') {
    cnt = noit_check_log_b_to_sm(in_buff, strlen(in_buff), &outrows);
  }
  else {
    cnt = 1;
    outrows = malloc(sizeof(*outrows));
    outrows[0] = strdup(in_buff);
  }
  for(i=0; i<cnt; i++) {
    buff = outrows[i];
    if(!buff) continue;
    noitL(noit_error, "recv_xlt(%s)\n", buff);
    scp = buff;
    PROCESS_NEXT_FIELD(token,len); /* Skip the leader */
    if(buff[1] == '\t' && (buff[0] == 'M' || buff[0] == 'S')) {
      char target[256], module[256], name[256], uuid_str[UUID_STR_LEN+1];
      noit_http_request *req = noit_http_session_request(ctx);
      noit_hash_table *qs;
      noit_hash_iter iter = NOIT_HASH_ITER_ZERO;
      const char *key;
      int klen, i=0;
      void *vval;
      char type[2] = { '\0', '\0' };
      type[0] = buff[0];

#define ra_write(a,b) if(noit_http_response_append(ctx, a, b) == noit_false) BAIL_HTTP_WRITE

      snprintf(s_inc_id, sizeof(s_inc_id), "script-%08x", (*inc_id)++);
      snprintf(buffer, sizeof(buffer), "<script id=\"%s\">%s({", s_inc_id, cb);
      ra_write(buffer, strlen(buffer));

      qs = noit_http_request_querystring_table(req);
      while(noit_hash_next(qs, &iter, &key, &klen, &vval)) {
        if(!strcmp(key, "cb")) continue;
        noit_hash_store(&json, key, klen, strdup(vval ?(char *)vval : "true"));
      }
      /* Time */
      noit_hash_store(&json, "script_id", 9, strdup(s_inc_id));
      noit_hash_store(&json, "type", 4, strdup(type));
      PROCESS_NEXT_FIELD(token,len);
      noit_hash_store(&json, "time", 4, noit__strndup(token, len));
      /* UUID */
      PROCESS_NEXT_FIELD(token,len);
      noit_check_extended_id_split(token, len, target, sizeof(target),
                                   module, sizeof(module), name, sizeof(name),
                                   uuid_str, sizeof(uuid_str));
      if(*uuid_str)
        noit_hash_store(&json, "id", 2,
                        noit__strndup(uuid_str, strlen(uuid_str)));
      if(*target)
        noit_hash_store(&json, "check_target", 12,
                        noit__strndup(target, strlen(target)));
      if(*module)
        noit_hash_store(&json, "check_module", 12,
                        noit__strndup(module, strlen(module)));
      if(*name)
        noit_hash_store(&json, "check_name", 10,
                        noit__strndup(name, strlen(name)));
      if(buff[0] == 'M') {
        /* name */
        PROCESS_NEXT_FIELD(token,len);
        noit_hash_store(&json, "metric_name", 11, noit__strndup(token, len));
        /* type */
        PROCESS_NEXT_FIELD(token,len);
        noit_hash_store(&json, "metric_type", 11, noit__strndup(token, len));
        /* value */
        PROCESS_LAST_FIELD(token,len); /* value */
        noit_hash_store(&json, "value", 5, noit__strndup(token, len));
      }
      else if(buff[0] == 'S') {
        /* state */
        PROCESS_NEXT_FIELD(token,len);
        noit_hash_store(&json, "check_state", 11, noit__strndup(token, len));
        /* availability */
        PROCESS_NEXT_FIELD(token,len);
        noit_hash_store(&json, "check_availability", 18, noit__strndup(token, len));
        /* duration */
        PROCESS_NEXT_FIELD(token,len);
        noit_hash_store(&json, "check_duration_ms", 17, noit__strndup(token, len));
        /* status */
        PROCESS_LAST_FIELD(token,len);
        noit_hash_store(&json, "status_message", 14, noit__strndup(token, len));
      }

      memset(&iter, 0, sizeof(iter));
      while(noit_hash_next(&json, &iter, &key, &klen, &vval)) {
        char *val = (char *)vval;
        if(i++) ra_write(",", 1);
        ra_write("\"", 1);
        ra_write(key, klen);
        ra_write("\":\"", 3);
        while(*val) {
          if(*val == '\"' || *val == '\\') {
            ra_write((char *)"\\", 1);
          }
          if(isprint(*val)) {
            ra_write((char *)val, 1);
          }
          else {
            char od[5];
            snprintf(od, sizeof(od), "\\%03o", *((unsigned char *)val));
            ra_write(od, strlen(od));
          }
          val++;
        }
        ra_write("\"", 1);
      }
      snprintf(buffer, sizeof(buffer), "});</script>\n");
      ra_write(buffer, strlen(buffer));

      if(noit_http_response_flush(ctx, noit_false) == noit_false) BAIL_HTTP_WRITE;
    }

    noit_hash_destroy(&json, NULL, free);
    memset(&json, 0, sizeof(json));
  }
  if(outrows) {
    for(i=0;i<cnt;i++) if(outrows[i]) free(outrows[i]);
    free(outrows);
  }

  return 0;

 bad_row:
  BAIL_HTTP_WRITE;
}
void
noit_check_release_attrs(noit_hash_table *attrs) {
  noit_hash_destroy(attrs, NULL, NULL);
}
示例#20
0
static int dns_check_send(noit_module_t *self, noit_check_t *check,
                          noit_check_t *cause) {
  void *vnv_pair = NULL;
  struct dns_nameval *nv_pair;
  eventer_t newe;
  struct timeval p_int, now;
  struct dns_check_info *ci = check->closure;
  const char *config_val;
  const char *rtype = NULL;
  const char *nameserver = NULL;
  int port = 0;
  const char *port_str = NULL;
  const char *want_sort = NULL;
  const char *ctype = "IN";
  const char *query = NULL;
  char interpolated_nameserver[1024];
  char interpolated_query[1024];
  noit_hash_table check_attrs_hash = NOIT_HASH_EMPTY;

  BAIL_ON_RUNNING_CHECK(check);

  gettimeofday(&now, NULL);
  memcpy(&check->last_fire_time, &now, sizeof(now));
  ci->current.state = NP_BAD;
  ci->current.available = NP_UNAVAILABLE;
  ci->timed_out = 1;
  ci->nrr = 0;
  ci->sort = 1;

  if(!strcmp(check->name, "in-addr.arpa") ||
     (strlen(check->name) >= sizeof("::in-addr.arpa") - 1 &&
      !strcmp(check->name + strlen(check->name) - sizeof("::in-addr.arpa") + 1,
              "::in-addr.arpa"))) {
    /* in-addr.arpa defaults:
     *   nameserver to NULL
     *   rtype to PTR
     *   query to %[:inaddrarpa:target]
     */
    nameserver = NULL;
    rtype = "PTR";
    query = "%[:inaddrarpa:target_ip]";
  }
  else {
    nameserver = "%[target_ip]";
    rtype = "A";
    query = "%[name]";
  }

  if(noit_hash_retr_str(check->config, "port", strlen("port"),
                        &port_str)) {
    port = atoi(port_str);
  }

#define CONFIG_OVERRIDE(a) \
  if(noit_hash_retr_str(check->config, #a, strlen(#a), \
                        &config_val) && \
     strlen(config_val) > 0) \
    a = config_val
  CONFIG_OVERRIDE(ctype);
  CONFIG_OVERRIDE(nameserver);
  CONFIG_OVERRIDE(rtype);
  CONFIG_OVERRIDE(query);
  CONFIG_OVERRIDE(want_sort);
  if(nameserver && !strcmp(nameserver, "default")) nameserver = NULL;
  if(want_sort && strcasecmp(want_sort, "on") && strcasecmp(want_sort, "true"))
    ci->sort = 0;

  noit_check_make_attrs(check, &check_attrs_hash);

  if(nameserver) {
    noit_check_interpolate(interpolated_nameserver,
                           sizeof(interpolated_nameserver),
                           nameserver,
                           &check_attrs_hash, check->config);
    nameserver = interpolated_nameserver;
  }
  if(query) {
    noit_check_interpolate(interpolated_query,
                           sizeof(interpolated_query),
                           query,
                           &check_attrs_hash, check->config);
    query = interpolated_query;
  }
  noit_hash_destroy(&check_attrs_hash, NULL, NULL);

  check->flags |= NP_RUNNING;
  noitL(nldeb, "dns_check_send(%p,%s,%s,%s,%s,%s)\n",
        self, check->target, nameserver ? nameserver : "default",
        query ? query : "null", ctype, rtype);

  __activate_ci(ci);
  /* If this ci has a handle and it isn't the one we need,
   * we should release it
   */
  if(ci->h &&
     ((ci->h->ns == NULL && nameserver != NULL) ||
      (ci->h->ns != NULL && nameserver == NULL) ||
      (ci->h->ns && strcmp(ci->h->ns, nameserver)))) {
    dns_ctx_release(ci->h);
    ci->h = NULL;
  }
  /* use the cached one, unless we don't have one */
  if(!ci->h) ci->h = dns_ctx_alloc(nameserver, port);
  if(!ci->h) ci->error = strdup("bad nameserver");

  /* Lookup out class */
  if(!noit_hash_retrieve(&dns_ctypes, ctype, strlen(ctype),
                         &vnv_pair)) {
    if(ci->error) free(ci->error);
    ci->error = strdup("bad class");
  }
  else {
    nv_pair = (struct dns_nameval *)vnv_pair;
    ci->query_ctype = nv_pair->val;
  }
  /* Lookup out rr type */
  if(!noit_hash_retrieve(&dns_rtypes, rtype, strlen(rtype),
                         &vnv_pair)) {
    if(ci->error) free(ci->error);
    ci->error = strdup("bad rr type");
  }
  else {
    nv_pair = (struct dns_nameval *)vnv_pair;
    ci->query_rtype = nv_pair->val;
  }

  if(!ci->error) {
    /* Submit the query */
    int abs;
    if(!dns_ptodn(query, strlen(query), ci->dn, sizeof(ci->dn), &abs) ||
       !dns_submit_dn(ci->h->ctx, ci->dn, ci->query_ctype, ci->query_rtype,
                      abs | DNS_NOSRCH, NULL, dns_cb, ci)) {
      ci->error = strdup("submission error");
    }
    else {
      dns_timeouts(ci->h->ctx, -1, now.tv_sec);
    }
  }

  /* we could have completed by now... if so, we've nothing to do */

  if(!__isactive_ci(ci)) return 0;

  if(ci->error) {
    /* Errors here are easy, fail and avoid scheduling a timeout */
    ci->check->flags &= ~NP_RUNNING;
    dns_check_log_results(ci);
    __deactivate_ci(ci);
    return 0;
  }

  newe = eventer_alloc();
  newe->mask = EVENTER_TIMER;
  gettimeofday(&now, NULL);
  p_int.tv_sec = check->timeout / 1000;
  p_int.tv_usec = (check->timeout % 1000) * 1000;
  add_timeval(now, p_int, &newe->whence);
  newe->closure = ci;
  newe->callback = dns_check_timeout;
  ci->timeout_event = newe;
  eventer_add(newe);

  return 0;
}
示例#21
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;
}
示例#22
0
static int
rest_show_check(noit_http_rest_closure_t *restc,
                int npats, char **pats) {
  noit_http_session_ctx *ctx = restc->http_ctx;
  xmlXPathObjectPtr pobj = NULL;
  xmlXPathContextPtr xpath_ctxt = NULL;
  xmlDocPtr doc = NULL;
  xmlNodePtr node, root, attr, config, state, tmp, anode;
  uuid_t checkid;
  noit_check_t *check;
  char xpath[1024], *uuid_conf, *module, *value;
  int rv, cnt, error_code = 500;
  noit_hash_iter iter = NOIT_HASH_ITER_ZERO;
  const char *k;
  int klen;
  void *data;
  noit_hash_table *configh;

  if(npats != 2) goto error;

  rv = noit_check_xpath(xpath, sizeof(xpath), pats[0], pats[1]);
  if(rv == 0) goto not_found;
  if(rv < 0) goto error;

  noit_conf_xml_xpath(NULL, &xpath_ctxt);
  pobj = xmlXPathEval((xmlChar *)xpath, xpath_ctxt);
  if(!pobj || pobj->type != XPATH_NODESET ||
     xmlXPathNodeSetIsEmpty(pobj->nodesetval)) goto not_found;
  cnt = xmlXPathNodeSetGetLength(pobj->nodesetval);
  if(cnt != 1) goto error;

  node = (noit_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, 0);
  uuid_conf = (char *)xmlGetProp(node, (xmlChar *)"uuid");
  if(!uuid_conf || uuid_parse(uuid_conf, checkid)) goto error;

  doc = xmlNewDoc((xmlChar *)"1.0");
  root = xmlNewDocNode(doc, NULL, (xmlChar *)"check", NULL);
  xmlDocSetRootElement(doc, root);

#define MYATTR(node,a,n,b) _noit_conf_get_string(node, &(n), "@" #a, &(b))
#define INHERIT(node,a,n,b) \
  _noit_conf_get_string(node, &(n), "ancestor-or-self::node()/@" #a, &(b))
#define SHOW_ATTR(parent, node, a) do { \
  xmlNodePtr anode = NULL; \
  char *value = NULL; \
  INHERIT(node, a, anode, value); \
  if(value != NULL) { \
    int clen, plen;\
    const char *cpath, *apath; \
    xmlNodePtr child; \
    cpath = node ? (char *)xmlGetNodePath(node) : ""; \
    apath = anode ? (char *)xmlGetNodePath(anode) : ""; \
    clen = strlen(cpath); \
    plen = strlen("/noit/checks"); \
    child = xmlNewNode(NULL, (xmlChar *)#a); \
    xmlNodeAddContent(child, (xmlChar *)value); \
    if(!strncmp(cpath, apath, clen) && apath[clen] == '/') { \
    } \
    else { \
      xmlSetProp(child, (xmlChar *)"inherited", (xmlChar *)apath+plen); \
    } \
    xmlAddChild(parent, child); \
  } \
} while(0)

  attr = xmlNewNode(NULL, (xmlChar *)"attributes");
  xmlAddChild(root, attr);

  SHOW_ATTR(attr,node,uuid);

  /* Name is odd, it falls back transparently to module */
  if(!INHERIT(node, module, tmp, module)) module = NULL;
  xmlAddChild(attr, (tmp = xmlNewNode(NULL, (xmlChar *)"name")));
  if(MYATTR(node, name, anode, value))
    xmlNodeAddContent(tmp, (xmlChar *)value);
  else if(module)
    xmlNodeAddContent(tmp, (xmlChar *)module);

  SHOW_ATTR(attr,node,module);
  SHOW_ATTR(attr,node,target);
  SHOW_ATTR(attr,node,period);
  SHOW_ATTR(attr,node,timeout);
  SHOW_ATTR(attr,node,oncheck);
  SHOW_ATTR(attr,node,filterset);
  SHOW_ATTR(attr,node,disable);

  /* Add the config */
  config = xmlNewNode(NULL, (xmlChar *)"config");
  configh = noit_conf_get_hash(node, "config");
  while(noit_hash_next(configh, &iter, &k, &klen, &data))
    NODE_CONTENT(config, k, data);
  noit_hash_destroy(configh, free, free);
  free(configh);
  xmlAddChild(root, config);

  /* Add the state */
  check = noit_poller_lookup(checkid);
  if(!check) {
    state = xmlNewNode(NULL, (xmlChar *)"state");
    xmlSetProp(state, (xmlChar *)"error", (xmlChar *)"true");
  }
  else
    state = noit_check_state_as_xml(check);
  xmlAddChild(root, state);
  noit_http_response_ok(ctx, "text/xml");
  noit_http_response_xml(ctx, doc);
  noit_http_response_end(ctx);
  goto cleanup;

 not_found:
  noit_http_response_not_found(ctx, "text/html");
  noit_http_response_end(ctx);
  goto cleanup;

 error:
  noit_http_response_standard(ctx, error_code, "ERROR", "text/html");
  noit_http_response_end(ctx);
  goto cleanup;

 cleanup:
  if(pobj) xmlXPathFreeObject(pobj);
  if(doc) xmlFreeDoc(doc);
  return 0;
}
示例#23
0
void
noit_poller_process_checks(const char *xpath) {
  int i, flags, cnt = 0;
  noit_conf_section_t *sec;
  __config_load_generation++;
  sec = noit_conf_get_sections(NULL, xpath, &cnt);
  for(i=0; i<cnt; i++) {
    void *vcheck;
    char uuid_str[37];
    char target[256] = "";
    char module[256] = "";
    char name[256] = "";
    char filterset[256] = "";
    char oncheck[1024] = "";
    int no_period = 0;
    int no_oncheck = 0;
    int period = 0, timeout = 0;
    noit_boolean disabled = noit_false, busted = noit_false;
    uuid_t uuid, out_uuid;
    noit_hash_table *options;

#define NEXT(...) noitL(noit_stderr, __VA_ARGS__); continue
#define MYATTR(type,a,...) noit_conf_get_##type(sec[i], "@" #a, __VA_ARGS__)
#define INHERIT(type,a,...) \
  noit_conf_get_##type(sec[i], "ancestor-or-self::node()/@" #a, __VA_ARGS__)

    if(!MYATTR(stringbuf, uuid, uuid_str, sizeof(uuid_str))) {
      noitL(noit_stderr, "check %d has no uuid\n", i+1);
      continue;
    }

    if(uuid_parse(uuid_str, uuid)) {
      noitL(noit_stderr, "check uuid: '%s' is invalid\n", uuid_str);
      continue;
    }

    if(!INHERIT(stringbuf, target, target, sizeof(target))) {
      noitL(noit_stderr, "check uuid: '%s' has no target\n", uuid_str);
      busted = noit_true;
    }
    if(!INHERIT(stringbuf, module, module, sizeof(module))) {
      noitL(noit_stderr, "check uuid: '%s' has no module\n", uuid_str);
      busted = noit_true;
    }

    if(!INHERIT(stringbuf, filterset, filterset, sizeof(filterset)))
      filterset[0] = '\0';

    if(!MYATTR(stringbuf, name, name, sizeof(name)))
      strlcpy(name, module, sizeof(name));

    if(!INHERIT(int, period, &period) || period == 0)
      no_period = 1;

    if(!INHERIT(stringbuf, oncheck, oncheck, sizeof(oncheck)) || !oncheck[0])
      no_oncheck = 1;

    if(no_period && no_oncheck) {
      noitL(noit_stderr, "check uuid: '%s' has neither period nor oncheck\n",
            uuid_str);
      busted = noit_true;
    }
    if(!(no_period || no_oncheck)) {
      noitL(noit_stderr, "check uuid: '%s' has oncheck and period.\n",
            uuid_str);
      busted = noit_true;
    }
    if(!INHERIT(int, timeout, &timeout)) {
      noitL(noit_stderr, "check uuid: '%s' has no timeout\n", uuid_str);
      busted = noit_true;
    }
    if(!no_period && timeout >= period) {
      noitL(noit_stderr, "check uuid: '%s' timeout > period\n", uuid_str);
      timeout = period/2;
    }
    options = noit_conf_get_hash(sec[i], "config");

    INHERIT(boolean, disable, &disabled);
    flags = 0;
    if(busted) flags |= (NP_UNCONFIG|NP_DISABLED);
    else if(disabled) flags |= NP_DISABLED;

    if(noit_hash_retrieve(&polls, (char *)uuid, UUID_SIZE,
                          &vcheck)) {
      noit_check_t *existing_check = (noit_check_t *)vcheck;
      /* Once set, we can never change it. */
      assert(!existing_check->module || !existing_check->module[0] ||
             !strcmp(existing_check->module, module));
      /* Only set it if it is not yet set */
      if(!existing_check->module || !existing_check->module[0]) {
        if(existing_check->module) free(existing_check->module);
        existing_check->module = strdup(module);
      }
      noit_check_update(existing_check, target, name, filterset, options,
                           period, timeout, oncheck[0] ? oncheck : NULL,
                           flags);
      noitL(noit_debug, "reloaded uuid: %s\n", uuid_str);
    }
    else {
      noit_poller_schedule(target, module, name, filterset, options,
                           period, timeout, oncheck[0] ? oncheck : NULL,
                           flags, uuid, out_uuid);
      noitL(noit_debug, "loaded uuid: %s\n", uuid_str);
    }

    noit_hash_destroy(options, free, free);
    free(options);
  }
  if(sec) free(sec);
}