void noit_jlog_listener_init() { xmlNodePtr node; eventer_name_callback("log_transit/1.0", noit_jlog_handler); mtev_control_dispatch_delegate(mtev_control_dispatch, NOIT_JLOG_DATA_FEED, noit_jlog_handler); mtev_control_dispatch_delegate(mtev_control_dispatch, NOIT_JLOG_DATA_TEMP_FEED, noit_jlog_handler); node = mtev_conf_get_section(NULL, "//logs"); if (node) { mtev_conf_get_int(node, "//jlog/max_msg_batch_lines", &MAX_ROWS_AT_ONCE); mtev_conf_get_int(node, "//jlog/default_mseconds_between_batches", &DEFAULT_MSECONDS_BETWEEN_BATCHES); mtev_conf_get_int(node, "//jlog/default_transient_mseconds_between_batches", &DEFAULT_TRANSIENT_MSECONDS_BETWEEN_BATCHES); } mtevAssert(mtev_http_rest_register_auth( "GET", "/", "^feed$", rest_show_feed, mtev_http_rest_client_cert_auth ) == 0); mtevAssert(mtev_http_rest_register_auth( "DELETE", "/feed/", "^(.+)$", rest_delete_feed, mtev_http_rest_client_cert_auth ) == 0); mtevAssert(mtev_http_rest_register_auth( "PUT", "/", "^feed$", rest_add_feed, mtev_http_rest_client_cert_auth ) == 0); }
static iep_thread_driver_t *noit_rabbimq_allocate(mtev_conf_section_t conf) { char *hostname = NULL, *cp, *brk; struct amqp_driver *dr = NULL; int i; pthread_mutex_lock(&driver_lock); for(i=0; i<MAX_HOSTS; i++) { if(stats.thread_states[i].owner == (pthread_t)(intptr_t)NULL) { stats.thread_states[i].owner = pthread_self(); dr = &stats.thread_states[i]; break; } } pthread_mutex_unlock(&driver_lock); if(!dr) return NULL; dr->nconnects = rand(); #define GETCONFSTR(w) mtev_conf_get_stringbuf(conf, #w, dr->w, sizeof(dr->w)) GETCONFSTR(exchange); if(!GETCONFSTR(routingkey)) dr->routingkey[0] = '\0'; GETCONFSTR(username); GETCONFSTR(password); if(!GETCONFSTR(vhost)) { dr->vhost[0] = '/'; dr->vhost[1] = '\0'; } if(!mtev_conf_get_int(conf, "heartbeat", &dr->heartbeat)) dr->heartbeat = 5000; dr->heartbeat = (dr->heartbeat + 999) / 1000; (void)mtev_conf_get_string(conf, "hostname", &hostname); if(!hostname) hostname = strdup("127.0.0.1"); for(cp = hostname; cp; cp = strchr(cp+1, ',')) dr->nhosts++; if(dr->nhosts > MAX_HOSTS) dr->nhosts = MAX_HOSTS; for(i = 0, cp = strtok_r(hostname, ",", &brk); cp; cp = strtok_r(NULL, ",", &brk), i++) strlcpy(dr->hostname[i], cp, sizeof(dr->hostname[i])); free(hostname); if(!mtev_conf_get_int(conf, "port", &dr->port)) dr->port = 5672; mtev_atomic_inc64(&stats.concurrency); return (iep_thread_driver_t *)dr; }
void noit_check_resolver_init() { int cnt; mtev_conf_section_t *servers, *searchdomains; eventer_t e; if(dns_init(NULL, 0) < 0) mtevL(noit_error, "dns initialization failed.\n"); dns_ctx = dns_new(NULL); if(dns_init(dns_ctx, 0) != 0) { mtevL(noit_error, "dns initialization failed.\n"); exit(-1); } /* Optional servers */ servers = mtev_conf_get_sections(NULL, "//resolver//server", &cnt); if(cnt) { int i; char server[128]; dns_add_serv(dns_ctx, NULL); /* reset */ for(i=0;i<cnt;i++) { if(mtev_conf_get_stringbuf(servers[i], "self::node()", server, sizeof(server))) { if(dns_add_serv(dns_ctx, server) < 0) { mtevL(noit_error, "Failed adding DNS server: %s\n", server); } } } free(servers); } searchdomains = mtev_conf_get_sections(NULL, "//resolver//search", &cnt); if(cnt) { int i; char search[128]; dns_add_srch(dns_ctx, NULL); /* reset */ for(i=0;i<cnt;i++) { if(mtev_conf_get_stringbuf(searchdomains[i], "self::node()", search, sizeof(search))) { if(dns_add_srch(dns_ctx, search) < 0) { mtevL(noit_error, "Failed adding DNS search path: %s\n", search); } else if(dns_search_flag) dns_search_flag = 0; /* enable search */ } } free(searchdomains); } if(mtev_conf_get_int(NULL, "//resolver/@ndots", &cnt)) dns_set_opt(dns_ctx, DNS_OPT_NDOTS, cnt); if(mtev_conf_get_int(NULL, "//resolver/@ntries", &cnt)) dns_set_opt(dns_ctx, DNS_OPT_NTRIES, cnt); if(mtev_conf_get_int(NULL, "//resolver/@timeout", &cnt)) dns_set_opt(dns_ctx, DNS_OPT_TIMEOUT, cnt); if(dns_open(dns_ctx) < 0) { mtevL(noit_error, "dns open failed.\n"); exit(-1); } eventer_name_callback("dns_cache_callback", dns_cache_callback); dns_set_tmcbck(dns_ctx, dns_cache_utm_fn, dns_ctx); e = eventer_alloc(); e->mask = EVENTER_READ | EVENTER_EXCEPTION; e->closure = dns_ctx; e->callback = dns_cache_callback; e->fd = dns_sock(dns_ctx); eventer_add(e); mtev_skiplist_init(&nc_dns_cache); mtev_skiplist_set_compare(&nc_dns_cache, name_lookup, name_lookup_k); mtev_skiplist_add_index(&nc_dns_cache, refresh_idx, refresh_idx_k); /* maybe load it from cache */ if(noit_resolver_cache_load_hook_exists()) { struct timeval now; char *key; void *data; int len; gettimeofday(&now, NULL); while(noit_resolver_cache_load_hook_invoke(&key, &data, &len) == MTEV_HOOK_CONTINUE) { dns_cache_node *n; n = calloc(1, sizeof(*n)); if(dns_cache_node_deserialize(n, data, len) >= 0) { n->target = strdup(key); /* if the TTL indicates that it will expire in less than 60 seconds * (including stuff that should have already expired), then fudge * the last_updated time to make it expire some random time within * the next 60 seconds. */ if(n->last_needed > now.tv_sec || n->last_updated > now.tv_sec) break; /* impossible */ n->last_needed = now.tv_sec; if(n->last_updated + n->ttl < now.tv_sec + 60) { int fudge = MIN(60, n->ttl) + 1; n->last_updated = now.tv_sec - n->ttl + (lrand48() % fudge); } DCLOCK(); mtev_skiplist_insert(&nc_dns_cache, n); DCUNLOCK(); n = NULL; } else { mtevL(noit_error, "Failed to deserialize resolver cache record.\n"); } if(n) dns_cache_node_free(n); if(key) free(key); if(data) free(data); } } noit_check_resolver_loop(NULL, 0, NULL, NULL); register_console_dns_cache_commands(); mtev_hash_init(&etc_hosts_cache); noit_check_etc_hosts_cache_refresh(NULL, 0, NULL, NULL); }
int mtev_main(const char *appname, const char *config_filename, int debug, int foreground, mtev_lock_op_t lock, const char *_glider, const char *drop_to_user, const char *drop_to_group, int (*passed_child_main)(void)) { mtev_conf_section_t watchdog_conf; int fd, lockfd, watchdog_timeout = 0, rv; int wait_for_lock; char conf_str[1024]; char lockfile[PATH_MAX]; char *trace_dir = NULL; char appscratch[1024]; char *glider = (char *)_glider; char *watchdog_timeout_str; int retry_val; int span_val; int ret; int cnt; mtev_conf_section_t root; wait_for_lock = (lock == MTEV_LOCK_OP_WAIT) ? 1 : 0; mtev_init_globals(); char *require_invariant_tsc = getenv("MTEV_RDTSC_REQUIRE_INVARIANT"); if (require_invariant_tsc && strcmp(require_invariant_tsc, "0") == 0) { mtev_time_toggle_require_invariant_tsc(mtev_false); } char *disable_rdtsc = getenv("MTEV_RDTSC_DISABLE"); if (disable_rdtsc && strcmp(disable_rdtsc, "1") == 0) { mtev_time_toggle_tsc(mtev_false); } char *disable_binding = getenv("MTEV_THREAD_BINDING_DISABLE"); if (disable_binding && strcmp(disable_binding, "1") == 0) { mtev_thread_disable_binding(); } /* First initialize logging, so we can log errors */ mtev_log_init(debug); mtev_log_stream_add_stream(mtev_debug, mtev_stderr); mtev_log_stream_add_stream(mtev_error, mtev_stderr); mtev_log_stream_add_stream(mtev_notice, mtev_error); /* Next load the configs */ mtev_conf_use_namespace(appname); mtev_conf_init(appname); if(mtev_conf_load(config_filename) == -1) { fprintf(stderr, "Cannot load config: '%s'\n", config_filename); exit(-1); } char* root_section_path = alloca(strlen(appname)+2); sprintf(root_section_path, "/%s", appname); root = mtev_conf_get_sections(NULL, root_section_path, &cnt); free(root); if(cnt==0) { fprintf(stderr, "The config must have <%s> as its root node\n", appname); exit(-1); } /* Reinitialize the logging system now that we have a config */ mtev_conf_log_init(appname, drop_to_user, drop_to_group); if(debug) { mtev_log_stream_set_flags(mtev_debug, mtev_log_stream_get_flags(mtev_debug) | MTEV_LOG_STREAM_ENABLED); } cli_log_switches(); snprintf(appscratch, sizeof(appscratch), "/%s/watchdog|/%s/include/watchdog", appname, appname); watchdog_conf = mtev_conf_get_section(NULL, appscratch); if(!glider) (void) mtev_conf_get_string(watchdog_conf, "@glider", &glider); if(mtev_watchdog_glider(glider)) { mtevL(mtev_stderr, "Invalid glider, exiting.\n"); exit(-1); } (void)mtev_conf_get_string(watchdog_conf, "@tracedir", &trace_dir); if(trace_dir) { if(mtev_watchdog_glider_trace_dir(trace_dir)) { mtevL(mtev_stderr, "Invalid glider tracedir, exiting.\n"); exit(-1); } } ret = mtev_conf_get_int(watchdog_conf, "@retries", &retry_val); if((ret == 0) || (retry_val == 0)) { retry_val = 5; } ret = mtev_conf_get_int(watchdog_conf, "@span", &span_val); if((ret == 0) || (span_val == 0)) { span_val = 60; } mtev_watchdog_ratelimit(retry_val, span_val); /* Lastly, run through all other system inits */ snprintf(appscratch, sizeof(appscratch), "/%s/eventer/@implementation", appname); if(!mtev_conf_get_stringbuf(NULL, appscratch, conf_str, sizeof(conf_str))) { mtevL(mtev_stderr, "Cannot find '%s' in configuration\n", appscratch); exit(-1); } if(eventer_choose(conf_str) == -1) { mtevL(mtev_stderr, "Cannot choose eventer %s\n", conf_str); exit(-1); } if(configure_eventer(appname) != 0) { mtevL(mtev_stderr, "Cannot configure eventer\n"); exit(-1); } mtev_watchdog_prefork_init(); if(foreground != 1 && chdir("/") != 0) { mtevL(mtev_stderr, "Failed chdir(\"/\"): %s\n", strerror(errno)); exit(-1); } /* Acquire the lock so that we can throw an error if it doesn't work. * If we've started -D, we'll have the lock. * If not we will daemon and must reacquire the lock. */ lockfd = -1; lockfile[0] = '\0'; snprintf(appscratch, sizeof(appscratch), "/%s/@lockfile", appname); if(lock != MTEV_LOCK_OP_NONE && mtev_conf_get_stringbuf(NULL, appscratch, lockfile, sizeof(lockfile))) { do { if((lockfd = mtev_lockfile_acquire(lockfile)) < 0) { if(!wait_for_lock) { mtevL(mtev_stderr, "Failed to acquire lock: %s\n", lockfile); exit(-1); } if(wait_for_lock == 1) { mtevL(mtev_stderr, "%d failed to acquire lock(%s), waiting...\n", (int)getpid(), lockfile); wait_for_lock++; } usleep(1000); } else { if(wait_for_lock > 1) mtevL(mtev_stderr, "Lock acquired proceeding.\n"); wait_for_lock = 0; } } while(wait_for_lock); } if(foreground == 1) { mtev_time_start_tsc(); mtevL(mtev_notice, "%s booting [unmanaged]\n", appname); int rv = passed_child_main(); mtev_lockfile_release(lockfd); return rv; } watchdog_timeout_str = getenv("WATCHDOG_TIMEOUT"); if(watchdog_timeout_str) { watchdog_timeout = atoi(watchdog_timeout_str); mtevL(mtev_error, "Setting watchdog timeout to %d\n", watchdog_timeout); } /* This isn't inherited across forks... */ if(lockfd >= 0) mtev_lockfile_release(lockfd); lockfd = -1; if(foreground == 0) { fd = open("/dev/null", O_RDONLY); if(fd < 0 || dup2(fd, STDIN_FILENO) < 0) { fprintf(stderr, "Failed to setup stdin: %s\n", strerror(errno)); exit(-1); } close(fd); fd = open("/dev/null", O_WRONLY); if(fd < 0 || dup2(fd, STDOUT_FILENO) < 0 || dup2(fd, STDERR_FILENO) < 0) { fprintf(stderr, "Failed to setup std{out,err}: %s\n", strerror(errno)); exit(-1); } close(fd); if(fork()) exit(0); setsid(); if(fork()) exit(0); } /* Reacquire the lock */ if(*lockfile) { if (lock) { if((lockfd = mtev_lockfile_acquire(lockfile)) < 0) { mtevL(mtev_stderr, "Failed to acquire lock: %s\n", lockfile); exit(-1); } } } signal(SIGHUP, SIG_IGN); mtevL(mtev_notice, "%s booting\n", appname); rv = mtev_watchdog_start_child(appname, passed_child_main, watchdog_timeout); mtev_lockfile_release(lockfd); return rv; }
static iep_thread_driver_t *noit_fq_allocate(mtev_conf_section_t conf) { char *hostname, *cp, *brk, *round_robin; int i; #define GETCONFSTR(w) mtev_conf_get_stringbuf(conf, #w, global_fq_ctx.w, sizeof(global_fq_ctx.w)) memset(&global_fq_ctx.down_host, 0, sizeof(global_fq_ctx.down_host)); memset(&global_fq_ctx.last_error, 0, sizeof(global_fq_ctx.last_error)); memset(&global_fq_ctx.filtered_exchange, 0, sizeof(global_fq_ctx.filtered_exchange)); snprintf(global_fq_ctx.exchange, sizeof(global_fq_ctx.exchange), "%s", "noit.firehose"); GETCONFSTR(exchange); GETCONFSTR(filtered_exchange); if(!GETCONFSTR(routingkey)) snprintf(global_fq_ctx.routingkey, sizeof(global_fq_ctx.routingkey), "%s", "check"); snprintf(global_fq_ctx.username, sizeof(global_fq_ctx.username), "%s", "guest"); GETCONFSTR(username); snprintf(global_fq_ctx.password, sizeof(global_fq_ctx.password), "%s", "guest"); GETCONFSTR(password); if(!mtev_conf_get_int(conf, "heartbeat", &global_fq_ctx.heartbeat)) global_fq_ctx.heartbeat = 2000; if(!mtev_conf_get_int(conf, "backlog", &global_fq_ctx.backlog)) global_fq_ctx.backlog = 10000; if(!mtev_conf_get_int(conf, "port", &global_fq_ctx.port)) global_fq_ctx.port = 8765; (void)mtev_conf_get_string(conf, "round_robin", &round_robin); if (!round_robin) { global_fq_ctx.round_robin = 0; } else { if (!(strncmp(round_robin, "true", 4))) { global_fq_ctx.round_robin = 1; global_fq_ctx.round_robin_target = 0; } else { global_fq_ctx.round_robin = 0; } } (void)mtev_conf_get_string(conf, "hostname", &hostname); if(!hostname) hostname = strdup("127.0.0.1"); for(cp = hostname; cp; cp = strchr(cp+1, ',')) global_fq_ctx.nhosts++; if(global_fq_ctx.nhosts > MAX_HOSTS) global_fq_ctx.nhosts = MAX_HOSTS; for(i = 0, cp = strtok_r(hostname, ",", &brk); cp; cp = strtok_r(NULL, ",", &brk), i++) { char *pcp; fq_client *c = &global_fq_ctx.client[i]; global_fq_ctx.ports[i] = global_fq_ctx.port; strlcpy(global_fq_ctx.hostname[i], cp, sizeof(global_fq_ctx.hostname[i])); pcp = strchr(global_fq_ctx.hostname[i], ':'); if(pcp) { *pcp++ = '\0'; global_fq_ctx.ports[i] = atoi(pcp); } fq_client_init(c, 0, fq_logger); fq_client_creds(*c, global_fq_ctx.hostname[i], global_fq_ctx.ports[i], global_fq_ctx.username, global_fq_ctx.password); fq_client_heartbeat(*c, global_fq_ctx.heartbeat); fq_client_set_nonblock(*c, 1); fq_client_set_backlog(*c, global_fq_ctx.backlog, 0); fq_client_connect(*c); } free(hostname); return (iep_thread_driver_t *)&global_fq_ctx; }