Changeset c6c11c3827cd812cc0f9cc92cf6de8140b859416

Show
Ignore:
Timestamp:
01/04/12 14:53:41 (7 years ago)
Author:
Theo Schlossnagle <jesus@omniti.com>
git-committer:
Theo Schlossnagle <jesus@omniti.com> 1325688821 -0500
git-parent:

[8dfd79782e697b0ac7f68e010887609de0ff34e9]

git-author:
Theo Schlossnagle <jesus@omniti.com> 1325688821 -0500
Message:

Support generic module configuration with using XML namespaces and
allow modules to register themselves as as interested in such for
all checks.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • src/modules/check_test.c

    r33b7efe rc6c11c3  
    9898  char *target = NULL, *name = NULL, *module = NULL, *filterset = NULL; 
    9999  char *resolve_rtype = NULL; 
    100   int timeout = 0, flags = NP_TRANSIENT
     100  int timeout = 0, flags = NP_TRANSIENT, i, mod_cnt
    101101  noit_module_t *m; 
    102102  noit_check_t *c = NULL; 
    103103  xmlNodePtr a, co; 
    104104  noit_hash_table *conf_hash = NULL; 
     105  noit_hash_table **moptions = NULL; 
    105106 
    106107  for(a = attr->children; a; a = a->next) { 
     
    137138    } 
    138139  } 
     140  mod_cnt = noit_check_registered_module_cnt(); 
     141  if(mod_cnt > 0) { 
     142    moptions = alloca(mod_cnt * sizeof(*moptions)); 
     143    memset(moptions, 0, mod_cnt * sizeof(*moptions)); 
     144    for(i=0; i<mod_cnt; i++) { 
     145      const char *name; 
     146      noit_conf_section_t checks; 
     147      name = noit_check_registered_module(i); 
     148      checks = noit_conf_get_section(NULL, "/noit/checks"); 
     149      if(name) moptions[i] = noit_conf_get_namespaced_hash(checks, "config", name); 
     150    } 
     151  } 
    139152  if(!m->initiate_check) { 
    140153    *error = "that module cannot run checks"; 
     
    144157  c = calloc(1, sizeof(*c)); 
    145158  noit_check_update(c, target, name, filterset, 
    146                     conf_hash, 0, timeout, NULL, flags); 
     159                    conf_hash, moptions, 0, timeout, NULL, flags); 
    147160  c->module = strdup(module); 
    148161  uuid_generate(c->checkid); 
     
    155168    noit_hash_destroy(conf_hash, free, free); 
    156169    free(conf_hash); 
     170  } 
     171  if(moptions) { 
     172    for(i=0; i<mod_cnt; i++) { 
     173      if(moptions[i]) { 
     174        noit_hash_destroy(moptions[i], free, free); 
     175        free(moptions[i]); 
     176      } 
     177    } 
    157178  } 
    158179  if(target) xmlFree(target); 
  • src/noit_check.c

    r0d859ed rc6c11c3  
    5757/* 60 seconds of possible stutter */ 
    5858#define MAX_INITIAL_STUTTER 60000 
    59  
     59#define MAX_MODULE_REGISTRATIONS 64 
     60 
     61/* used to manage per-check generic module metadata */ 
     62struct vp_w_free { 
     63  void *ptr; 
     64  void (*freefunc)(void *); 
     65}; 
     66 
     67static int reg_module_id = 0; 
     68static char *reg_module_names[MAX_MODULE_REGISTRATIONS] = { NULL }; 
     69static int reg_module_used = -1; 
    6070static u_int64_t check_completion_count = 0; 
    6171static noit_hash_table polls = NOIT_HASH_EMPTY; 
     
    162172    char oncheck[1024] = ""; 
    163173    char resolve_rtype[16] = ""; 
     174    int ridx; 
    164175    int no_period = 0; 
    165176    int no_oncheck = 0; 
     
    168179    uuid_t uuid, out_uuid; 
    169180    noit_hash_table *options; 
     181    noit_hash_table **moptions = NULL; 
     182    noit_boolean moptions_used = noit_false; 
     183 
     184    if(reg_module_id > 0) { 
     185      moptions = alloca(reg_module_id * sizeof(noit_hash_table *)); 
     186      memset(moptions, 0, reg_module_id * sizeof(noit_hash_table *)); 
     187    } 
    170188 
    171189#define NEXT(...) noitL(noit_stderr, __VA_ARGS__); continue 
     
    227245    } 
    228246    options = noit_conf_get_hash(sec[i], "config"); 
     247    for(ridx=0; ridx<reg_module_id; ridx++) { 
     248      moptions[ridx] = noit_conf_get_namespaced_hash(sec[i], "config", 
     249                                                     reg_module_names[ridx]); 
     250      if(moptions[ridx]) moptions_used = noit_true; 
     251    } 
    229252 
    230253    INHERIT(boolean, disable, &disabled); 
     
    249272      } 
    250273      noit_check_update(existing_check, target, name, filterset, options, 
     274                           moptions_used ? moptions : NULL, 
    251275                           period, timeout, oncheck[0] ? oncheck : NULL, 
    252276                           flags); 
     
    255279    else { 
    256280      noit_poller_schedule(target, module, name, filterset, options, 
     281                           moptions_used ? moptions : NULL, 
    257282                           period, timeout, oncheck[0] ? oncheck : NULL, 
    258283                           flags, uuid, out_uuid); 
     
    260285    } 
    261286 
     287    for(ridx=0; ridx<reg_module_id; ridx++) { 
     288      if(moptions[ridx]) { 
     289        noit_hash_destroy(moptions[ridx], free, free); 
     290        free(moptions[ridx]); 
     291      } 
     292    } 
    262293    noit_hash_destroy(options, free, free); 
    263294    free(options); 
     
    635666                  const char *filterset, 
    636667                  noit_hash_table *config, 
     668                  noit_hash_table **mconfigs, 
    637669                  u_int32_t period, 
    638670                  u_int32_t timeout, 
     
    682714    } 
    683715  } 
     716  if(mconfigs != NULL) { 
     717    int i; 
     718    for(i=0; i<reg_module_id; i++) { 
     719      if(mconfigs[i]) { 
     720        noit_hash_table *t = calloc(1, sizeof(*new_check->config)); 
     721        noit_hash_merge_as_dict(t, mconfigs[i]); 
     722        noit_check_set_module_config(new_check, i, t); 
     723      } 
     724    } 
     725  } 
    684726  if(new_check->oncheck) free(new_check->oncheck); 
    685727  new_check->oncheck = oncheck ? strdup(oncheck) : NULL; 
     
    711753                     const char *filterset, 
    712754                     noit_hash_table *config, 
     755                     noit_hash_table **mconfigs, 
    713756                     u_int32_t period, 
    714757                     u_int32_t timeout, 
     
    728771    uuid_copy(new_check->checkid, in); 
    729772 
    730   noit_check_update(new_check, target, name, filterset, config, 
     773  noit_check_update(new_check, target, name, filterset, config, mconfigs, 
    731774                    period, timeout, oncheck, flags); 
    732775  assert(noit_hash_store(&polls, 
     
    778821    free(checker->config); 
    779822    checker->config = NULL; 
     823  } 
     824  if(checker->module_metadata) { 
     825    int i; 
     826    for(i=0; i<reg_module_id; i++) { 
     827      struct vp_w_free *tuple; 
     828      tuple = checker->module_metadata[i]; 
     829      if(tuple && tuple->freefunc) tuple->freefunc(tuple->ptr); 
     830      free(tuple); 
     831    } 
     832    free(checker->module_metadata); 
     833  } 
     834  if(checker->module_configs) { 
     835    int i; 
     836    for(i=0; i<reg_module_id; i++) { 
     837      if(checker->module_configs[i]) { 
     838        noit_hash_destroy(checker->module_configs[i], free, free); 
     839        free(checker->module_configs[i]); 
     840      } 
     841    } 
     842    free(checker->module_metadata); 
    780843  } 
    781844  free(checker); 
     
    14241487} 
    14251488 
     1489int 
     1490noit_check_register_module(const char *name) { 
     1491  int i; 
     1492  for(i=0; i<reg_module_id; i++) 
     1493    if(!strcmp(reg_module_names[i], name)) return i; 
     1494  if(reg_module_id >= MAX_MODULE_REGISTRATIONS) return -1; 
     1495  noitL(noit_debug, "Registered module %s as %d\n", name, i); 
     1496  i = reg_module_id++; 
     1497  reg_module_names[i] = strdup(name); 
     1498  return i; 
     1499} 
     1500int 
     1501noit_check_registered_module_cnt() { 
     1502  return reg_module_id; 
     1503} 
     1504const char * 
     1505noit_check_registered_module(int idx) { 
     1506  if(reg_module_used < 0) reg_module_used = reg_module_id; 
     1507  assert(reg_module_used == reg_module_id); 
     1508  if(idx >= reg_module_id || idx < 0) return NULL; 
     1509  return reg_module_names[idx]; 
     1510} 
     1511 
     1512void 
     1513noit_check_set_module_metadata(noit_check_t *c, int idx, void *md, void (*freefunc)(void *)) { 
     1514  struct vp_w_free *tuple; 
     1515  if(reg_module_used < 0) reg_module_used = reg_module_id; 
     1516  assert(reg_module_used == reg_module_id); 
     1517  if(idx >= reg_module_id || idx < 0) return; 
     1518  if(!c->module_metadata) c->module_metadata = calloc(reg_module_id, sizeof(void *)); 
     1519  c->module_metadata[idx] = calloc(1, sizeof(struct vp_w_free)); 
     1520  tuple = c->module_metadata[idx]; 
     1521  tuple->ptr = md; 
     1522  tuple->freefunc = freefunc; 
     1523} 
     1524void 
     1525noit_check_set_module_config(noit_check_t *c, int idx, noit_hash_table *config) { 
     1526  if(reg_module_used < 0) reg_module_used = reg_module_id; 
     1527  assert(reg_module_used == reg_module_id); 
     1528  if(idx >= reg_module_id || idx < 0) return; 
     1529  if(!c->module_configs) c->module_configs = calloc(reg_module_id, sizeof(noit_hash_table *)); 
     1530  c->module_configs[idx] = config; 
     1531} 
     1532void * 
     1533noit_check_get_module_metadata(noit_check_t *c, int idx) { 
     1534  struct vp_w_free *tuple; 
     1535  if(reg_module_used < 0) reg_module_used = reg_module_id; 
     1536  assert(reg_module_used == reg_module_id); 
     1537  if(idx >= reg_module_id || idx < 0 || !c->module_metadata) return NULL; 
     1538  tuple = c->module_metadata[idx]; 
     1539  return tuple ? tuple->ptr : NULL; 
     1540} 
     1541noit_hash_table * 
     1542noit_check_get_module_config(noit_check_t *c, int idx) { 
     1543  if(reg_module_used < 0) reg_module_used = reg_module_id; 
     1544  assert(reg_module_used == reg_module_id); 
     1545  if(idx >= reg_module_id || idx < 0 || !c->module_configs) return NULL; 
     1546  return c->module_configs[idx]; 
     1547} 
  • src/noit_check.h

    r899f2d2 rc6c11c3  
    154154  noit_skiplist *feeds; 
    155155  char target_ip[INET6_ADDRSTRLEN]; 
     156  void **module_metadata; 
     157  noit_hash_table **module_configs; 
    156158} noit_check_t; 
    157159 
     
    186188                       const char *filterset, 
    187189                       noit_hash_table *config, 
     190                       noit_hash_table **mconfig, 
    188191                       u_int32_t period, 
    189192                       u_int32_t timeout, 
     
    202205                    const char *filterset, 
    203206                    noit_hash_table *config, 
     207                    noit_hash_table **mconfig, 
    204208                    u_int32_t period, 
    205209                    u_int32_t timeout, 
     
    278282API_EXPORT(void) 
    279283  noit_check_transient_remove_feed(noit_check_t *check, const char *feed); 
     284 
     285API_EXPORT(int) 
     286  noit_check_register_module(const char *); 
     287API_EXPORT(int) 
     288  noit_check_registered_module_cnt(); 
     289API_EXPORT(const char *) 
     290  noit_check_registered_module(int); 
     291 
     292API_EXPORT(void) 
     293  noit_check_set_module_metadata(noit_check_t *, int, void *, void (*freefunc)(void *)); 
     294API_EXPORT(void) 
     295  noit_check_set_module_config(noit_check_t *, int, noit_hash_table *); 
     296API_EXPORT(void *) 
     297  noit_check_get_module_metadata(noit_check_t *, int); 
     298API_EXPORT(noit_hash_table *) 
     299  noit_check_get_module_config(noit_check_t *, int); 
    280300 
    281301/* These are from noit_check_log.c */ 
  • src/noit_check_rest.c

    r4741bb2 rc6c11c3  
    4848#define FAIL(a) do { error = (a); goto error; } while(0) 
    4949 
    50 #define NODE_CONTENT(parent, k, v) do { \ 
     50#define NS_NODE_CONTENT(parent, ns, k, v) do { \ 
    5151  xmlNodePtr tmp; \ 
    5252  if(v) { \ 
    53     tmp = xmlNewNode(NULL, (xmlChar *)(k)); \ 
     53    tmp = xmlNewNode(ns, (xmlChar *)(k)); \ 
    5454    xmlNodeAddContent(tmp, (xmlChar *)(v)); \ 
    5555    xmlAddChild(parent, tmp); \ 
    5656  } \ 
    5757} while(0) 
     58#define NODE_CONTENT(parent, k, v) NS_NODE_CONTENT(parent, NULL, k, v) 
    5859 
    5960xmlNodePtr 
     
    128129  noit_check_t *check; 
    129130  char xpath[1024], *uuid_conf, *module, *value; 
    130   int rv, cnt, error_code = 500; 
     131  int rv, mod, mod_cnt, cnt, error_code = 500; 
    131132  noit_hash_iter iter = NOIT_HASH_ITER_ZERO; 
    132133  const char *k; 
     
    211212  noit_hash_destroy(configh, free, free); 
    212213  free(configh); 
     214  mod_cnt = noit_check_registered_module_cnt(); 
     215  for(mod=0; mod<mod_cnt; mod++) { 
     216    xmlNsPtr ns; 
     217    const char *nsname; 
     218    char buff[256]; 
     219    nsname = noit_check_registered_module(mod); 
     220    snprintf(buff, sizeof(buff), "noit://module/%s", nsname); 
     221    ns = xmlNewNs(config, (xmlChar *)buff, (xmlChar *)nsname); 
     222    if(NULL != (configh = noit_conf_get_namespaced_hash(node, "config", nsname))) { 
     223      while(noit_hash_next(configh, &iter, &k, &klen, &data)) 
     224        NS_NODE_CONTENT(config, ns, k, data); 
     225      noit_hash_destroy(configh, free, free); 
     226      free(configh); 
     227    } 
     228  } 
    213229  xmlAddChild(root, config); 
    214230 
     
    387403      xmlSetProp(config, (xmlChar *)"inherit", inherit->children->content); 
    388404    for(n = c->children; n; n = n->next) { 
     405      xmlNsPtr targetns = NULL; 
    389406      xmlChar *v = xmlNodeGetContent(n); 
    390       xmlNodePtr co = xmlNewNode(NULL, n->name); 
     407      if(n->ns) { 
     408        targetns = xmlSearchNs(check->doc, config, n->ns->prefix); 
     409        if(!targetns) targetns = xmlNewNs(config, n->ns->href, n->ns->prefix); 
     410      } 
     411      xmlNodePtr co = xmlNewNode(targetns, n->name); 
    391412      xmlNodeAddContent(co, v); 
    392413      xmlFree(v); 
  • src/noit_conf.c

    r82dc7d3 rc6c11c3  
    386386void noit_conf_get_elements_into_hash(noit_conf_section_t section, 
    387387                                      const char *path, 
    388                                       noit_hash_table *table) { 
     388                                      noit_hash_table *table, 
     389                                      const char *namespace) { 
    389390  int i, cnt; 
    390391  xmlXPathObjectPtr pobj = NULL; 
     
    406407    char *value; 
    407408    node = xmlXPathNodeSetItem(pobj->nodesetval, i); 
    408     value = (char *)xmlXPathCastNodeToString(node); 
    409     noit_hash_replace(table, 
    410                       strdup((char *)node->name), strlen((char *)node->name), 
    411                       strdup(value), free, free); 
    412     xmlFree(value); 
     409    if(namespace && node->ns && !strcmp((char *)node->ns->prefix, namespace)) { 
     410      value = (char *)xmlXPathCastNodeToString(node); 
     411      noit_hash_replace(table, 
     412                        strdup((char *)node->name), strlen((char *)node->name), 
     413                        strdup(value), free, free); 
     414      xmlFree(value); 
     415    } 
     416    else if(!namespace && !node->ns) { 
     417      value = (char *)xmlXPathCastNodeToString(node); 
     418      noit_hash_replace(table, 
     419                        strdup((char *)node->name), strlen((char *)node->name), 
     420                        strdup(value), free, free); 
     421      xmlFree(value); 
     422    } 
    413423  } 
    414424 out: 
     
    419429void noit_conf_get_into_hash(noit_conf_section_t section, 
    420430                             const char *path, 
    421                              noit_hash_table *table) { 
     431                             noit_hash_table *table, 
     432                             const char *namespace) { 
    422433  unsigned int cnt; 
    423434  xmlXPathObjectPtr pobj = NULL; 
     
    454465    parent_node = xmlXPathNodeSetItem(pobj->nodesetval, cnt-2); 
    455466    if(parent_node != current_node) 
    456       noit_conf_get_into_hash(parent_node, (const char *)node->name, table); 
     467      noit_conf_get_into_hash(parent_node, (const char *)node->name, table, namespace); 
    457468  } 
    458469  /* 2. */ 
     
    460471  if(inheritid) { 
    461472    snprintf(xpath_expr, sizeof(xpath_expr), "//*[@id=\"%s\"]", inheritid); 
    462     noit_conf_get_into_hash(NULL, xpath_expr, table); 
     473    noit_conf_get_into_hash(NULL, xpath_expr, table, namespace); 
    463474    xmlFree(inheritid); 
    464475  } 
    465476  /* 3. */ 
    466   noit_conf_get_elements_into_hash(node, "*", table); 
     477  noit_conf_get_elements_into_hash(node, "*", table, namespace); 
    467478 
    468479 out: 
     
    471482    xmlXPathFreeContext(current_ctxt); 
    472483} 
     484noit_hash_table *noit_conf_get_namespaced_hash(noit_conf_section_t section, 
     485                                               const char *path, const char *ns) { 
     486  noit_hash_table *table = NULL; 
     487 
     488  table = calloc(1, sizeof(*table)); 
     489  noit_conf_get_into_hash(section, path, table, ns); 
     490  if(table->size == 0) { 
     491    noit_hash_destroy(table, free, free); 
     492    free(table); 
     493    table = NULL; 
     494  } 
     495  return table; 
     496} 
    473497noit_hash_table *noit_conf_get_hash(noit_conf_section_t section, 
    474498                                    const char *path) { 
     
    476500 
    477501  table = calloc(1, sizeof(*table)); 
    478   noit_conf_get_into_hash(section, path, table); 
     502  noit_conf_get_into_hash(section, path, table, NULL); 
    479503  return table; 
    480504} 
  • src/noit_conf.h

    rdb7317d rc6c11c3  
    7777API_EXPORT(noit_hash_table *) 
    7878  noit_conf_get_hash(noit_conf_section_t section, const char *path); 
     79API_EXPORT(noit_hash_table *) 
     80  noit_conf_get_namespaced_hash(noit_conf_section_t section, 
     81                                const char *path, const char *ns); 
    7982 
    8083API_EXPORT(int) noit_conf_get_string(noit_conf_section_t section,