static void handle_extra_feeds(noit_check_t *check, int (*log_f)(mtev_log_stream_t ls, noit_check_t *check)) { mtev_log_stream_t ls; mtev_skiplist_node *curr, *next; const char *feed_name; if(!check->feeds) return; curr = next = mtev_skiplist_getlist(check->feeds); while(curr) { /* We advance next here (before we try to use curr). * We may need to remove the node we're looking at and that would * disturb the iterator, so advance in advance. */ mtev_skiplist_next(check->feeds, &next); feed_name = (char *)curr->data; ls = mtev_log_stream_find(feed_name); if(!ls || log_f(ls, check)) { noit_check_transient_remove_feed(check, feed_name); /* mtev_skiplisti_remove(check->feeds, curr, free); */ } curr = next; } /* We're done... we may have destroyed the last feed. * that combined with transience means we should kill the check */ /* noit_check_transient_remove_feed(check, NULL); */ }
void mtev_skiplist_add_index(mtev_skiplist *sl, mtev_skiplist_comparator_t comp, mtev_skiplist_comparator_t compk) { mtev_skiplist_node *m = NULL; mtev_skiplist *ni; int icount=0; mtev_skiplist_find(sl->index, (void *)comp, &m); if(m) return; /* Index already there! */ ni = (mtev_skiplist *)malloc(sizeof(mtev_skiplist)); mtev_skiplisti_init(ni); mtev_skiplist_set_compare(ni, comp, compk); /* Build the new index... This can be expensive! */ m = mtev_skiplist_insert(sl->index, ni); while(m->prev) m=m->prev, icount++; for(m=mtev_skiplist_getlist(sl); m; mtev_skiplist_next(sl, &m)) { int j=icount-1; mtev_skiplist_node *nsln; nsln = mtev_skiplist_insert(ni, m->data); /* skip from main index down list */ while(j>0) m=m->nextindex, j--; /* insert this node in the indexlist after m */ nsln->nextindex = m->nextindex; if(m->nextindex) m->nextindex->previndex = nsln; nsln->previndex = m; m->nextindex = nsln; } }
static int check_test_sweeper(eventer_t e, int mask, void *closure, struct timeval *now) { int left = 0; mtev_skiplist_node *iter = NULL; sweeper_event = NULL; iter = mtev_skiplist_getlist(&in_progress); while(iter) { struct check_test_closure *cl = iter->data; /* advance here, we might delete */ mtev_skiplist_next(&in_progress,&iter); if(NOIT_CHECK_DISABLED(cl->check)) { if(NOIT_CHECK_SHOULD_RESOLVE(cl->check)) noit_check_resolve(cl->check); if(NOIT_CHECK_RESOLVED(cl->check)) { noit_module_t *m = noit_module_lookup(cl->check->module); cl->check->flags &= ~NP_DISABLED; if(NOIT_CHECK_SHOULD_RESOLVE(cl->check)) mtevL(nldeb, "translated to %s\n", cl->check->target_ip); if(m) m->initiate_check(m, cl->check, 1, NULL); } left++; } else if(NOIT_CHECK_RUNNING(cl->check)) left++; else mtev_skiplist_remove(&in_progress, cl->restc, (mtev_freefunc_t)rest_test_check_result); } if(left) check_test_schedule_sweeper(); return 0; }
static int noit_console_show_dns_cache(mtev_console_closure_t ncct, int argc, char **argv, mtev_console_state_t *dstate, void *closure) { int i; DCLOCK(); if(argc == 0) { mtev_skiplist_node *sn; for(sn = mtev_skiplist_getlist(&nc_dns_cache); sn; mtev_skiplist_next(&nc_dns_cache, &sn)) { dns_cache_node *n = (dns_cache_node *)sn->data; nc_print_dns_cache_node(ncct, n->target, n); } } for(i=0;i<argc;i++) { dns_cache_node *n; n = mtev_skiplist_find(&nc_dns_cache, argv[i], NULL); nc_print_dns_cache_node(ncct, argv[i], n); } DCUNLOCK(); return 0; }
mtev_skiplist_node *mtev_skiplist_insert_compare(mtev_skiplist *sl, const void *data, mtev_skiplist_comparator_t comp) { mtev_skiplist_node *m, *p, *tmp, *ret = NULL, **stack; int nh=1, ch, stacki; if(!sl->top) { sl->height = 1; sl->top = sl->bottom = calloc(1, sizeof(mtev_skiplist_node)); sl->top->sl = sl; } if(sl->preheight) { while(nh < sl->preheight && get_b_rand()) nh++; } else { while(nh <= sl->height && get_b_rand()) nh++; } /* Now we have the new height at which we wish to insert our new node */ /* Let us make sure that our tree is a least that tall (grow if necessary)*/ for(;sl->height<nh;sl->height++) { sl->top->up = (mtev_skiplist_node *)calloc(1, sizeof(mtev_skiplist_node)); sl->top->up->down = sl->top; sl->top = sl->top->up; sl->top->sl = sl; } ch = sl->height; /* Find the node (or node after which we would insert) */ /* Keep a stack to pop back through for insertion */ m = sl->top; stack = (mtev_skiplist_node **)alloca(sizeof(mtev_skiplist_node *)*(nh)); stacki=0; while(m) { int compared=-1; if(m->next) compared=comp(data, m->next->data); if(compared == 0) { return 0; } if(compared<0) { if(ch<=nh) { /* push on stack */ stack[stacki++] = m; } m = m->down; ch--; } else { m = m->next; } } /* Pop the stack and insert nodes */ p = NULL; for(;stacki>0;stacki--) { m = stack[stacki-1]; tmp = calloc(1, sizeof(*tmp)); tmp->next = m->next; if(m->next) m->next->prev=tmp; tmp->prev = m; tmp->down = p; if(p) p->up=tmp; tmp->data = (void *)data; tmp->sl = sl; m->next = tmp; /* This sets ret to the bottom-most node we are inserting */ if(!p) ret=tmp; p = tmp; } if(sl->index != NULL) { /* this is a external insertion, we must insert into each index as well */ mtev_skiplist_node *p, *ni, *li; mtevAssert(ret); li=ret; for(p = mtev_skiplist_getlist(sl->index); p; mtev_skiplist_next(sl->index, &p)) { ni = mtev_skiplist_insert((mtev_skiplist *)p->data, ret->data); mtevAssert(ni); li->nextindex = ni; ni->previndex = li; li = ni; } } sl->size++; return ret; }
void noit_check_resolver_maintain() { time_t now; mtev_skiplist *tlist; mtev_skiplist_node *sn; now = time(NULL); sn = mtev_skiplist_getlist(nc_dns_cache.index); assert(sn); tlist = sn->data; assert(tlist); sn = mtev_skiplist_getlist(tlist); while(sn) { dns_cache_node *n = sn->data; mtev_skiplist_next(tlist, &sn); /* move forward */ /* remove if needed */ if(n->last_updated + n->ttl > now) break; if(n->last_needed + DEFAULT_PURGE_AGE < now && !(n->lookup_inflight_v4 || n->lookup_inflight_v6)) mtev_skiplist_remove(&nc_dns_cache, n->target, dns_cache_node_free); else { int abs; if(!dns_ptodn(n->target, strlen(n->target), n->dn, sizeof(n->dn), &abs)) { blank_update(n); } else { if(!n->lookup_inflight_v4) { n->lookup_inflight_v4 = mtev_true; if(!dns_submit_dn(dns_ctx, n->dn, DNS_C_IN, DNS_T_A, abs | dns_search_flag, NULL, dns_cache_resolve_v4, n)) blank_update_v4(n); else dns_timeouts(dns_ctx, -1, now); } if(!n->lookup_inflight_v6) { n->lookup_inflight_v6 = mtev_true; if(!dns_submit_dn(dns_ctx, n->dn, DNS_C_IN, DNS_T_AAAA, abs | dns_search_flag, NULL, dns_cache_resolve_v6, n)) blank_update_v6(n); else dns_timeouts(dns_ctx, -1, now); } } mtevL(noit_debug, "Firing lookup for '%s'\n", n->target); continue; } } /* If we have a cache implementation */ if(noit_resolver_cache_store_hook_exists()) { /* And that implementation is interested in getting a dump... */ if(noit_resolver_cache_store_hook_invoke(NULL, NULL, 0) == MTEV_HOOK_CONTINUE) { mtev_skiplist_node *sn; /* dump it all */ DCLOCK(); for(sn = mtev_skiplist_getlist(&nc_dns_cache); sn; mtev_skiplist_next(&nc_dns_cache, &sn)) { int sbuffsize; char sbuff[1024]; dns_cache_node *n = (dns_cache_node *)sn->data; sbuffsize = dns_cache_node_serialize(sbuff, sizeof(sbuff), n); if(sbuffsize > 0) noit_resolver_cache_store_hook_invoke(n->target, sbuff, sbuffsize); } DCUNLOCK(); } } }
static void log_histo(struct histogram_config *conf, noit_check_t *check, u_int64_t whence_s, const char *metric_name, histogram_t *h, mtev_boolean live_feed) { mtev_boolean extended_id = mtev_false; char uuid_str[256*3+37]; const char *v; char *hist_serial = NULL; char *hist_encode = NULL; struct timeval whence; ssize_t est, enc_est; whence.tv_sec = whence_s; whence.tv_usec = 0; if(!conf->histogram) return; SETUP_LOG(metrics, ); if(metrics_log) { v = mtev_log_stream_get_property(metrics_log, "extended_id"); if(v && !strcmp(v, "on")) extended_id = mtev_true; } uuid_str[0] = '\0'; if(extended_id) { strlcat(uuid_str, check->target, sizeof(uuid_str)-37); strlcat(uuid_str, "`", sizeof(uuid_str)-37); strlcat(uuid_str, check->module, sizeof(uuid_str)-37); strlcat(uuid_str, "`", sizeof(uuid_str)-37); strlcat(uuid_str, check->name, sizeof(uuid_str)-37); strlcat(uuid_str, "`", sizeof(uuid_str)-37); } uuid_unparse_lower(check->checkid, uuid_str + strlen(uuid_str)); #define SECPART(a) ((unsigned long)(a)->tv_sec) #define MSECPART(a) ((unsigned long)((a)->tv_usec / 1000)) est = hist_serialize_estimate(h); hist_serial = malloc(est); if(!hist_serial) { mtevL(noit_error, "malloc(%d) failed\n", (int)est); goto cleanup; } enc_est = ((est + 2)/3)*4; hist_encode = malloc(enc_est); if(!hist_encode) { mtevL(noit_error, "malloc(%d) failed\n", (int)enc_est); goto cleanup; } if(hist_serialize(h, hist_serial, est) != est) { mtevL(noit_error, "histogram serialization failure\n"); goto cleanup; } enc_est = mtev_b64_encode((unsigned char *)hist_serial, est, hist_encode, enc_est); if(enc_est < 0) { mtevL(noit_error, "base64 histogram encoding failure\n"); goto cleanup; } if(live_feed && check->feeds) { mtev_skiplist_node *curr, *next; curr = next = mtev_skiplist_getlist(check->feeds); while(curr) { const char *feed_name = (char *)curr->data; mtev_log_stream_t ls = mtev_log_stream_find(feed_name); mtev_skiplist_next(check->feeds, &next); if(!ls || mtev_log(ls, &whence, __FILE__, __LINE__, "H1\t%lu.%03lu\t%s\t%s\t%.*s\n", SECPART(&whence), MSECPART(&whence), uuid_str, metric_name, (int)enc_est, hist_encode)) noit_check_transient_remove_feed(check, feed_name); curr = next; } } if(!live_feed) { SETUP_LOG(metrics, goto cleanup); mtev_log(metrics_log, &whence, __FILE__, __LINE__, "H1\t%lu.%03lu\t%s\t%s\t%.*s\n", SECPART(&whence), MSECPART(&whence), uuid_str, metric_name, (int)enc_est, hist_encode); }