static eventer_t eventer_kqueue_impl_remove(eventer_t e) { eventer_t removed = NULL; if(e->mask & EVENTER_ASYNCH) { abort(); } if(e->mask & (EVENTER_READ | EVENTER_WRITE | EVENTER_EXCEPTION)) { ev_lock_state_t lockstate; lockstate = acquire_master_fd(e->fd); noitL(eventer_deb, "kqueue: remove(%d)\n", e->fd); if(e == master_fds[e->fd].e) { removed = e; master_fds[e->fd].e = NULL; if(e->mask & (EVENTER_READ | EVENTER_EXCEPTION)) ke_change(e->fd, EVFILT_READ, EV_DELETE | EV_DISABLE, e); if(e->mask & (EVENTER_WRITE)) ke_change(e->fd, EVFILT_WRITE, EV_DELETE | EV_DISABLE, e); } else noitL(eventer_deb, "kqueue: remove(%d) failed.\n", e->fd); release_master_fd(e->fd, lockstate); } else if(e->mask & EVENTER_TIMER) { removed = eventer_remove_timed(e); } else if(e->mask & EVENTER_RECURRENT) { removed = eventer_remove_recurrent(e); } else { abort(); } return removed; }
static void postgres_ingest_stats(postgres_check_info_t *ci) { if(ci->rv == PGRES_TUPLES_OK) { /* metrics */ int nrows, ncols, i, j; nrows = PQntuples(ci->result); ncols = PQnfields(ci->result); noit_stats_set_metric(&ci->current, "row_count", METRIC_INT32, &nrows); for (i=0; i<nrows; i++) { noitL(nldeb, "postgres: row %d [%d cols]:\n", i, ncols); if(ncols<2) continue; if(PQgetisnull(ci->result, i, 0)) continue; for (j=1; j<ncols; j++) { Oid coltype; int iv, *piv; int64_t lv, *plv; double dv, *pdv; char *sv; char mname[128]; snprintf(mname, sizeof(mname), "%s`%s", PQgetvalue(ci->result, i, 0), PQfname(ci->result, j)); coltype = PQftype(ci->result, j); noitL(nldeb, "postgres: col %d (%s) type %d:\n", j, mname, coltype); switch(coltype) { case BOOLOID: if(PQgetisnull(ci->result, i, j)) piv = NULL; else { iv = strcmp(PQgetvalue(ci->result, i, j), "f") ? 1 : 0; piv = &iv; } noit_stats_set_metric(&ci->current, mname, METRIC_INT32, piv); break; case INT2OID: case INT4OID: case INT8OID: if(PQgetisnull(ci->result, i, j)) plv = NULL; else { lv = strtoll(PQgetvalue(ci->result, i, j), NULL, 10); plv = &lv; } noit_stats_set_metric(&ci->current, mname, METRIC_INT64, plv); case FLOAT4OID: case FLOAT8OID: case NUMERICOID: if(PQgetisnull(ci->result, i, j)) pdv = NULL; else { dv = atof(PQgetvalue(ci->result, i, j)); pdv = &dv; } noit_stats_set_metric(&ci->current, mname, METRIC_DOUBLE, pdv); default: if(PQgetisnull(ci->result, i, j)) sv = NULL; else sv = PQgetvalue(ci->result, i, j); noit_stats_set_metric(&ci->current, mname, METRIC_GUESS, sv); break; } } } } }
static void stratcon_datastore_journal(struct sockaddr *remote, const char *remote_cn, char *line) { interim_journal_t *ij = NULL; char uuid_str[UUID_STR_LEN+1], *cp1, *cp2; char rtype[256]; const char *fqdn = NULL, *dsn = NULL; int storagenode_id = 0; uuid_t checkid; if(!line) { noitL(noit_error, "Error: Line not found for %s in stratcon_datastore_journal\n", remote_cn); return; } cp1 = strchr(line, '\t'); *rtype = '\0'; if(cp1 && cp1 - line < sizeof(rtype) - 1) { memcpy(rtype, line, cp1 - line); rtype[cp1 - line] = '\0'; } /* if it is a UUID based thing, find the storage node */ switch(*rtype) { case 'C': case 'S': case 'M': case 'D': case 'B': case 'H': if((cp1 = strchr(cp1+1, '\t')) != NULL && (cp2 = strchr(cp1+1, '\t')) != NULL && (cp2-cp1 >= UUID_STR_LEN)) { strlcpy(uuid_str, cp2 - UUID_STR_LEN, sizeof(uuid_str)); if(!uuid_parse(uuid_str, checkid)) { ingestor->storage_node_lookup(uuid_str, remote_cn, NULL, &storagenode_id, NULL, &fqdn, &dsn); ij = interim_journal_get(remote, remote_cn, storagenode_id, fqdn); } } break; case 'n': ij = interim_journal_get(remote,remote_cn,0,NULL); break; default: noitL(noit_error, "Error: Line has bad type for %s in stratcon_datastore_journal (%s)\n", remote_cn, line); break; } if(!ij) { noitL(ingest_err, "%d\t%s\n", storagenode_id, line); } else { int len; len = write(ij->fd, line, strlen(line)); if(len < 0) { noitL(noit_error, "write to %s failed: %s\n", ij->filename, strerror(errno)); } } free(line); return; }
static int dns_module_init(noit_module_t *self) { const struct dns_nameval *nv; struct dns_ctx *pctx; int i; pthread_mutex_init(&dns_ctx_store_lock, NULL); pthread_mutex_init(&active_events_lock, NULL); /* HASH the rr types */ for(i=0, nv = dns_type_index(i); nv->name; nv = dns_type_index(++i)) noit_hash_store(&dns_rtypes, nv->name, strlen(nv->name), (void *)nv); /* HASH the class types */ for(i=0, nv = dns_class_index(i); nv->name; nv = dns_class_index(++i)) noit_hash_store(&dns_ctypes, nv->name, strlen(nv->name), (void *)nv); noit_check_interpolate_register_oper_fn("inaddrarpa", dns_interpolate_inaddr_arpa); noit_check_interpolate_register_oper_fn("reverseip", dns_interpolate_reverse_ip); if (dns_init(NULL, 0) < 0 || (pctx = dns_new(NULL)) == NULL) { noitL(nlerr, "Unable to initialize dns subsystem\n"); return -1; } dns_free(pctx); if(dns_ctx_alloc(NULL, 0) == NULL) { noitL(nlerr, "Error setting up default dns resolver context.\n"); return -1; } return 0; }
static int noit_check_recur_handler(eventer_t e, int mask, void *closure, struct timeval *now) { recur_closure_t *rcl = closure; int ms; rcl->check->fire_event = NULL; /* This is us, we get free post-return */ noit_check_resolve(rcl->check); ms = noit_check_schedule_next(rcl->self, NULL, rcl->check, now, rcl->dispatch, NULL); if(NOIT_CHECK_RESOLVED(rcl->check)) { if(NOIT_HOOK_CONTINUE == check_preflight_hook_invoke(rcl->self, rcl->check, rcl->cause)) { if(NOIT_CHECK_DISPATCH_ENABLED()) { char id[UUID_STR_LEN+1]; uuid_unparse_lower(rcl->check->checkid, id); NOIT_CHECK_DISPATCH(id, rcl->check->module, rcl->check->name, rcl->check->target); } if(ms < rcl->check->timeout && !(rcl->check->flags & NP_TRANSIENT)) noitL(noit_error, "%s might not finish in %dms (timeout %dms)\n", rcl->check->name, ms, rcl->check->timeout); rcl->dispatch(rcl->self, rcl->check, rcl->cause); } check_postflight_hook_invoke(rcl->self, rcl->check, rcl->cause); } else noitL(noit_debug, "skipping %s`%s`%s, unresolved\n", rcl->check->target, rcl->check->module, rcl->check->name); free(rcl); return 0; }
static void stratcon_ingestor_submit_lookup(struct realtime_tracker *rt, eventer_t completion) { struct realtime_tracker *node; for(node = rt; node; node = node->next) { char uuid_str[UUID_STR_LEN+1]; const char *fqdn, *dsn, *remote_cn; char remote_ip[32]; int storagenode_id; uuid_unparse_lower(node->checkid, uuid_str); if(storage_node_quick_lookup(uuid_str, NULL, &node->sid, &storagenode_id, &remote_cn, &fqdn, &dsn)) continue; noitL(noit_debug, "stratcon_ingest_find <- (%d, %s) @ %s\n", node->sid, remote_cn ? remote_cn : "(null)", dsn ? dsn : "(null)"); if(stratcon_find_noit_ip_by_cn(remote_cn, remote_ip, sizeof(remote_ip)) == 0) { node->noit = strdup(remote_ip); noitL(noit_debug, "lookup(cache): %s -> %s\n", remote_cn, node->noit); continue; } } eventer_add(completion); }
static void eventer_ports_impl_add(eventer_t e) { assert(e->mask); ev_lock_state_t lockstate; const char *cbname; cbname = eventer_name_for_callback(e->callback); if(e->mask & EVENTER_ASYNCH) { noitL(eventer_deb, "debug: eventer_add asynch (%s)\n", cbname ? cbname : "???"); eventer_add_asynch(NULL, e); return; } /* Recurrent delegation */ if(e->mask & EVENTER_RECURRENT) { noitL(eventer_deb, "debug: eventer_add recurrent (%s)\n", cbname ? cbname : "???"); eventer_add_recurrent(e); return; } /* Timed events are simple */ if(e->mask & EVENTER_TIMER) { eventer_add_timed(e); return; } /* file descriptor event */ noitL(eventer_deb, "debug: eventer_add fd (%s,%d,0x%04x)\n", cbname ? cbname : "???", e->fd, e->mask); lockstate = acquire_master_fd(e->fd); assert(e->whence.tv_sec == 0 && e->whence.tv_usec == 0); master_fds[e->fd].e = e; alter_fd(e, e->mask); release_master_fd(e->fd, lockstate); }
static int stratcon_ingest_launch_file_ingestion(const char *path, const char *remote_str, const char *remote_cn, const char *id_str) { char msg[PATH_MAX + 7], hfile[PATH_MAX]; /*file:\r\n*/ if(strcmp(path + strlen(path) - 2, ".h")) { snprintf(hfile, sizeof(hfile), "%s.h", path); if(link(path, hfile) < 0 && errno != EEXIST) { noitL(noit_error, "cannot link journal %s: %s\n", path, strerror(errno)); return -1; } } else strlcpy(hfile, path, sizeof(hfile)); noitL(noit_debug, " handoff -> %s\n", hfile); pthread_mutex_lock(&http_ctx_lock); if(the_one_and_only) { noit_http_session_ctx *ctx = the_one_and_only; snprintf(msg, sizeof(msg), "file:%s\r\n", hfile); if(noit_http_response_append(ctx,msg,strlen(msg)) == noit_false || noit_http_response_flush(ctx, noit_false) == noit_false) { noitL(noit_error, "handoff endpoint disconnected\n"); the_one_and_only = NULL; } } pthread_mutex_unlock(&http_ctx_lock); return 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); }
static void * asynch_logio_writer(void *vls) { noit_log_stream_t ls = vls; asynch_log_ctx *actx = ls->op_ctx; asynch_log_line *iter = NULL; int gen; gen = noit_atomic_inc32(&actx->gen); noitL(noit_debug, "starting asynchronous %s writer[%d/%p]\n", actx->name, (int)getpid(), (void *)(vpsized_int)pthread_self()); while(gen == actx->gen) { pthread_rwlock_t *lock; int fast = 0, max = 1000; asynch_log_line *line; lock = ls->lock; if(lock) pthread_rwlock_rdlock(lock); while(max > 0 && NULL != (line = asynch_log_pop(actx, &iter))) { if(actx->write(actx, line) == -1) abort(); if(line->buf_dynamic != NULL) free(line->buf_dynamic); free(line); fast = 1; max--; } if(lock) pthread_rwlock_unlock(lock); if(max > 0) { /* we didn't hit our limit... so we ran the queue dry */ /* 200ms if there was nothing, 10ms otherwise */ usleep(fast ? 10000 : 200000); } } noitL(noit_debug, "stopping asynchronous %s writer[%d/%p]\n", actx->name, (int)getpid(), (void *)(vpsized_int)pthread_self()); pthread_exit((void *)0); }
static int ping_icmp_init(noit_module_t *self) { socklen_t on; struct protoent *proto; ping_icmp_data_t *data; data = malloc(sizeof(*data)); data->in_flight = calloc(1, sizeof(*data->in_flight)); data->ipv4_fd = data->ipv6_fd = -1; if ((proto = getprotobyname("icmp")) == NULL) { noitL(noit_error, "Couldn't find 'icmp' protocol\n"); return -1; } data->ipv4_fd = socket(AF_INET, SOCK_RAW, proto->p_proto); if(data->ipv4_fd < 0) { noitL(noit_error, "ping_icmp: socket failed: %s\n", strerror(errno)); } else { socklen_t slen = sizeof(on); if(getsockopt(data->ipv4_fd, SOL_SOCKET, SO_SNDBUF, &on, &slen) == 0) { while(on < (1 << 20)) { on <<= 1; if(setsockopt(data->ipv4_fd, SOL_SOCKET, SO_SNDBUF, &on, sizeof(on)) != 0) { on >>= 1; break; } } noitL(noit_debug, "ping_icmp: send buffer set to %d\n", on); } else
static int noit_stomp_submit(iep_thread_driver_t *dr, const char *payload, size_t payloadlen) { struct stomp_driver *driver = (struct stomp_driver *)dr; apr_pool_t *dummy; apr_status_t rc; stomp_frame out; if(apr_pool_create(&dummy, NULL) != APR_SUCCESS) return -1; out.command = "SEND"; out.headers = apr_hash_make(dummy); if (driver->exchange) apr_hash_set(out.headers, "exchange", APR_HASH_KEY_STRING, driver->exchange); apr_hash_set(out.headers, "destination", APR_HASH_KEY_STRING, driver->destination); apr_hash_set(out.headers, "ack", APR_HASH_KEY_STRING, "auto"); out.body_length = -1; out.body = (char *)payload; rc = stomp_write(driver->connection, &out, dummy); if(rc != APR_SUCCESS) { noitL(noit_error, "STOMP send failed, disconnecting\n"); if(driver->connection) stomp_disconnect(&driver->connection); driver->connection = NULL; } else noitL(noit_debug, "STOMP send succeeded\n"); apr_pool_destroy(dummy); return (rc == APR_SUCCESS) ? 0 : -1; }
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; }
int noit_control_dispatch(eventer_t e, int mask, void *closure, struct timeval *now) { u_int32_t cmd; int len = 0, callmask = mask; void *vdelegation_table; noit_hash_table *delegation_table = NULL; acceptor_closure_t *ac = closure; assert(ac->rlen >= 0); while(len >= 0 && ac->rlen < sizeof(cmd)) { len = e->opset->read(e->fd, ((char *)&cmd) + ac->rlen, sizeof(cmd) - ac->rlen, &mask, e); if(len == -1 && errno == EAGAIN) return EVENTER_READ | EVENTER_EXCEPTION; if(len > 0) ac->rlen += len; } assert(ac->rlen >= 0 && ac->rlen <= sizeof(cmd)); if(callmask & EVENTER_EXCEPTION || ac->rlen != sizeof(cmd)) { int newmask; socket_error: /* Exceptions cause us to simply snip the connection */ eventer_remove_fd(e->fd); e->opset->close(e->fd, &newmask, e); acceptor_closure_free(ac); return 0; } ac->cmd = ntohl(cmd); /* Lookup cmd and dispatch */ if(noit_hash_retrieve(&listener_commands, (char *)&ac->dispatch, sizeof(ac->dispatch), (void **)&vdelegation_table)) { void *vfunc; delegation_table = (noit_hash_table *)vdelegation_table; if(noit_hash_retrieve(delegation_table, (char *)&ac->cmd, sizeof(ac->cmd), &vfunc)) { e->callback = *((eventer_func_t *)vfunc); return e->callback(e, callmask, closure, now); } else { const char *event_name; noitL(noit_error, "listener (%s %p) has no command: 0x%08x\n", (event_name = eventer_name_for_callback(ac->dispatch))?event_name:"???", delegation_table, cmd); } } else { const char *event_name; noitL(noit_error, "No delegation table for listener (%s %p)\n", (event_name = eventer_name_for_callback(ac->dispatch))?event_name:"???", delegation_table); } goto socket_error; }
static int ip_acl_onload(noit_image_t *self) { int i, cnt; noit_conf_section_t *acl_c; ip_acl_module_id = noit_check_register_module("ip_acl"); if(ip_acl_module_id < 0) return -1; acl_c = noit_conf_get_sections(NULL, "/noit/acls//acl", &cnt); if(acl_c) { for(i=0; i<cnt; i++) { char *name; int j, rcnt, arcnt = 0; noit_conf_section_t *rule_c; if(noit_conf_get_string(acl_c[i], "@name", &name)) { rule_c = noit_conf_get_sections(acl_c[i], "rule", &rcnt); if(rule_c) { btrie *acl = calloc(1, sizeof(*acl)); for(j=0; j<rcnt; j++) { int mask = -1, rv; char dirstr[16] = "unspecified"; char *cp, target[256] = ""; union { struct in_addr addr4; struct in6_addr addr6; } a; noit_conf_get_stringbuf(rule_c[j], "self::node()", target, sizeof(target)); if(NULL != (cp = strchr(target, '/'))) { *cp++ = '\0'; mask = atoi(cp); } if(!noit_conf_get_stringbuf(rule_c[j], "@type", dirstr, sizeof(dirstr)) || (strcmp(dirstr, "deny") && strcmp(dirstr, "allow"))) { noitL(noit_error, "Unknown acl rule type \"%s\" in acl \"%s\"\n", dirstr, name); } else if(inet_pton(AF_INET, target, &a) == 1) { if(mask == -1) mask = 32; noit_add_route_ipv4(acl, &a.addr4, mask, strcmp(dirstr, "allow") ? DENY_PTR : ALLOW_PTR); arcnt++; } else if(inet_pton(AF_INET6, target, &a) == 1) { if(mask == -1) mask = 128; noit_add_route_ipv6(acl, &a.addr6, mask, strcmp(dirstr, "allow") ? DENY_PTR : ALLOW_PTR); arcnt++; } } noitL(noit_error, "ACL %s/%p -> %d/%d rules\n", name, acl, arcnt, rcnt); noit_hash_replace(&acls, name, strlen(name), acl, free, free_btrie); free(rule_c); } } } free(acl_c); } return 0; }
void noit_poller_make_causal_map() { noit_hash_iter iter = NOIT_HASH_ITER_ZERO; uuid_t key_id; int klen; void *vcheck; /* Cleanup any previous causal map */ while(noit_hash_next(&polls, &iter, (const char **)key_id, &klen, &vcheck)) { noit_check_t *check = (noit_check_t *)vcheck; dep_list_t *dep; while((dep = check->causal_checks) != NULL) { check->causal_checks = dep->next; free(dep); } } memset(&iter, 0, sizeof(iter)); /* Walk all checks and add check dependencies to their parents */ while(noit_hash_next(&polls, &iter, (const char **)key_id, &klen, &vcheck)) { noit_check_t *check = (noit_check_t *)vcheck, *parent; if(check->oncheck) { /* This service is causally triggered by another service */ char fullcheck[1024]; char *name = check->oncheck; char *target = NULL; noitL(noit_debug, "Searching for upstream trigger on %s\n", name); if((target = strchr(check->oncheck, '`')) != NULL) { strlcpy(fullcheck, check->oncheck, target - check->oncheck); name = target + 1; target = fullcheck; } else target = check->target; parent = noit_poller_lookup_by_name(target, name); if(!parent) { check->flags |= NP_DISABLED; noitL(noit_stderr, "Disabling check %s`%s, can't find oncheck %s`%s\n", check->target, check->name, target, name); } else { dep_list_t *dep; dep = malloc(sizeof(*dep)); dep->check = check; dep->next = parent->causal_checks; parent->causal_checks = dep; noitL(noit_debug, "Causal map %s`%s --> %s`%s\n", parent->target, parent->name, check->target, check->name); } } } }
static int statsd_handler(eventer_t e, int mask, void *closure, struct timeval *now) { noit_module_t *self = (noit_module_t *)closure; int packets_per_cycle; statsd_mod_config_t *conf; noit_check_t *parent = NULL; conf = noit_module_get_userdata(self); if(conf->primary_active) parent = noit_poller_lookup(conf->primary); packets_per_cycle = MAX(conf->packets_per_cycle, 1); for( ; packets_per_cycle > 0; packets_per_cycle--) { noit_check_t *checks[MAX_CHECKS]; int nchecks = 0; char ip[INET6_ADDRSTRLEN]; union { struct sockaddr_in in; struct sockaddr_in6 in6; } addr; socklen_t addrlen = sizeof(addr); ssize_t len; uuid_t check_id; len = recvfrom(e->fd, conf->payload, conf->payload_len-1, 0, (struct sockaddr *)&addr, &addrlen); if(len < 0) { if(errno != EAGAIN) noitL(nlerr, "statsd: recvfrom() -> %s\n", strerror(errno)); break; } switch(addr.in.sin_family) { case AF_INET: addrlen = sizeof(struct sockaddr_in); inet_ntop(AF_INET, &((struct sockaddr_in *)&addr)->sin_addr, ip, addrlen); break; case AF_INET6: addrlen = sizeof(struct sockaddr_in6); inet_ntop(AF_INET6, &((struct sockaddr_in6 *)&addr)->sin6_addr, ip, addrlen); break; default: ip[0] = '\0'; } conf->payload[len] = '\0'; nchecks = 0; if(*ip) nchecks = noit_poller_lookup_by_ip_module(ip, self->hdr.name, checks, MAX_CHECKS-1); noitL(nldeb, "statsd(%d bytes) from '%s' -> %d checks%s\n", (int)len, ip, (int)nchecks, parent ? " + a parent" : ""); if(parent) checks[nchecks++] = parent; if(nchecks) statsd_handle_payload(checks, nchecks, conf->payload, len); } return EVENTER_READ | EVENTER_EXCEPTION; }
static int noit_lua_module_onload(noit_image_t *i) { int rv; lua_State *L; lua_module_closure_t *lmc; noit_lua_init(); lmc = noit_image_get_userdata(i); L = lmc->lua_state; lua_getglobal(L, "require"); lua_pushstring(L, lmc->object); rv = lua_pcall(L, 1, 1, 0); if(rv) { int i; noitL(nlerr, "lua: %s.onload failed\n", lmc->object); i = lua_gettop(L); if(i>0) { if(lua_isstring(L, i)) { const char *err; size_t len; err = lua_tolstring(L, i, &len); noitL(nlerr, "lua: %s\n", err); } } lua_pop(L,i); return -1; } lua_pop(L, lua_gettop(L)); noit_lua_pushmodule(L, lmc->object); if(lua_isnil(L, -1)) { lua_pop(L, 1); noitL(nlerr, "lua: no such object %s\n", lmc->object); return -1; } lua_getfield(L, -1, "onload"); lua_remove(L, -2); if(!lua_isfunction(L, -1)) { lua_pop(L, 1); /* No onload */ return 0; } noit_lua_setup_module(L, (noit_module_t *)i); lua_pcall(L, 1, 1, 0); if(lua_isnumber(L, -1)) { int rv; rv = lua_tointeger(L, -1); lua_pop(L, 1); return rv; } lua_pop(L,1); noitL(nlerr, "%s.onload must return a integer\n", lmc->object); return -1; }
static int noitice_hup(eventer_t e, int mask, void *unused, struct timeval *now) { if(__reload_needed) { noitL(noit_error, "SIGHUP received, performing reload\n"); if(noit_conf_load(config_file) == -1) { noitL(noit_error, "Cannot load config: '%s'\n", config_file); exit(-1); } noit_poller_reload(NULL); __reload_needed = 0; } return 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); } }
void * noit_livestream_thread_main(void *e_vptr) { int mask; eventer_t e = e_vptr; acceptor_closure_t *ac = e->closure; noit_livestream_closure_t *jcl = ac->service_ctx; /* Go into blocking mode */ if(eventer_set_fd_blocking(e->fd) == -1) { noitL(noit_error, "failed setting livestream to blocking: [%d] [%s]\n", errno, strerror(errno)); goto alldone; } while(1) { u_int32_t netlen; struct log_entry *le = NULL; int rv; sem_wait(&jcl->lqueue_sem); pthread_mutex_lock(&jcl->lqueue_lock); if(jcl->lqueue) { /* If there are items, pop and advance the header pointer */ le = jcl->lqueue; jcl->lqueue = jcl->lqueue->next; if(!jcl->lqueue) jcl->lqueue_end = NULL; } pthread_mutex_unlock(&jcl->lqueue_lock); if(!le) continue; /* Here we actually push the message */ netlen = htonl(le->len); if((rv = Ewrite(&netlen, sizeof(netlen))) != sizeof(netlen)) { noitL(noit_error, "Error writing le header over SSL %d != %d\n", rv, (int)sizeof(netlen)); goto alldone; } if((rv = Ewrite(le->buff, le->len)) != le->len) { noitL(noit_error, "Error writing livestream message over SSL %d != %d\n", rv, le->len); goto alldone; } } alldone: e->opset->close(e->fd, &mask, e); jcl->wants_shutdown = 1; if(ac) acceptor_closure_free(ac); return NULL; }
static int noit_rabbimq_connect(iep_thread_driver_t *dr) { struct amqp_driver *driver = (struct amqp_driver *)dr; if(!driver->connection) { int sidx = driver->nconnects++ % driver->nhosts; struct timeval timeout; amqp_rpc_reply_t r, *rptr; noitL(noit_error, "AMQP connect: %s:%d\n", driver->hostname[sidx], driver->port); BUMPSTAT(connects); driver->hostidx = sidx; timeout.tv_sec = driver->heartbeat; timeout.tv_usec = 0; driver->sockfd = amqp_open_socket(driver->hostname[sidx], driver->port, &timeout); if(driver->sockfd < 0) { noitL(noit_error, "AMQP connect failed: %s:%d\n", driver->hostname[sidx], driver->port); return -1; } driver->has_error = 0; driver->connection = amqp_new_connection(); amqp_set_basic_return_cb(driver->connection, noit_rabbitmq_brcb, driver); amqp_set_sockfd(driver->connection, driver->sockfd); r = amqp_login(driver->connection, driver->vhost, 0, 131072, driver->heartbeat, AMQP_SASL_METHOD_PLAIN, driver->username, driver->password); if(r.reply_type != AMQP_RESPONSE_NORMAL) { noitL(noit_error, "AMQP login failed\n"); amqp_connection_close(driver->connection, AMQP_REPLY_SUCCESS); amqp_destroy_connection(driver->connection); driver->connection = NULL; return -1; } amqp_channel_open(driver->connection, 1); rptr = amqp_get_rpc_reply(); if(rptr->reply_type != AMQP_RESPONSE_NORMAL) { noitL(noit_error, "AMQP channe_open failed\n"); amqp_connection_close(driver->connection, AMQP_REPLY_SUCCESS); amqp_destroy_connection(driver->connection); driver->connection = NULL; return -1; } gettimeofday(&driver->last_hb, NULL); return 0; } /* 1 means already connected */ return 1; }
static int dns_module_init(noit_module_t *self) { const struct dns_nameval *nv; struct dns_ctx *pctx; int i; const char *config_val; dns_mod_config_t *conf; conf = noit_module_get_userdata(self); pthread_mutex_init(&dns_ctx_store_lock, NULL); pthread_mutex_init(&active_events_lock, NULL); conf->contexts = DEFAULT_MAX_CONTEXTS; if(noit_hash_retr_str(conf->options, "contexts", strlen("contexts"), (const char**)&config_val)) { conf->contexts = atoi(config_val); if (conf->contexts <= 0) conf->contexts = DEFAULT_MAX_CONTEXTS; } /* HASH the rr types */ for(i=0, nv = dns_type_index(i); nv->name; nv = dns_type_index(++i)) noit_hash_store(&dns_rtypes, nv->name, strlen(nv->name), (void *)nv); /* HASH the class types */ for(i=0, nv = dns_class_index(i); nv->name; nv = dns_class_index(++i)) noit_hash_store(&dns_ctypes, nv->name, strlen(nv->name), (void *)nv); noit_check_interpolate_register_oper_fn("inaddrarpa", dns_interpolate_inaddr_arpa); noit_check_interpolate_register_oper_fn("reverseip", dns_interpolate_reverse_ip); if (dns_init(NULL, 0) < 0 || (pctx = dns_new(NULL)) == NULL) { noitL(nlerr, "Unable to initialize dns subsystem\n"); return -1; } dns_free(pctx); if(dns_module_dns_ctx_alloc(self, NULL, 0) == NULL) { noitL(nlerr, "Error setting up default dns resolver context.\n"); return -1; } register_console_dns_commands(); return 0; }
static void eventer_kqueue_impl_update(eventer_t e, int mask) { if(e->mask & EVENTER_TIMER) { eventer_update_timed(e, mask); return; } noitL(eventer_deb, "kqueue: update(%d, %x->%x)\n", e->fd, e->mask, mask); /* Disable old, if they aren't active in the new */ if((e->mask & (EVENTER_READ | EVENTER_EXCEPTION)) && !(mask & (EVENTER_READ | EVENTER_EXCEPTION))) ke_change(e->fd, EVFILT_READ, EV_DELETE | EV_DISABLE, e); if((e->mask & (EVENTER_WRITE)) && !(mask & (EVENTER_WRITE))) ke_change(e->fd, EVFILT_WRITE, EV_DELETE | EV_DISABLE, e); /* Enable new, if the weren't in the old */ if((mask & (EVENTER_READ | EVENTER_EXCEPTION)) && !(e->mask & (EVENTER_READ | EVENTER_EXCEPTION))) ke_change(e->fd, EVFILT_READ, EV_ADD | EV_ENABLE, e); if((mask & (EVENTER_WRITE)) && !(e->mask & (EVENTER_WRITE))) ke_change(e->fd, EVFILT_WRITE, EV_ADD | EV_ENABLE, e); /* Switch */ e->mask = mask; }
static int check_test_sweeper(eventer_t e, int mask, void *closure, struct timeval *now) { int left = 0; noit_skiplist_node *iter = NULL; sweeper_event = NULL; iter = noit_skiplist_getlist(&in_progress); while(iter) { struct check_test_closure *cl = iter->data; /* advance here, we might delete */ noit_skiplist_next(&in_progress,&iter); if(NOIT_CHECK_DISABLED(cl->check)) { if(NOIT_CHECK_SHOULD_RESOLVE(cl->check)) noit_check_resolve(cl->check); if(NOIT_CHECK_RESOLVED(cl->check)) { noit_module_t *m = noit_module_lookup(cl->check->module); cl->check->flags &= ~NP_DISABLED; if(NOIT_CHECK_SHOULD_RESOLVE(cl->check)) noitL(nldeb, "translated to %s\n", cl->check->target_ip); if(m) m->initiate_check(m, cl->check, 1, NULL); } left++; } else if(NOIT_CHECK_RUNNING(cl->check)) left++; else noit_skiplist_remove(&in_progress, cl->restc, (noit_freefunc_t)rest_test_check_result); } if(left) check_test_schedule_sweeper(); return 0; }
static int lua_general_resume(noit_lua_resume_info_t *ri, int nargs) { const char *err = NULL; int status, base, rv = 0; #if LUA_VERSION_NUM >= 502 status = lua_resume(ri->coro_state, ri->lmc->lua_state, nargs); #else status = lua_resume(ri->coro_state, nargs); #endif switch(status) { case 0: break; case LUA_YIELD: lua_gc(ri->coro_state, LUA_GCCOLLECT, 0); return 0; default: /* The complicated case */ base = lua_gettop(ri->coro_state); if(base>=0) { if(lua_isstring(ri->coro_state, base-1)) { err = lua_tostring(ri->coro_state, base-1); noitL(nlerr, "err -> %s\n", err); } } rv = -1; } lua_general_ctx_free(ri); return rv; }
static int rest_stream_data(noit_http_rest_closure_t *restc, int npats, char **pats) { /* We're here and want to subvert the rest system */ const char *document_domain = NULL; noit_http_session_ctx *ctx = restc->http_ctx; noit_http_connection *conn = noit_http_session_connection(ctx); eventer_t e; acceptor_closure_t *ac = restc->ac; /* Rewire the handler */ if(ac->service_ctx_free) ac->service_ctx_free(ac->service_ctx); ac->service_ctx = ctx; ac->service_ctx_free = noit_http_ctx_acceptor_free; if(!noit_hash_retr_str(ac->config, "document_domain", strlen("document_domain"), &document_domain)) { noitL(noit_error, "Document domain not set! Realtime streaming will be broken\n"); document_domain = ""; } noit_http_process_querystring(noit_http_session_request(ctx)); /* Rewire the http context */ e = noit_http_connection_event(conn); e->callback = stratcon_realtime_http_handler; noit_http_session_set_dispatcher(ctx, stratcon_request_dispatcher, alloc_realtime_context(document_domain)); return stratcon_request_dispatcher(ctx); }
static void ke_change (register int const ident, register int const filter, register int const flags, register eventer_t e) { register struct kevent *kep; KQUEUE_DECL; KQUEUE_SETUP; if(!kqs) kqs = master_kqs; if(kqs == master_kqs) pthread_mutex_lock(&kqs_lock); if (!ke_vec_a) { kqs_init(kqs); } else if (ke_vec_used == ke_vec_a) { ke_vec_a <<= 1; ke_vec = (struct kevent *) realloc(ke_vec, ke_vec_a * sizeof (struct kevent)); } kep = &ke_vec[ke_vec_used++]; EV_SET(kep, ident, filter, flags, 0, 0, (void *)(vpsized_int)e->fd); noitL(eventer_deb, "debug: ke_change(fd:%d, filt:%x, flags:%x)\n", ident, filter, flags); if(kqs == master_kqs) pthread_mutex_unlock(&kqs_lock); }
static void stratcon_ingest_sweep_journals_int(char *first, char *second, char *third, int (*test)(const char *), int (*ingest)(const char *fullpath, const char *remote_str, const char *remote_cn, const char *id_str)) { char path[PATH_MAX]; DIR *root; struct dirent *de, *entry; int i = 0, cnt = 0; char **entries; int size = 0; snprintf(path, sizeof(path), "%s%s%s%s%s%s%s", basejpath, first ? "/" : "", first ? first : "", second ? "/" : "", second ? second : "", third ? "/" : "", third ? third : ""); #ifdef _PC_NAME_MAX size = pathconf(path, _PC_NAME_MAX); #endif size = MAX(size, PATH_MAX + 128); de = alloca(size); root = opendir(path); if(!root) return; while(portable_readdir_r(root, de, &entry) == 0 && entry != NULL) cnt++; closedir(root); root = opendir(path); if(!root) return; entries = malloc(sizeof(*entries) * cnt); while(portable_readdir_r(root, de, &entry) == 0 && entry != NULL) { if(i < cnt) { entries[i++] = strdup(entry->d_name); } } closedir(root); cnt = i; /* could have changed, directories are fickle */ qsort(entries, i, sizeof(*entries), (int (*)(const void *, const void *))strcasecmp); for(i=0; i<cnt; i++) { if(!strcmp(entries[i], ".") || !strcmp(entries[i], "..")) continue; noitL(ds_deb, "Processing L%d entry '%s'\n", third ? 4 : second ? 3 : first ? 2 : 1, entries[i]); if(!first) stratcon_ingest_sweep_journals_int(entries[i], NULL, NULL, test, ingest); else if(!second) stratcon_ingest_sweep_journals_int(first, entries[i], NULL, test, ingest); else if(!third) stratcon_ingest_sweep_journals_int(first, second, entries[i], test, ingest); else if(test(entries[i])) { char fullpath[PATH_MAX]; snprintf(fullpath, sizeof(fullpath), "%s/%s/%s/%s/%s", basejpath, first,second,third,entries[i]); ingest(fullpath,first,second,third); } } for(i=0; i<cnt; i++) free(entries[i]); free(entries); }
int allocate_pty(int *master, int *slave) { #if defined(HAVE_OPENPTY) || (defined(HAVE_DECL_OPENPTY) && HAVE_DECL_OPENPTY != 0) if(openpty(master, slave, NULL, NULL, NULL)) return -1; #else /* STREAMS... sigh */ char *slavename; extern char *ptsname(); *master = open("/dev/ptmx", O_RDWR); /* open master */ if(*master < 0) return -1; grantpt(*master); /* change permission of slave */ unlockpt(*master); /* unlock slave */ slavename = ptsname(*master); /* get name of slave */ *slave = open(slavename, O_RDWR); /* open slave */ if(*slave < 0) { close(*master); *master = -1; return -1; } /* This is a bit backwards as we using the PTY backwards. * We want to make the master a tty instead of the slave... odd, I know. */ ioctl(*master, I_PUSH, "ptem"); /* push ptem */ ioctl(*master, I_PUSH, "ldterm"); /* push ldterm*/ #endif if(eventer_set_fd_nonblocking(*master)) return -1; noitL(noit_debug, "allocate_pty -> %d,%d\n", *master, *slave); return 0; }