Esempio n. 1
0
void mtev_skiplist_set_compare(mtev_skiplist *sl,
                               mtev_skiplist_comparator_t comp,
                              mtev_skiplist_comparator_t compk) {
  if(sl->compare && sl->comparek) {
    mtev_skiplist_add_index(sl, comp, compk);
  } else {
    sl->compare = comp;
    sl->comparek = compk;
  }
}
Esempio n. 2
0
int external_child(external_data_t *data) {
  in_fd = data->pipe_n2e[0];
  out_fd = data->pipe_e2n[1];
  nlerr = data->nlerr;
  nldeb = data->nldeb;

  /* switch to / */
  if(chdir("/") != 0) {
    mtevL(noit_error, "Failed chdir(\"/\"): %s\n", strerror(errno));
    return -1;
  }

  mtev_skiplist_init(&active_procs);
  mtev_skiplist_set_compare(&active_procs, __proc_state_check_no,
                            __proc_state_check_no_key);
  mtev_skiplist_add_index(&active_procs, __proc_state_pid,
                          __proc_state_pid_key);
  mtev_skiplist_init(&done_procs);
  mtev_skiplist_set_compare(&done_procs, __proc_state_check_no,
                            __proc_state_check_no_key);

  while(1) {
    struct pollfd pfd;
    struct proc_state *proc_state;
    int64_t check_no;
    int16_t argcnt, *arglens, envcnt, *envlens;
    int i;

    sig_noop(SIGCHLD);

    /* We poll here so that we can be interrupted by the SIGCHLD */
    pfd.fd = in_fd;
    pfd.events = POLLIN;
    while(poll(&pfd, 1, -1) == -1 && errno == EINTR) finish_procs();

    assert_read(in_fd, &check_no, sizeof(check_no));
    assert_read(in_fd, &argcnt, sizeof(argcnt));
    if(argcnt == 0) {
      /* cancellation */
      fetch_and_kill_by_check(check_no);
      continue;
    }
    assert(argcnt > 1);
    proc_state = calloc(1, sizeof(*proc_state));
    proc_state->stdout_fd = -1;
    proc_state->stderr_fd = -1;
    proc_state->check_no = check_no;

    /* read in the argument lengths */
    arglens = calloc(argcnt, sizeof(*arglens));
    assert_read(in_fd, arglens, argcnt * sizeof(*arglens));
    /* first string is the path, second is the first argv[0] */
    /* we need to allocate argcnt + 1 (NULL), but the first is path */
    proc_state->argv = malloc(argcnt * sizeof(*proc_state->argv));
    /* read each string, first in path, second into argv[0], ... */
    /* arglens[i] comes from the parent, so we should trust it */
    /* coverity[tainted_data] */
    proc_state->path = malloc(arglens[0]);
    assert_read(in_fd, proc_state->path, arglens[0]);
    for(i=0; i<argcnt-1; i++) {
      proc_state->argv[i] = malloc(arglens[i+1]);
      assert_read(in_fd, proc_state->argv[i], arglens[i+1]);
    }
    proc_state->argv[i] = NULL;
    free(arglens);

    /* similar thing with envp, but no path trickery */
    assert_read(in_fd, &envcnt, sizeof(envcnt));
    envlens = calloc(envcnt, sizeof(*envlens));
    assert_read(in_fd, envlens, envcnt * sizeof(*envlens));
    proc_state->envp = malloc((envcnt+1) * sizeof(*proc_state->envp));
    for(i=0; i<envcnt; i++) {
      proc_state->envp[i] = malloc(envlens[i]);
      assert_read(in_fd, proc_state->envp[i], envlens[i]);
    }
    proc_state->envp[i] = NULL;
    free(envlens);

    /* All set, this just needs to be run */
    external_proc_spawn(proc_state);

    finish_procs();
  }
}
Esempio n. 3
0
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);
}