Beispiel #1
0
void 
app_shutdown(void)
{
  run_application_hook(AH_SHUTDOWN);
  log_template_global_deinit();
  log_tags_global_deinit();
  log_msg_global_deinit();

  stats_destroy();
  child_manager_deinit();
  g_list_foreach(application_hooks, (GFunc) g_free, NULL);
  g_list_free(application_hooks);
  dns_cache_thread_deinit();
  dns_cache_global_deinit();
  hostname_global_deinit();
  crypto_deinit();
  msg_deinit();

  
  /* NOTE: the iv_deinit() call should come here, but there's some exit
   * synchronization issue in libivykis that causes use-after-free with the
   * thread-local-state for the main thread and iv_work_pool worker threads. 
   * I've dropped a mail to Lennert about the issue, but I'm commenting this
   * out for now to avoid it biting someone. Bazsi, 2013/12/23.
   *
   *

    iv_deinit();

   */
}
Beispiel #2
0
void
test_reset_stats()
{
  GString *reply = NULL;
  GString *command = g_string_sized_new(128);
  StatsCounterItem *counter = NULL;

  stats_init();
  stats_lock();
  stats_register_counter(0, SCS_CENTER, "id", "received", SC_TYPE_PROCESSED, &counter);
  stats_counter_set(counter, 666);
  stats_unlock();

  g_string_assign(command, "RESET_STATS");
  reply = control_connection_reset_stats(command);
  assert_string(reply->str, "The statistics of syslog-ng have been reset to 0.", "Bad reply");
  g_string_free(reply, TRUE);

  g_string_assign(command, "STATS");
  reply = control_connection_send_stats(command);
  assert_string(reply->str, "SourceName;SourceId;SourceInstance;State;Type;Number\ncenter;id;received;a;processed;0\n", "Bad reply");
  g_string_free(reply, TRUE);

  stats_destroy();
  g_string_free(command, TRUE);
  return;
}
Beispiel #3
0
void
test_stats()
{
  GString *reply = NULL;
  GString *command = g_string_sized_new(128);
  StatsCounterItem *counter = NULL;
  gchar **stats_result;

  stats_init();
  stats_lock();
  stats_register_counter(0, SCS_CENTER, "id", "received", SC_TYPE_PROCESSED, &counter);
  stats_unlock();

  g_string_assign(command,"STATS");

  reply = control_connection_send_stats(command);
  stats_result = g_strsplit(reply->str, "\n", 2);
  assert_string(stats_result[0], "SourceName;SourceId;SourceInstance;State;Type;Number",
                "Bad reply");
  g_strfreev(stats_result);
  g_string_free(reply, TRUE);

  g_string_free(command, TRUE);
  stats_destroy();
  return;
}
static void
teardown(void)
{
  scratch_buffers_explicit_gc();
  scratch_buffers_allocator_deinit();
  scratch_buffers_global_deinit();
  stats_destroy();
}
Beispiel #5
0
static void
core_ctx_destroy(struct context *ctx)
{
    log_debug(LOG_VVERB, "destroy ctx %p id %"PRIu32"", ctx, ctx->id);
    proxy_deinit(ctx);
    server_pool_disconnect(ctx);
    event_deinit(ctx);
    stats_destroy(ctx->stats);
    server_pool_deinit(&ctx->pool);
    conf_destroy(ctx->cf);
    nc_free(ctx);
}
Beispiel #6
0
void
app_shutdown(void)
{
    run_application_hook(AH_SHUTDOWN);
    log_tags_deinit();
    stats_destroy();
    dns_cache_destroy();
    child_manager_deinit();
    g_list_foreach(application_hooks, (GFunc) g_free, NULL);
    g_list_free(application_hooks);
    msg_deinit();
}
Beispiel #7
0
Test(control_cmds, test_stats)
{
  StatsCounterItem *counter = NULL;
  gchar **stats_result;
  const gchar *response;

  stats_init();

  stats_lock();
  StatsClusterKey sc_key;
  stats_cluster_logpipe_key_set(&sc_key, SCS_CENTER, "id", "received" );
  stats_register_counter(0, &sc_key, SC_TYPE_PROCESSED, &counter);
  stats_unlock();

  _run_command("STATS", &response);

  stats_result = g_strsplit(response, "\n", 2);
  cr_assert_str_eq(stats_result[0], "SourceName;SourceId;SourceInstance;State;Type;Number",
                   "Bad reply");
  g_strfreev(stats_result);
  stats_destroy();
}
Beispiel #8
0
Test(control_cmds, test_reset_stats)
{
  StatsCounterItem *counter = NULL;
  const gchar *response;

  stats_init();

  stats_lock();
  StatsClusterKey sc_key;
  stats_cluster_logpipe_key_set(&sc_key, SCS_CENTER, "id", "received" );
  stats_register_counter(0, &sc_key, SC_TYPE_PROCESSED, &counter);
  stats_counter_set(counter, 666);
  stats_unlock();

  _run_command("RESET_STATS", &response);
  cr_assert(first_line_eq(response, "OK The statistics of syslog-ng have been reset to 0."), "Bad reply");

  _run_command("STATS", &response);
  cr_assert_str_eq(response,
                   "SourceName;SourceId;SourceInstance;State;Type;Number\ncenter;id;received;a;processed;0\n.\n",
                   "Bad reply");
  stats_destroy();
}
Beispiel #9
0
struct stats *
stats_create(uint16_t stats_port, char *stats_ip, int stats_interval,
             char *source, struct array *server_pool)
{
    rstatus_t status;
    struct stats *st;
    char *server_name;

    st = nc_alloc(sizeof(*st));
    if (st == NULL) {
        return NULL;
    }

    st->port = stats_port;
    st->interval = stats_interval;
    string_set_raw(&st->addr, stats_ip);

    st->start_ts = (int64_t)time(NULL);

    st->buf.len = 0;
    st->buf.data = NULL;
    st->buf.size = 0;

    array_null(&st->current);
    array_null(&st->shadow);
    array_null(&st->sum);

    st->tid = (pthread_t) -1;
    st->sd = -1;

    string_set_text(&st->service_str, "service");
    //string_set_text(&st->service, "bilitw");

    server_name = nc_alloc(100);
    memset(server_name, 0, 100);
    sprintf(server_name, "bilitw worker %d", nc_worker_index);
    string_set_raw(&st->service, server_name);
    //&st->service->len = strlen(server_name) + 1;
    //&st->service->data = (uint8_t *)server_name;


    string_set_text(&st->source_str, "source");
    string_set_raw(&st->source, source);

    string_set_text(&st->version_str, "version");
    string_set_text(&st->version, NC_VERSION_STRING);

    string_set_text(&st->uptime_str, "uptime");
    string_set_text(&st->timestamp_str, "timestamp");

    string_set_text(&st->ntotal_conn_str, "total_connections");
    string_set_text(&st->ncurr_conn_str, "curr_connections");

    st->updated = 0;
    st->aggregate = 0;

    /* map server pool to current (a), shadow (b) and sum (c) */

    status = stats_pool_map(&st->current, server_pool);
    if (status != NC_OK) {
        goto error;
    }

    status = stats_pool_map(&st->shadow, server_pool);
    if (status != NC_OK) {
        goto error;
    }

    status = stats_pool_map(&st->sum, server_pool);
    if (status != NC_OK) {
        goto error;
    }

    status = stats_create_buf(st);
    if (status != NC_OK) {
        goto error;
    }

    status = stats_start_aggregator(st);
    if (status != NC_OK) {
        goto error;
    }

    return st;

error:
    stats_destroy(st);
    return NULL;
}
Beispiel #10
0
static struct context *
core_ctx_create(struct instance *nci)
{
    rstatus_t status;
    struct context *ctx;
    struct conn *sentinel_conn;

    ctx = nc_alloc(sizeof(*ctx));
    if (ctx == NULL) {
        return NULL;
    }
    ctx->id = ++ctx_id;
    ctx->cf = NULL;
    ctx->stats = NULL;
    array_null(&ctx->pool);
    ctx->ep = -1;
    ctx->nevent = EVENT_SIZE_HINT;
    ctx->max_timeout = nci->stats_interval;
    ctx->timeout = ctx->max_timeout;
    ctx->event = NULL;
    ctx->server_reconnect_interval = nci->server_reconnect_interval;
    ctx->whitelist = nci->whitelist;

    /* parse and create configuration */
    ctx->cf = conf_create(nci->conf_filename);
    if (ctx->cf == NULL) {
        nc_free(ctx);
        return NULL;
    }

    /* initialize server pool from configuration */
    status = server_pool_init(&ctx->pool, &ctx->cf->pool, ctx);
    if (status != NC_OK) {
        conf_destroy(ctx->cf);
        nc_free(ctx);
        return NULL;
    }

    /* initialize sentinel server */
    ctx->sentinel = sentinel_init(nci->sentinel_port, nci->sentinel_addr);
    if (ctx->sentinel == NULL) {
        server_pool_deinit(&ctx->pool);
        conf_destroy(ctx->cf);
        nc_free(ctx);
        return NULL;
    }

    /* create stats per server pool */
    ctx->stats = stats_create(nci->stats_port, nci->stats_addr, nci->stats_interval,
                              nci->hostname, &ctx->pool);
    if (ctx->stats == NULL) {
        sentinel_deinit(ctx->sentinel);
        server_pool_deinit(&ctx->pool);
        conf_destroy(ctx->cf);
        nc_free(ctx);
        return NULL;
    }

    /* initialize event handling for client, proxy and server */
    status = event_init(ctx, EVENT_SIZE_HINT);
    if (status != NC_OK) {
        stats_destroy(ctx->stats);
        sentinel_deinit(ctx->sentinel);
        server_pool_deinit(&ctx->pool);
        conf_destroy(ctx->cf);
        nc_free(ctx);
        return NULL;
    }

    /* preconnect? servers in server pool */
    status = server_pool_preconnect(ctx);
    if (status != NC_OK) {
        server_pool_disconnect(ctx);
        event_deinit(ctx);
        stats_destroy(ctx->stats);
        sentinel_deinit(ctx->sentinel);
        server_pool_deinit(&ctx->pool);
        conf_destroy(ctx->cf);
        nc_free(ctx);
        return NULL;
    }

    /* initialize sentinel server conn */
    sentinel_conn = sentinel_connect(ctx);
    if (sentinel_conn == NULL) {
        server_pool_disconnect(ctx);
        event_deinit(ctx);
        stats_destroy(ctx->stats);
        sentinel_deinit(ctx->sentinel);
        server_pool_deinit(&ctx->pool);
        conf_destroy(ctx->cf);
        nc_free(ctx);
    }

    /* initialize proxy per server pool */
    status = proxy_init(ctx);
    if (status != NC_OK) {
        sentinel_conn->close(ctx, sentinel_conn);
        server_pool_disconnect(ctx);
        event_deinit(ctx);
        stats_destroy(ctx->stats);
        sentinel_deinit(ctx->sentinel);
        server_pool_deinit(&ctx->pool);
        conf_destroy(ctx->cf);
        nc_free(ctx);
        return NULL;
    }

    log_debug(LOG_VVERB, "created ctx %p id %"PRIu32"", ctx, ctx->id);

    return ctx;
}
struct stats *
stats_create(uint16_t stats_port, char *stats_ip, int stats_interval,
             char *source, struct array *server_pool) 
{
    rstatus_t status;
    struct stats *st;

    st = nc_alloc(sizeof(*st));
    if (st == NULL) {
        return NULL;
    }

    st->port = stats_port;
    st->interval = stats_interval;
    string_set_raw(&st->addr, stats_ip);

    st->start_ts = (int64_t)time(NULL);

    st->buf.len = 0;
    st->buf.data = NULL;
    st->buf.size = 0;

    array_null(&st->current);
    array_null(&st->shadow);
    array_null(&st->sum);

    st->tid = (pthread_t) -1;
    st->sd = -1;

    string_set_text(&st->service_str, "service");
    string_set_text(&st->service, "nutcracker");

    string_set_text(&st->source_str, "source");
    string_set_raw(&st->source, source);

    string_set_text(&st->version_str, "version");
    string_set_text(&st->version, NC_VERSION_STRING);

    string_set_text(&st->uptime_str, "uptime");
    string_set_text(&st->timestamp_str, "timestamp");

    string_set_text(&st->ntotal_conn_str, "total_connections");
    string_set_text(&st->ncurr_conn_str, "curr_connections");

    st->updated = 0;
    st->aggregate = 0;

    /* map server pool to current (a), shadow (b) and sum (c) */

    status = stats_pool_map(&st->current, server_pool);
    if (status != NC_OK) {
        goto error;
    }

    status = stats_pool_map(&st->shadow, server_pool);
    if (status != NC_OK) {
        goto error;
    }

    status = stats_pool_map(&st->sum, server_pool);
    if (status != NC_OK) {
        goto error;
    }

    status = stats_create_buf(st); //为stats格式信息分配buf空间
    if (status != NC_OK) {
        goto error;
    }

    //stats状态信息专门起一个线程来处理
    status = stats_start_aggregator(st);
    if (status != NC_OK) {
        goto error;
    }

    return st;

error:
    stats_destroy(st);
    return NULL;
}
Beispiel #12
0
static struct context *
core_ctx_create(struct instance *nci)
{
	rstatus_t status;
	struct context *ctx;

	srand((unsigned) time(NULL));

	ctx = dn_alloc(sizeof(*ctx));
	if (ctx == NULL) {
		return NULL;
	}
	ctx->id = ++ctx_id;
	ctx->cf = NULL;
	ctx->stats = NULL;
	ctx->evb = NULL;
	array_null(&ctx->pool);
	ctx->max_timeout = nci->stats_interval;
	ctx->timeout = ctx->max_timeout;
	ctx->dyn_state = INIT;

	/* parse and create configuration */
	ctx->cf = conf_create(nci->conf_filename);
	if (ctx->cf == NULL) {
		loga("Failed to create context!!!");
		dn_free(ctx);
		return NULL;
	}

	/* initialize server pool from configuration */
	status = server_pool_init(&ctx->pool, &ctx->cf->pool, ctx);
	if (status != DN_OK) {
		loga("Failed to initialize server pool!!!");
		conf_destroy(ctx->cf);
		dn_free(ctx);
		return NULL;
	}


	/* crypto init */
    status = crypto_init(ctx);
    if (status != DN_OK) {
   	loga("Failed to initialize crypto!!!");
    	dn_free(ctx);
    	return NULL;
    }


	/* create stats per server pool */
	ctx->stats = stats_create(nci->stats_port, nci->stats_addr, nci->stats_interval,
			                  nci->hostname, &ctx->pool, ctx);
	if (ctx->stats == NULL) {
		loga("Failed to create stats!!!");
		crypto_deinit();
		server_pool_deinit(&ctx->pool);
		conf_destroy(ctx->cf);
		dn_free(ctx);
		return NULL;
	}

	/* initialize event handling for client, proxy and server */
	ctx->evb = event_base_create(EVENT_SIZE, &core_core);
	if (ctx->evb == NULL) {
		loga("Failed to create socket event handling!!!");
		crypto_deinit();
		stats_destroy(ctx->stats);
		server_pool_deinit(&ctx->pool);
		conf_destroy(ctx->cf);
		dn_free(ctx);
		return NULL;
	}

	/* preconnect? servers in server pool */
	status = server_pool_preconnect(ctx);
	if (status != DN_OK) {
		loga("Failed to preconnect for server pool!!!");
		crypto_deinit();
		server_pool_disconnect(ctx);
		event_base_destroy(ctx->evb);
		stats_destroy(ctx->stats);
		server_pool_deinit(&ctx->pool);
		conf_destroy(ctx->cf);
		dn_free(ctx);
		return NULL;
	}

	/* initialize proxy per server pool */
	status = proxy_init(ctx);
	if (status != DN_OK) {
		loga("Failed to initialize proxy!!!");
		crypto_deinit();
		server_pool_disconnect(ctx);
		event_base_destroy(ctx->evb);
		stats_destroy(ctx->stats);
		server_pool_deinit(&ctx->pool);
		conf_destroy(ctx->cf);
		dn_free(ctx);
		return NULL;
	}

	/* initialize dnode listener per server pool */
	status = dnode_init(ctx);
	if (status != DN_OK) {
		loga("Failed to initialize dnode!!!");
		crypto_deinit();
		server_pool_disconnect(ctx);
		event_base_destroy(ctx->evb);
		stats_destroy(ctx->stats);
		server_pool_deinit(&ctx->pool);
		conf_destroy(ctx->cf);
		dn_free(ctx);
		return NULL;
	}

	ctx->dyn_state = JOINING;  //TODOS: change this to JOINING

	/* initialize peers */
	status = dnode_peer_init(&ctx->pool, ctx);
	if (status != DN_OK) {
		loga("Failed to initialize dnode peers!!!");
		crypto_deinit();
		dnode_deinit(ctx);
		server_pool_disconnect(ctx);
		event_base_destroy(ctx->evb);
		stats_destroy(ctx->stats);
		server_pool_deinit(&ctx->pool);
		conf_destroy(ctx->cf);
		dn_free(ctx);
		return NULL;
	}

	core_debug(ctx);

	/* preconntect peers - probably start gossip here */
	status = dnode_peer_pool_preconnect(ctx);
	if (status != DN_OK) {
		loga("Failed to preconnect dnode peers!!!");
		crypto_deinit();
		dnode_peer_deinit(&ctx->pool);
		dnode_deinit(ctx);
		server_pool_disconnect(ctx);
		event_base_destroy(ctx->evb);
		stats_destroy(ctx->stats);
		server_pool_deinit(&ctx->pool);
		conf_destroy(ctx->cf);
		dn_free(ctx);
		return NULL;
	}

	//init ring msg queue
	CBUF_Init(C2G_InQ);
	CBUF_Init(C2G_OutQ);

	//init stats msg queue
	CBUF_Init(C2S_InQ);
	CBUF_Init(C2S_OutQ);

	gossip_pool_init(ctx);

	log_debug(LOG_VVERB, "created ctx %p id %"PRIu32"", ctx, ctx->id);

	return ctx;
}
Beispiel #13
0
static struct context *
core_ctx_create(struct instance *nci)
{
    rstatus_t status;
    struct context *ctx;

    ctx = nc_alloc(sizeof(*ctx));
    if (ctx == NULL) {
        return NULL;
    }
    ctx->id = ++ctx_id;
    ctx->cf = NULL;
    ctx->stats = NULL;
    ctx->evb = NULL;
    array_null(&ctx->pool);
    ctx->max_timeout = nci->stats_interval;
    ctx->timeout = ctx->max_timeout;
    ctx->max_nfd = 0;
    ctx->max_ncconn = 0;
    ctx->max_nsconn = 0;

    /* parse and create configuration */
    ctx->cf = conf_create(nci->conf_filename);
    if (ctx->cf == NULL) {
        nc_free(ctx);
        return NULL;
    }

    /* initialize server pool from configuration */
    status = server_pool_init(&ctx->pool, &ctx->cf->pool, ctx);
    if (status != NC_OK) {
        conf_destroy(ctx->cf);
        nc_free(ctx);
        return NULL;
    }

    /*
     * Get rlimit and calculate max client connections after we have
     * calculated max server connections
     */
    status = core_calc_connections(ctx);
    if (status != NC_OK) {
        server_pool_deinit(&ctx->pool);
        conf_destroy(ctx->cf);
        nc_free(ctx);
        return NULL;
    }

    /* create stats per server pool */
    ctx->stats = stats_create(nci->stats_port, nci->stats_addr, nci->stats_interval,
                              nci->hostname, &ctx->pool);
    if (ctx->stats == NULL) {
        server_pool_deinit(&ctx->pool);
        conf_destroy(ctx->cf);
        nc_free(ctx);
        return NULL;
    }

    /* initialize event handling for client, proxy and server */
    ctx->evb = event_base_create(EVENT_SIZE, &core_core);
    if (ctx->evb == NULL) {
        stats_destroy(ctx->stats);
        server_pool_deinit(&ctx->pool);
        conf_destroy(ctx->cf);
        nc_free(ctx);
        return NULL;
    }

    /* preconnect? servers in server pool */
    status = server_pool_preconnect(ctx);
    if (status != NC_OK) {
        server_pool_disconnect(ctx);
        event_base_destroy(ctx->evb);
        stats_destroy(ctx->stats);
        server_pool_deinit(&ctx->pool);
        conf_destroy(ctx->cf);
        nc_free(ctx);
        return NULL;
    }

    /* initialize proxy per server pool */
    status = proxy_init(ctx);
    if (status != NC_OK) {
        server_pool_disconnect(ctx);
        event_base_destroy(ctx->evb);
        stats_destroy(ctx->stats);
        server_pool_deinit(&ctx->pool);
        conf_destroy(ctx->cf);
        nc_free(ctx);
        return NULL;
    }

    log_debug(LOG_VVERB, "created ctx %p id %"PRIu32"", ctx, ctx->id);

    return ctx;
}
Beispiel #14
0
struct stats *
stats_create(uint16_t stats_port, char *stats_ip, int stats_interval,
             char *source, struct array *server_pool, struct context *ctx)
{
    rstatus_t status;
    struct stats *st;

    st = dn_alloc(sizeof(*st));
    if (st == NULL) {
        return NULL;
    }

    st->port = stats_port;
    st->interval = stats_interval;
    string_set_raw(&st->addr, stats_ip);

    st->start_ts = (int64_t)time(NULL);

    st->buf.len = 0;
    st->buf.data = NULL;
    st->buf.size = 0;

    array_null(&st->current);
    array_null(&st->shadow);
    array_null(&st->sum);

    st->tid = (pthread_t) -1;
    st->sd = -1;

    string_set_text(&st->service_str, "service");
    string_set_text(&st->service, "dynomite");

    string_set_text(&st->source_str, "source");
    string_set_raw(&st->source, source);

    string_set_text(&st->version_str, "version");
    string_set_text(&st->version, DN_VERSION_STRING);

    string_set_text(&st->uptime_str, "uptime");
    string_set_text(&st->timestamp_str, "timestamp");

    //for latency histo
    string_set_text(&st->latency_999th_str, "latency_999th");
    string_set_text(&st->latency_99th_str, "latency_99th");
    string_set_text(&st->latency_95th_str, "latency_95th");
    string_set_text(&st->latency_mean_str, "latency_mean");
    string_set_text(&st->latency_max_str, "latency_max");

    //for payload size histo
    string_set_text(&st->payload_size_999th_str, "payload_size_999th");
    string_set_text(&st->payload_size_99th_str, "payload_size_99th");
    string_set_text(&st->payload_size_95th_str, "payload_size_95th");
    string_set_text(&st->payload_size_mean_str, "payload_size_mean");
    string_set_text(&st->payload_size_max_str, "payload_size_max");

    string_set_text(&st->alloc_msgs_str, "alloc_msgs");

    //only display the first pool
    struct server_pool *sp = (struct server_pool*) array_get(server_pool, 0);

    string_set_text(&st->rack_str, "rack");

    string_copy(&st->rack, sp->rack.data, sp->rack.len);

    string_set_text(&st->dc_str, "dc");
    string_copy(&st->dc, sp->dc.data, sp->dc.len);

    st->updated = 0;
    st->aggregate = 0;

    histo_init(&st->latency_histo);
    histo_init(&st->payload_size_histo);

    st->alloc_msgs = 0;

    /* map server pool to current (a), shadow (b) and sum (c) */

    status = stats_pool_map(&st->current, server_pool);
    if (status != DN_OK) {
        goto error;
    }

    status = stats_pool_map(&st->shadow, server_pool);
    if (status != DN_OK) {
        goto error;
    }

    status = stats_pool_map(&st->sum, server_pool);
    if (status != DN_OK) {
        goto error;
    }

    status = stats_create_buf(st);
    if (status != DN_OK) {
        goto error;
    }

    status = stats_start_aggregator(st);
    if (status != DN_OK) {
        goto error;
    }

    st->ctx = ctx;
    return st;

error:
    stats_destroy(st);
    return NULL;
}
Beispiel #15
0
static struct context *
core_ctx_create(struct instance *nci)
{
    rstatus_t status;
    struct context *ctx;
    int64_t now;
    uint32_t npool;

    ctx = nc_alloc(sizeof(*ctx));
    if (ctx == NULL) {
        return NULL;
    }

    now = nc_msec_now();
    if (now < 0) {
        nc_free(ctx);
        return NULL;
    }

    ctx->id = ++ctx_id;
    ctx->cf = NULL;
    ctx->stats = NULL;
    ctx->evb = NULL;
    array_null(&ctx->pool);
    ctx->max_timeout = nci->stats_interval;
    ctx->timeout = ctx->max_timeout;
    ctx->next_tick = now + NC_TICK_INTERVAL;

    /* parse and create configuration */
    ctx->cf = conf_create(nci->conf_filename);
    if (ctx->cf == NULL) {
        nc_free(ctx);
        return NULL;
    }

    npool = array_n(&ctx->cf->pool);
    
    /* initialize server pool from configuration */
    if (npool != 0) {
        status = server_pool_init(&ctx->pool, &ctx->cf->pool, ctx);
        if (status != NC_OK) {
            conf_destroy(ctx->cf);
            nc_free(ctx);
            return NULL;
        }
    }

    /* create stats per server pool */
    if (npool != 0) {
        ctx->stats = stats_create(nci->stats_port, nci->stats_addr, nci->stats_interval,
                                  nci->hostname, &ctx->pool);
        if (ctx->stats == NULL) {
            server_pool_deinit(&ctx->pool);
            conf_destroy(ctx->cf);
            nc_free(ctx);
            return NULL;
        }
    }

    /* initialize event handling for client, proxy and server */
    ctx->evb = evbase_create(NC_EVENT_SIZE, &core_core);
    if (ctx->evb == NULL) {
        stats_destroy(ctx->stats);
        server_pool_deinit(&ctx->pool);
        conf_destroy(ctx->cf);
        nc_free(ctx);
        return NULL;
    }

    /* preconnect? servers in server pool */
    if (npool != 0) {
        status = server_pool_preconnect(ctx);
        if (status != NC_OK) {
            server_pool_disconnect(ctx);
            evbase_destroy(ctx->evb);
            stats_destroy(ctx->stats);
            server_pool_deinit(&ctx->pool);
            conf_destroy(ctx->cf);
            nc_free(ctx);
            return NULL;
        }
    }

    /* initialize proxy per server pool */
    if (npool != 0) {
        status = proxy_init(ctx);
        if (status != NC_OK) {
            server_pool_disconnect(ctx);
            evbase_destroy(ctx->evb);
            stats_destroy(ctx->stats);
            server_pool_deinit(&ctx->pool);
            conf_destroy(ctx->cf);
            nc_free(ctx);
            return NULL;
        }
    }

    log_debug(LOG_VVERB, "created ctx %p id %"PRIu32"", ctx, ctx->id);

    return ctx;
}