From: Arran Cudbard-Bell Date: Tue, 5 Mar 2019 10:06:59 +0000 (+0800) Subject: Split the initial spawning phase out of the pool init phase X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=358ccf0eccbb8bef1ce98a668d7482da72e44652;p=thirdparty%2Ffreeradius-server.git Split the initial spawning phase out of the pool init phase The pool now has additional configuration functions that might need to be called before it starts spawning connections --- diff --git a/src/lib/redis/cluster.c b/src/lib/redis/cluster.c index a80a2a8288a..cc811dda907 100644 --- a/src/lib/redis/cluster.c +++ b/src/lib/redis/cluster.c @@ -407,6 +407,8 @@ static cluster_rcode_t cluster_node_connect(fr_redis_cluster_t *cluster, fr_redi fr_pair_list_free(&args); } + if (fr_pool_start(node->pool) < 0) goto error; + return CLUSTER_OP_SUCCESS; } @@ -2375,7 +2377,7 @@ fr_redis_cluster_t *fr_redis_cluster_alloc(TALLOC_CTX *ctx, /* * Only get cluster map config if required */ - if (fr_pool_start(node->pool) > 0) { + if (fr_pool_start_num(node->pool) > 0) { /* * Fine to leave this node configured, if we do find * a live node, and it's not in the map, it'll be cleared out. diff --git a/src/lib/server/module.c b/src/lib/server/module.c index ed3eb40ecdc..20fd69b25d7 100644 --- a/src/lib/server/module.c +++ b/src/lib/server/module.c @@ -305,6 +305,11 @@ fr_pool_t *module_connection_pool_init(CONF_SECTION *module, fr_pool_enable_triggers(pool, trigger_prefix, trigger_args); + if (fr_pool_start(pool) < 0) { + ERROR("%s: Starting initial connections failed", log_prefix); + return -1; + } + DEBUG4("%s: Adding pool reference %p to config item \"%s.pool\"", log_prefix, pool, parent_name(cs)); cf_data_add(cs, pool, NULL, false); return pool; diff --git a/src/lib/server/pool.c b/src/lib/server/pool.c index 9a7987238b5..afa177a362b 100644 --- a/src/lib/server/pool.c +++ b/src/lib/server/pool.c @@ -35,6 +35,8 @@ RCSID("$Id$") #include #include +#include + typedef struct fr_pool_connection_s fr_pool_connection_t; static int connection_check(fr_pool_t *pool, REQUEST *request); @@ -948,26 +950,16 @@ fr_pool_t *fr_pool_init(TALLOC_CTX *ctx, fr_pool_connection_create_t c, fr_pool_connection_alive_t a, char const *log_prefix) { - uint32_t i; - fr_pool_t *pool = NULL; - fr_pool_connection_t *this; - time_t now; + fr_pool_t *pool = NULL; if (!cs || !opaque || !c) return NULL; - now = time(NULL); - /* * Pool is allocated in the NULL context as * threads are likely to allocate memory * beneath the pool. */ - pool = talloc_zero(NULL, fr_pool_t); - if (!pool) { - /* Simply using ERROR here results in a null pointer dereference */ - fr_log(&default_log, L_ERR, "%s: Out of memory", __FUNCTION__); - return NULL; - } + MEM(pool = talloc_zero(NULL, fr_pool_t)); /* * Ensure the pool is freed at the same time @@ -1030,8 +1022,9 @@ fr_pool_t *fr_pool_init(TALLOC_CTX *ctx, } if (!pool->heap) { ERROR("%s: Failed creating connection heap", __FUNCTION__); - talloc_free(pool); - return NULL; + error: + fr_pool_free(pool); + return -1; } pool->log_prefix = log_prefix ? talloc_typed_strdup(pool, log_prefix) : "core"; @@ -1098,24 +1091,33 @@ fr_pool_t *fr_pool_init(TALLOC_CTX *ctx, return pool; } + return pool; +} + +int fr_pool_start(fr_pool_t *pool) +{ + uint32_t i; + fr_pool_connection_t *this; + /* * Create all of the connections, unless the admin says * not to. */ for (i = 0; i < pool->start; i++) { - this = connection_spawn(pool, NULL, now, false, true); + /* + * Call time() once for each spawn attempt as there + * could be a significant delay. + */ + this = connection_spawn(pool, NULL, time(NULL), false, true); if (!this) { ERROR("Failed spawning initial connections"); - error: - /* coverity[missing_unlock] */ - fr_pool_free(pool); - return NULL; + return -1; } } fr_pool_trigger_exec(pool, NULL, "start"); - return pool; + return 0; } /** Allocate a new pool using an existing one as a template @@ -1164,7 +1166,7 @@ struct timeval fr_pool_timeout(fr_pool_t *pool) * @param[in] pool to get connection start for. * @return the connection start value configured for the pool. */ -int fr_pool_start(fr_pool_t *pool) +int fr_pool_start_num(fr_pool_t *pool) { return pool->start; } diff --git a/src/lib/server/pool.h b/src/lib/server/pool.h index cbe5df44e9b..ecafc63d72d 100644 --- a/src/lib/server/pool.h +++ b/src/lib/server/pool.h @@ -138,6 +138,7 @@ fr_pool_t *fr_pool_init(TALLOC_CTX *ctx, fr_pool_connection_create_t c, fr_pool_connection_alive_t a, char const *log_prefix); +int fr_pool_start(fr_pool_t *pool); fr_pool_t *fr_pool_copy(TALLOC_CTX *ctx, fr_pool_t *pool, void *opaque); @@ -150,7 +151,7 @@ void fr_pool_enable_triggers(fr_pool_t *pool, struct timeval fr_pool_timeout(fr_pool_t *pool); -int fr_pool_start(fr_pool_t *pool); +int fr_pool_start_num(fr_pool_t *pool); void const *fr_pool_opaque(fr_pool_t *pool); diff --git a/src/modules/rlm_rest/rlm_rest.c b/src/modules/rlm_rest/rlm_rest.c index 1da89c11622..1bea094bf77 100644 --- a/src/modules/rlm_rest/rlm_rest.c +++ b/src/modules/rlm_rest/rlm_rest.c @@ -998,6 +998,11 @@ static int mod_thread_instantiate(CONF_SECTION const *conf, void *instance, fr_e return -1; } + if (fr_pool_start(t->pool) < 0) { + ERROR("Starting initial connections failed"); + return -1; + } + return rest_io_init(t, inst->multiplex); }