void
stratcon_datastore_core_init() {
  static int initialized = 0;
  if(initialized) return;
  initialized = 1;
  ds_err = mtev_log_stream_find("error/datastore");
  ds_deb = mtev_log_stream_find("debug/datastore");
  ds_pool_deb = mtev_log_stream_find("debug/datastore_pool");
  ingest_err = mtev_log_stream_find("error/ingest");
  if(!ds_err) ds_err = noit_error;
  if(!ingest_err) ingest_err = noit_error;
  if(!mtev_conf_get_string(NULL, "//database/journal/path",
                           &basejpath)) {
    mtevL(noit_error, "//database/journal/path is unspecified\n");
    exit(-1);
  }
}
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;
}
Example #3
0
int mtev_load_image(const char *file, const char *name,
                    mtev_hash_table *registry,
                    int (*validate)(mtev_image_t *),
                    size_t obj_size) {
  char module_file[PATH_MAX];
  const char *dlsymname;
  void *dlhandle = NULL;
  void *dlsymbol;
  mtev_image_t *obj;

  if(file[0] == '/') {
    strlcpy(module_file, file, sizeof(module_file));
    dlhandle = dlopen(module_file, RTLD_LAZY | RTLD_GLOBAL);
  }
  else {
    char *basepath, *base, *brk;
    if(!mtev_conf_get_string(MTEV_CONF_ROOT, "//modules/@directory", &basepath))
      basepath = strdup(MTEV_MODULES_DIR);
    for (base = strtok_r(basepath, ";:", &brk);
         base;
         base = strtok_r(NULL, ";:", &brk)) {
      snprintf(module_file, sizeof(module_file), "%s/%s.%s",
               base, file, MODULEEXT);
      dlhandle = dlopen(module_file, RTLD_LAZY | RTLD_GLOBAL);
      if(dlhandle) {
         mtevL(mtev_debug, "Successfully opened image '%s'\n",
               module_file);
        break;
      } else {
         mtevL(mtev_debug, "Tried to open image '%s' but failed: %s\n",
               module_file, dlerror());
      }
    }
    free(basepath);
    if(!dlhandle) {
      snprintf(module_file, sizeof(module_file), "%s/%s.%s",
               MTEV_MODULES_DIR, file, MODULEEXT);
      dlhandle = dlopen(module_file, RTLD_LAZY | RTLD_GLOBAL);
    }
  }

  if(!dlhandle) {
    mtevL(mtev_stderr, "Cannot open image '%s': %s\n",
          module_file, dlerror());
    return -1;
  }

  dlsymname = strrchr(name, ':');
  if(!dlsymname) dlsymname = name;
  else dlsymname++;
  dlsymbol = dlsym(dlhandle, dlsymname);
  if(!dlsymbol) {
    mtevL(mtev_stderr, "Cannot find '%s' in image '%s': %s\n",
          dlsymname, module_file, dlerror());
    dlclose(dlhandle);
    return -1;
  }

  if(validate(dlsymbol) == -1) {
    mtevL(mtev_stderr, "I can't understand module %s\n", name);
    dlclose(dlhandle);
    return -1;
  }

  obj = calloc(1, obj_size);
  memcpy(obj, dlsymbol, obj_size);
  obj->opaque_handle = calloc(1, sizeof(struct __extended_image_data));

  if(obj->onload && obj->onload(obj)) {
    free(obj->opaque_handle);
    free(obj);
    dlclose(dlhandle);
    return -1;
  }
  char *namecopy = strdup(name);
  if(!mtev_hash_store(registry, namecopy, strlen(namecopy), obj)) {
    mtevL(mtev_error, "Attempted to load module %s more than once.\n", name);
    dlclose(dlhandle);
    free(namecopy);
    return -1;
  }
  ((struct __extended_image_data *)obj->opaque_handle)->dlhandle = dlhandle;
  return 0;
}
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;
}