Beispiel #1
0
static int
lua_general_reverse_socket_initiate(lua_State *L) {
  const char *host;
  int port;
  mtev_hash_table *sslconfig = NULL, *config = NULL;
  if(lua_gettop(L) < 2 ||
     !lua_isstring(L,1) ||
     !lua_isnumber(L,2) ||
     (lua_gettop(L) >= 3 && !lua_istable(L,3)) ||
     (lua_gettop(L) >= 4 && !lua_istable(L,4)))
    luaL_error(L, "reverse_start(host,port,sslconfig,config)");

  host = lua_tostring(L,1);
  port = lua_tointeger(L,2);
  if(lua_gettop(L)>=3) sslconfig = mtev_lua_table_to_hash(L,3);
  if(lua_gettop(L)>=4) config = mtev_lua_table_to_hash(L,4);

  mtev_lua_help_initiate_mtev_connection(host, port, sslconfig, config);

  if(sslconfig) {
    mtev_hash_destroy(sslconfig, NULL, NULL);
    free(sslconfig);
  }
  if(config) {
    mtev_hash_destroy(config, NULL, NULL);
    free(config);
  }
  return 0;
}
static mtev_hash_table *
get_dedupe_hash(uint64_t whence)
{
  struct hash_and_time *hash_with_time;
  mtev_hash_table *hash;

  if (mtev_hash_retrieve(&dedupe_hashes, (const char *)&whence, sizeof(whence), (void **)&hash_with_time) == 1) {
    hash = &hash_with_time->hash;
  } else {
    hash_with_time = calloc(1, sizeof(struct hash_and_time));

    mtev_hash_init_locks(&hash_with_time->hash, MTEV_HASH_DEFAULT_SIZE, MTEV_HASH_LOCK_MODE_MUTEX);
    uint64_t *stored_ts = calloc(1, sizeof(uint64_t));
    *stored_ts = whence;
    if (mtev_hash_store(&dedupe_hashes, (const char *)stored_ts, sizeof(*stored_ts), hash_with_time) == 0) {
      /* ugh, someone beat us */
      free(stored_ts);
      mtev_hash_destroy(&hash_with_time->hash, NULL, NULL);
      free(hash_with_time);
      if (mtev_hash_retrieve(&dedupe_hashes, (const char *)&whence, sizeof(whence), (void **)&hash_with_time) == 0) {
        return NULL;
      }
    }
    hash = &hash_with_time->hash;
  }

  hash_with_time->last_touched_s = mtev_gethrtime() / 1000000000;
  return hash;
}
Beispiel #3
0
static int do_test(mtev_hash_lock_mode_t lock_mode) {
  mtev_hash_table hash;

  mtev_hash_init_locks(&hash, 400, lock_mode);

  pthread_t threads[THREAD_COUNT];
  for (int i = 0; i < THREAD_COUNT; i++) {
    pthread_create(&threads[i], NULL, thread_func, &hash);
  }

  for (int i = 0; i < THREAD_COUNT; i++) {
    pthread_join(threads[i], NULL);
  }

  mtev_hash_iter iter = MTEV_HASH_ITER_ZERO;

  const char *k;
  int klen;
  void *data;

  while(mtev_hash_next(&hash, &iter, &k, &klen, &data)) {
    printf("%s\n", k);
  }

  mtev_hash_destroy(&hash, free, NULL);
  return 0;
}
static int
prune_old_dedupe_hashes(eventer_t e, int mask, void *unused,
    struct timeval *now) {

  mtev_hash_iter iter = MTEV_HASH_ITER_ZERO;
  uint64_t now_hrtime = mtev_gethrtime() / 1000000000;
  const char *k;
  int klen;
  void *data;
  struct hash_and_time *hash_with_time;

  struct removable_hashes {
    uint64_t key;
    struct hash_and_time *data;
    struct removable_hashes *next;
  };

  struct removable_hashes *head = NULL;
  struct removable_hashes *tail = NULL;

  /* build a list of expirable items */
  while(mtev_hash_next(&dedupe_hashes, &iter, &k, &klen, &data)) {
    hash_with_time = data;
    if (now_hrtime > hash_with_time->last_touched_s && now_hrtime - hash_with_time->last_touched_s > 10) {
      struct removable_hashes *h = calloc(1, sizeof(struct removable_hashes));
      h->key = *(uint64_t *)k;
      h->data = hash_with_time;
      if (tail != NULL) {
        tail->next = h;
      }
      tail = h;

      if (head == NULL) {
        head = tail;
      }
    }
  }

  /* expire them */
  while (head != NULL) {
    mtev_hash_delete(&dedupe_hashes, (const char *)&head->key, sizeof(head->key), free, NULL);
    mtev_hash_destroy(&head->data->hash, free, NULL);
    free(head->data);
    struct removable_hashes *prev = head;
    head = head->next;
    free(prev);
  }

  e->whence.tv_sec = now->tv_sec + 5;
  return 1;
}
Beispiel #5
0
static int mtev_httptrap_config(noit_module_t *self, mtev_hash_table *options) {
  httptrap_mod_config_t *conf;
  conf = noit_module_get_userdata(self);
  if(conf) {
    if(conf->options) {
      mtev_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;
}
Beispiel #6
0
static
int configure_eventer() {
  int rv = 0;
  mtev_hash_table *table;
  table = mtev_conf_get_hash(NULL, "/" APPNAME "/eventer/config");
  if(table) {
    mtev_hash_iter iter = MTEV_HASH_ITER_ZERO;
    const char *key, *value;
    int klen;
    while(mtev_hash_next_str(table, &iter, &key, &klen, &value)) {
      int subrv;
      if((subrv = eventer_propset(key, value)) != 0)
        rv = subrv;
    }
    mtev_hash_destroy(table, free, free);
    free(table);
  }
  return rv;
}
Beispiel #7
0
static int
noit_lua_interpolate(lua_State *L) {
  noit_check_t *check;
  mtev_hash_table check_attrs_hash;
  char buff[8192];

  if(lua_gettop(L) != 1) luaL_error(L, "wrong number of arguments");
  check = lua_touserdata(L, lua_upvalueindex(1));
  if(!lua_isstring(L,1) && !lua_istable(L,1)) {
    luaL_error(L, "noit.check.interpolate(<string|table>)");
  }

  noit_check_make_attrs(check, &check_attrs_hash);
  if(lua_isstring(L,1)) {
    const char *ns = lua_tostring(L, 1);
    noit_check_interpolate(buff, sizeof(buff), ns,
                           &check_attrs_hash, check->config);
    lua_pushstring(L, buff);
  }
  else {
    /* We have a table */
         /* And we need a new table to return */
    lua_createtable(L, 0, 0);

    /* push a blank key to prep for lua_next calls */
    lua_pushnil(L);
    while(lua_next(L, -3)) { /* src table is -3 */
      const char *key = lua_tostring(L, -2);
      if(lua_isstring(L, -1)) {
                               const char *ns = lua_tostring(L,-1);
        noit_check_interpolate(buff, sizeof(buff), ns,
                               &check_attrs_hash, check->config);
                               lua_pop(L,1);
        lua_pushstring(L, buff);
                       }
                       lua_setfield(L, -3, key); /* tgt table is -3 */
    }
  }
  mtev_hash_destroy(&check_attrs_hash, NULL, NULL);
  return 1;
}
Beispiel #8
0
static int
configure_eventer(const char *appname) {
    int rv = 0;
    mtev_boolean rlim_found = mtev_false;
    mtev_hash_table *table;
    char appscratch[1024];

    snprintf(appscratch, sizeof(appscratch), "/%s/eventer/config", appname);
    table = mtev_conf_get_hash(NULL, appscratch);
    if(table) {
        mtev_hash_iter iter = MTEV_HASH_ITER_ZERO;
        const char *key, *value;
        int klen;
        while(mtev_hash_next_str(table, &iter, &key, &klen, &value)) {
            int subrv;
            /* We want to set a sane default if the user doesn't provide an
             * rlim_nofiles value... however, we have to try to set the user
             * value before we set the default, because otherwise, if snowth
             * is being run as a non-privileged user and we set a default
             * lower than the user specified one, we can't raise it. Ergo -
             * try to set from the config first, then set a default if one
             * isn't specified */
            if ((strlen(key) == strlen("rlim_nofiles")) &&
                    (strncmp(key, "rlim_nofiles", strlen(key)) == 0) ) {
                rlim_found = mtev_true;
            }
            if((subrv = eventer_propset(key, value)) != 0)
                rv = subrv;
        }
        mtev_hash_destroy(table, free, free);
        free(table);
    }

    /* If no rlim_nofiles configuration was found, set a default
     * of (2048*2048) */
    if (!rlim_found) {
        eventer_propset("rlim_nofiles", "4194304");
    }
    return rv;
}
Beispiel #9
0
static int
rest_show_check(mtev_http_rest_closure_t *restc,
                int npats, char **pats) {
  mtev_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 = NULL, *value = NULL;
  int rv, mod, mod_cnt, cnt, error_code = 500;
  mtev_hash_iter iter = MTEV_HASH_ITER_ZERO;
  const char *k;
  int klen;
  void *data;
  mtev_hash_table *configh;

  if(npats != 2 && npats != 3) goto error;

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

  mtev_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 = (mtev_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, 0);
  uuid_conf = (char *)xmlGetProp(node, (xmlChar *)"uuid");
  if(!uuid_conf || uuid_parse(uuid_conf, checkid)) goto error;

  if(npats == 3 && !strcmp(pats[2], ".json")) {
    return rest_show_check_json(restc, checkid);
  }

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

#define MYATTR(node,a,n,b) _mtev_conf_get_string(node, &(n), "@" #a, &(b))
#define INHERIT(node,a,n,b) \
  _mtev_conf_get_string(node, &(n), "ancestor-or-self::node()/@" #a, &(b))
#define SHOW_ATTR(parent, node, a) do { \
  char *_value = NULL; \
  INHERIT(node, a, anode, _value); \
  if(_value != NULL) { \
    int clen, plen;\
    char *_cpath, *_apath; \
    xmlNodePtr child; \
    _cpath = node ? (char *)xmlGetNodePath(node) : strdup(""); \
    _apath = anode ? (char *)xmlGetNodePath(anode) : strdup(""); \
    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); \
    free(_cpath); \
    free(_apath); \
    free(_value); \
  } \
} while(0)

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

  SHOW_ATTR(attr,node,uuid);
  SHOW_ATTR(attr,node,seq);

  /* 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);
  if(value) free(value);
  if(module) free(module);

  SHOW_ATTR(attr,node,module);
  SHOW_ATTR(attr,node,target);
  SHOW_ATTR(attr,node,resolve_rtype);
  SHOW_ATTR(attr,node,seq);
  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 = mtev_conf_get_hash(node, "config");
  while(mtev_hash_next(configh, &iter, &k, &klen, &data))
    NODE_CONTENT(config, k, data);
  mtev_hash_destroy(configh, free, free);
  free(configh);

  mod_cnt = noit_check_registered_module_cnt();
  for(mod=0; mod<mod_cnt; mod++) {
    xmlNsPtr ns;
    const char *nsname;
    char buff[256];

    nsname = noit_check_registered_module(mod);
 
    snprintf(buff, sizeof(buff), "noit://module/%s", nsname);
    ns = xmlSearchNs(root->doc, root, (xmlChar *)nsname);
    if(!ns) ns = xmlNewNs(root, (xmlChar *)buff, (xmlChar *)nsname);
    if(ns) {
      configh = mtev_conf_get_namespaced_hash(node, "config", nsname);
      if(configh) {
        memset(&iter, 0, sizeof(iter));
        while(mtev_hash_next(configh, &iter, &k, &klen, &data)) {
          NS_NODE_CONTENT(config, ns, "value", data,
            xmlSetProp(tmp, (xmlChar *)"name", (xmlChar *)k);
          );
        }
        mtev_hash_destroy(configh, free, free);
        free(configh);
      }
    }
  }
Beispiel #10
0
void mtev_dso_init(void) {
  mtev_conf_section_t *sections;
  int i, cnt = 0;

  mtev_dso_add_type("loader", mtev_dso_list_loaders);
  mtev_dso_add_type("generic", mtev_dso_list_generics);

  /* Load our generic modules */
  sections = mtev_conf_get_sections(MTEV_CONF_ROOT, "//modules//generic", &cnt);
  for(i=0; i<cnt; i++) {
    char g_name[256];
    mtev_dso_generic_t *gen;
    mtev_conf_section_t *include_sections = NULL;
    int section_cnt;

    if(!mtev_conf_get_stringbuf(sections[i], "ancestor-or-self::node()/@name",
                                g_name, sizeof(g_name))) {
      mtevL(mtev_stderr, "No name defined in generic stanza %d\n", i+1);
      continue;
    }

    if(mtev_conf_env_off(sections[i], NULL)) {
      mtevL(mtev_debug, "generic module %s environmentally disabled.\n", g_name);
      continue;
    }

    gen = (mtev_dso_generic_t *)
      mtev_load_generic_image(&__mtev_image_loader, g_name,
                              sections[i]);
    if(!gen) {
      mtevL(mtev_stderr, "Failed to load generic %s\n", g_name);
      mtev_dso_load_failure_count++;
      continue;
    }
    if(gen->config) {
      int rv;
      mtev_hash_table *config;
      include_sections = mtev_conf_get_sections(sections[i], "include", &section_cnt);
      if ((include_sections) && (section_cnt == 1)) {
        config = mtev_conf_get_hash(*include_sections, "config");
      }
      else {
        config = mtev_conf_get_hash(sections[i], "config");
      }
      mtev_conf_release_sections(include_sections, section_cnt);
      rv = gen->config(gen, config);
      if(rv == 0) {
        mtev_hash_destroy(config, free, free);
        free(config);
      }
      else if(rv < 0) {
        mtevL(mtev_stderr, "Failed to config generic %s\n", g_name);
        continue;
      }
    }
    if(gen->init && gen->init(gen)) {
      mtevL(mtev_stderr, "Failed to init generic %s\n", g_name);
      mtev_dso_load_failure_count++;
    }
    else
      mtevL(mtev_debug, "Generic module %s successfully loaded.\n", g_name);
  }
  mtev_conf_release_sections(sections, cnt);
  /* Load our module loaders */
  sections = mtev_conf_get_sections(MTEV_CONF_ROOT, "//modules//loader", &cnt);
  for(i=0; i<cnt; i++) {
    char loader_name[256];
    mtev_dso_loader_t *loader;
    mtev_conf_section_t *include_sections = NULL;
    int section_cnt;

    if(!mtev_conf_get_stringbuf(sections[i], "ancestor-or-self::node()/@name",
                                loader_name, sizeof(loader_name))) {
      mtevL(mtev_stderr, "No name defined in loader stanza %d\n", i+1);
      continue;
    }

    if(mtev_conf_env_off(sections[i], NULL)) {
      mtevL(mtev_debug, "loader %s environmentally disabled.\n", loader_name);
      continue;
    }

    loader = (mtev_dso_loader_t *)
      mtev_load_loader_image(&__mtev_image_loader, loader_name,
                             sections[i]);
    if(!loader) {
      mtevL(mtev_stderr, "Failed to load loader %s\n", loader_name);
      mtev_dso_load_failure_count++;
      continue;
    }
    if(loader->config) {
      int rv;
      mtev_hash_table *config;
      include_sections = mtev_conf_get_sections(sections[i], "include", &section_cnt);
      if ((include_sections) && (section_cnt == 1)) {
        config = mtev_conf_get_hash(*include_sections, "config");
      }
      else {
        config = mtev_conf_get_hash(sections[i], "config");
      }
      mtev_conf_release_sections(include_sections, section_cnt);
      rv = loader->config(loader, config);
      if(rv == 0) {
        mtev_hash_destroy(config, free, free);
        free(config);
      }
      else if(rv < 0) {
        mtevL(mtev_stderr, "Failed to config loader %s\n", loader_name);
        mtev_dso_load_failure_count++;
        continue;
      }
    }
    if(loader->init && loader->init(loader))
      mtevL(mtev_stderr, "Failed to init loader %s\n", loader_name);
  }
  mtev_conf_release_sections(sections, cnt);
}
static int
stratcon_datastore_journal_sync(eventer_t e, int mask, void *closure,
                                struct timeval *now) {
  mtev_hash_iter iter = MTEV_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;

  mtevL(ds_deb, "Syncing journal sets...\n");
  if (syncset->ws) {
    while(mtev_hash_next(syncset->ws, &iter, &k, &klen, &vij)) {
      char tmppath[PATH_MAX], id_str[32];
      int suffix_idx;
      ij = vij;
      mtevL(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:
          mtevL(noit_error, "rename failed(%s): (%s->%s)\n", strerror(errno),
                tmppath, ij->filename);
          exit(-1);
        }
      }
      if(ij->fd >= 0) {
        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,
                      mtev_false);
    }
    mtev_hash_destroy(syncset->ws, free, interim_journal_free);
    free(syncset->ws);
  }
  else {
    mtevL(noit_error, "attempted to sync non-existing working set\n");
  }

  return 0;
}
static int
noit_console_show_check(mtev_console_closure_t ncct,
                        int argc, char **argv,
                        mtev_console_state_t *state, void *closure) {
  int i, cnt;
  mtev_conf_t_userdata_t *info;
  char xpath[1024];
  xmlXPathObjectPtr pobj = NULL;
  xmlXPathContextPtr xpath_ctxt = NULL;

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

  info = mtev_console_userdata_get(ncct, MTEV_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++) {
    mtev_hash_iter iter = MTEV_HASH_ITER_ZERO;
    const char *k;
    int klen;
    void *data;
    uuid_t checkid;
    noit_check_t *check;
    mtev_hash_table *config;
    xmlNodePtr node, anode, mnode = NULL;
    char *uuid_conf;
    char *module, *value;

    node = (mtev_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);
    xmlFree(uuid_conf);

#define MYATTR(a,n,b) _mtev_conf_get_string(node, &(n), "@" #a, &(b))
#define INHERIT(a,n,b) \
  _mtev_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); \
  if(value != NULL) free(value); \
} while(0)

    if(!INHERIT(module, mnode, module)) module = NULL;
    if(MYATTR(name, anode, value)) {
      nc_printf(ncct, " name: %s\n", value);
      free(value);
    }
    else
      nc_printf(ncct, " name: %s [from module]\n", module ? module : "[undef]");
    nc_attr_show(ncct, "module", node, mnode, module);
    if(module) free(module);
    SHOW_ATTR(target);
    SHOW_ATTR(seq);
    SHOW_ATTR(resolve_rtype);
    SHOW_ATTR(period);
    SHOW_ATTR(timeout);
    SHOW_ATTR(oncheck);
    SHOW_ATTR(filterset);
    SHOW_ATTR(disable);
    /* Print out all the config settings */
    config = mtev_conf_get_hash(node, "config");
    while(mtev_hash_next(config, &iter, &k, &klen, &data)) {
      nc_printf(ncct, " config::%s: %s\n", k, (const char *)data);
    }
    mtev_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;
      stats_t *c;
      struct timeval *whence;
      mtev_hash_table *metrics;
      nc_printf(ncct, " target_ip: %s\n", check->target_ip);
      nc_printf(ncct, " currently: %08x ", check->flags);
      if(NOIT_CHECK_RUNNING(check)) { nc_printf(ncct, "running"); 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->fire_event != NULL) {
        struct timeval now, diff;
        mtev_gettimeofday(&now, NULL);
        sub_timeval(check->fire_event->whence, now, &diff);
        nc_printf(ncct, " next run: %0.3f seconds\n",
                diff.tv_sec + (diff.tv_usec / 1000000.0));
      }
      else {
        nc_printf(ncct, " next run: unscheduled\n");
      }

      c = noit_check_get_stats_current(check);
      whence = noit_check_stats_whence(c, NULL);
      if(whence->tv_sec == 0) {
        nc_printf(ncct, " last run: never\n");
      }
      else {
        const char *status;
        struct timeval now, *then, diff;
        mtev_gettimeofday(&now, NULL);
        then = noit_check_stats_whence(c, NULL);
        sub_timeval(now, *then, &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(noit_check_stats_available(c, NULL)),
                  noit_check_state_string(noit_check_stats_state(c, NULL)));
        status = noit_check_stats_status(c, NULL);
        nc_printf(ncct, " status: %s\n", status);
        nc_printf(ncct, " feeds: %d\n", check->feeds ? check->feeds->size : 0);
      }

      c = noit_check_get_stats_inprogress(check);
      metrics = noit_check_stats_metrics(c);
      if(mtev_hash_size(metrics) > 0) {
        nc_printf(ncct, " metrics (inprogress):\n");
        nc_print_stat_metrics(ncct, check, c);
      }
      c = noit_check_get_stats_current(check);
      metrics = noit_check_stats_metrics(c);
      if(mtev_hash_size(metrics)) {
        nc_printf(ncct, " metrics (current):\n");
        nc_print_stat_metrics(ncct, check, c);
      }
      c = noit_check_get_stats_previous(check);
      metrics = noit_check_stats_metrics(c);
      if(mtev_hash_size(metrics) > 0) {
        nc_printf(ncct, " metrics (previous):\n");
        nc_print_stat_metrics(ncct, check, c);
      }
    }
  }
 out:
  if(pobj) xmlXPathFreeObject(pobj);
  return 0;
}
Beispiel #13
0
static int mysql_drive_session(eventer_t e, int mask, void *closure,
                                  struct timeval *now) {
  const char *dsn, *sql;
  char sql_buff[8192];
  char dsn_buff[512];
  mysql_check_info_t *ci = closure;
  noit_check_t *check = ci->check;
  struct timeval t1, t2, diff;
  mtev_hash_table dsn_h = MTEV_HASH_EMPTY;
  const char *host=NULL;
  const char *user=NULL;
  const char *password=NULL;
  const char *dbname=NULL;
  const char *port_s=NULL;
  const char *socket=NULL;
  const char *sslmode=NULL;
  u_int32_t port;
  unsigned long client_flag = CLIENT_IGNORE_SIGPIPE;
  unsigned int timeout;

  if(mask & (EVENTER_READ | EVENTER_WRITE)) {
    /* this case is impossible from the eventer.  It is called as
     * such on the synchronous completion of the event.
     */
    mysql_log_results(ci->self, ci->check);
    mysql_cleanup(ci->self, ci->check);
    check->flags &= ~NP_RUNNING;
    return 0;
  }
  switch(mask) {
    case EVENTER_ASYNCH_WORK:
      ci->connect_duration = NULL;
      ci->query_duration = NULL;

      FETCH_CONFIG_OR(dsn, "");
      noit_check_interpolate(dsn_buff, sizeof(dsn_buff), dsn,
                             &ci->attrs, check->config);

      mysql_parse_dsn(dsn_buff, &dsn_h);
      mtev_hash_retrieve(&dsn_h, "host", strlen("host"), (void**)&host);
      mtev_hash_retrieve(&dsn_h, "user", strlen("user"), (void**)&user);
      mtev_hash_retrieve(&dsn_h, "password", strlen("password"), (void**)&password);
      mtev_hash_retrieve(&dsn_h, "dbname", strlen("dbname"), (void**)&dbname);
      mtev_hash_retrieve(&dsn_h, "port", strlen("port"), (void**)&port_s);
      if(mtev_hash_retrieve(&dsn_h, "sslmode", strlen("sslmode"), (void**)&sslmode) &&
         !strcmp(sslmode, "require"))
        client_flag |= CLIENT_SSL;
      port = port_s ? strtol(port_s, NULL, 10) : 3306;
      mtev_hash_retrieve(&dsn_h, "socket", strlen("socket"), (void**)&socket);

      ci->conn = mysql_init(NULL); /* allocate us a handle */
      if(!ci->conn) AVAIL_BAIL("mysql_init failed");
      timeout = check->timeout / 1000;
      mysql_options(ci->conn, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&timeout);
      if(!mysql_real_connect(ci->conn, host, user, password,
                             dbname, port, socket, client_flag)) {
        mtevL(noit_stderr, "error during mysql_real_connect: %s\n",
          mysql_error(ci->conn));
        AVAIL_BAIL(mysql_error(ci->conn));
      }
      if(mysql_ping(ci->conn))
        AVAIL_BAIL(mysql_error(ci->conn));

#if MYSQL_VERSION_ID >= 50000
      if (sslmode && !strcmp(sslmode, "require")) {
        /* mysql has a bad habit of silently failing to establish ssl and
         * falling back to unencrypted, so after making the connection, let's 
         * check that we're actually using SSL by checking for a non-NULL 
         * return value from mysql_get_ssl_cipher().
         */
        if (mysql_get_ssl_cipher(ci->conn) == NULL) {
          mtevL(nldeb, "mysql_get_ssl_cipher() returns NULL, but SSL mode required.");
          AVAIL_BAIL("mysql_get_ssl_cipher() returns NULL, but SSL mode required.");
        }
      }
#endif

      gettimeofday(&t1, NULL);
      sub_timeval(t1, check->last_fire_time, &diff);
      ci->connect_duration_d = diff.tv_sec * 1000.0 + diff.tv_usec / 1000.0;
      ci->connect_duration = &ci->connect_duration_d;

      FETCH_CONFIG_OR(sql, "");
      noit_check_interpolate(sql_buff, sizeof(sql_buff), sql,
                             &ci->attrs, check->config);
      if (mysql_query(ci->conn, sql_buff))
        AVAIL_BAIL(mysql_error(ci->conn));

      gettimeofday(&t2, NULL);
      sub_timeval(t2, t1, &diff);
      ci->query_duration_d = diff.tv_sec * 1000.0 + diff.tv_usec / 1000.0;
      ci->query_duration = &ci->query_duration_d;

      ci->result = mysql_store_result(ci->conn);
      if(!ci->result) AVAIL_BAIL("mysql_store_result failed");
      ci->rv = mysql_num_rows(ci->result);
      mysql_ingest_stats(ci);
      if(ci->result) {
        MYSQL_RES *result_swap = ci->result;
        ci->result = NULL;
        mysql_free_result(result_swap);
      }
      if(ci->conn) {
        MYSQL *conn_swap = ci->conn;
        ci->conn = NULL;
        mysql_close(conn_swap);
      }
      ci->timed_out = 0;
      mtev_hash_destroy(&dsn_h, free, free);
      return 0;
      break;
    case EVENTER_ASYNCH_CLEANUP:
      /* This sets us up for a completion call. */
      e->mask = EVENTER_READ | EVENTER_WRITE;
      break;
    default:
      abort();
  }
  return 0;
}
Beispiel #14
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 = NULL;
  noit_check_t *c = NULL;
  xmlNodePtr a, co;
  mtev_hash_table *conf_hash = NULL;
  mtev_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);
  }
  if(!noit_check_validate_target(target)) {
    *error = "malformed target";
    goto error;
  }
  if(!noit_check_validate_name(name)) {
    *error = "malformed name";
    goto error;
  }
  if(module) 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 : "");
      mtev_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;
      mtev_conf_section_t checks;
      name = noit_check_registered_module(i);
      checks = mtev_conf_get_section(NULL, "/noit/checks");
      if(name) moptions[i] = mtev_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 = mtev_memory_safe_calloc(1, sizeof(*c));
  c->module = strdup(module);
  c->flags = NP_TRANSIENT;
  noit_check_update(c, target, name, filterset,
                    conf_hash, moptions, 0, timeout, NULL, 0, flags);
  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) {
    mtev_hash_destroy(conf_hash, free, free);
    free(conf_hash);
  }
  if(moptions) {
    for(i=0; i<mod_cnt; i++) {
      if(moptions[i]) {
        mtev_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 #15
0
int
noit_filtersets_cull_unused() {
  mtev_hash_table active = MTEV_HASH_EMPTY;
  char *buffer = NULL;
  mtev_conf_section_t *declares;
  int i, n_uses = 0, n_declares = 0, removed = 0;
  const char *declare_xpath = "//filterset[@name and not (@cull='false')]";

  declares = mtev_conf_get_sections(NULL, declare_xpath, &n_declares);
  if(declares) {
    /* store all unit filtersets used */
    for(i=0;i<n_declares;i++) {
      if(!buffer) buffer = malloc(128);
      if(mtev_conf_get_stringbuf(declares[i], "@name", buffer, 128)) {
        if(mtev_hash_store(&active, buffer, strlen(buffer), declares[i])) {
          buffer = NULL;
        }
        else {
          void *vnode = NULL;
          /* We've just hit a duplicate.... check to see if there's an existing
           * entry and if there is, load the latest one and delete the old
           * one. */
          mtev_hash_retrieve(&active, buffer, strlen(buffer), &vnode);
          if (vnode) {
            noit_filter_compile_add(declares[i]);
            CONF_REMOVE(vnode);
            xmlUnlinkNode(vnode);
            xmlFreeNode(vnode);
            removed++;
            if(mtev_hash_replace(&active, buffer, strlen(buffer), declares[i], free, NULL)) {
              buffer = NULL;
            }
          }
        }
      }
    }
    if(buffer) free(buffer);
    free(declares);
  }

  n_uses = noit_poller_do(filterset_accum, &active);

  if(n_uses > 0 && mtev_hash_size(&active) > 0) {
    mtev_hash_iter iter = MTEV_HASH_ITER_ZERO;
    const char *filter_name;
    int filter_name_len;
    void *vnode;
    while(mtev_hash_next(&active, &iter, &filter_name, &filter_name_len,
                         &vnode)) {
      if(noit_filter_remove(vnode)) {
        CONF_REMOVE(vnode);
        xmlUnlinkNode(vnode);
        xmlFreeNode(vnode);
        removed++;
      }
    }
  }

  mtev_hash_destroy(&active, free, NULL);
  return removed;
}
static int
noit_console_config_show(mtev_console_closure_t ncct,
                         int argc, char **argv,
                         mtev_console_state_t *state, void *closure) {
  mtev_hash_iter iter = MTEV_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];
  mtev_conf_t_userdata_t *info = NULL;
  mtev_hash_table *config;
  xmlXPathObjectPtr pobj = NULL;
  xmlXPathContextPtr xpath_ctxt = NULL, current_ctxt;
  xmlDocPtr master_config = NULL;
  xmlNodePtr node = NULL;

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

  info = mtev_console_userdata_get(ncct, MTEV_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 = (mtev_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, i);
    if(!strcmp((char *)node->name, "check")) continue;
    if(node->children && node->children == xmlGetLastChild(node) &&
      xmlNodeIsText(node->children)) {
      char *node_str, *xmlpath;
      node_str = (char *)xmlXPathCastNodeToString(node->children);
      xmlpath = (char *)xmlGetNodePath(node);
      if(!titled++) nc_printf(ncct, "== Section Settings ==\n");
      nc_printf(ncct, "%s: %s\n", xmlpath + cliplen, node_str);
      free(xmlpath);
      free(node_str);
    }
  }
  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 = (mtev_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, 0);
    titled = 0;
    config = mtev_conf_get_hash(node, "config");
    while(mtev_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);
    }
    mtev_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++) {
    char *xmlpath;
    node = (mtev_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, i);
    if(!strcmp((char *)node->name, "check")) continue;
    if(!strcmp((char *)node->name, "filterset")) continue;
    xmlpath = (char *)xmlGetNodePath(node);
    if(strcmp(xmlpath + cliplen, "config")) {
      if(!(node->children && node->children == xmlGetLastChild(node) &&
           xmlNodeIsText(node->children))) {
        if(!titled++) nc_printf(ncct, "== Subsections ==\n");
        nc_printf(ncct, "%s\n", xmlpath + cliplen);
      }
    }
    free(xmlpath);
  }

  titled = 0;
  for(i=0; i<cnt; i++) {
    node = (mtev_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 = NULL;
      uuid_t checkid;

      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);
          break;
        }
      }
      nc_printf(ncct, "check[@uuid=\"%s\"] ", uuid_str ? uuid_str : "undefined");
      if(uuid_str && 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);
        }
      }
      if(uuid_str) free(uuid_str);
      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;
}
Beispiel #17
0
static void free_hash_o_histotier(void *vh) {
  mtev_hash_table *h = vh;
  mtev_hash_destroy(h, free, free_histotier);
  free(h);
}