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);
}
Example #2
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);
}
Example #4
0
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;
}
Example #5
0
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;
}