From 980855bd953c1507ae479bf1262d4ef984830066 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Thu, 7 Feb 2019 14:59:29 +0100 Subject: [PATCH] BUG/MEDIUM: server: initialize the orphaned conns lists and tasks at the end This also depends on the nbthread count, so it must only be performed after parsing the whole config file. As a side effect, this removes some code duplication between servers and server-templates. This must be backported to 1.9. --- include/proto/server.h | 1 + src/cfgparse.c | 27 ++++++++++++++++++++++++--- src/server.c | 40 +--------------------------------------- 3 files changed, 26 insertions(+), 42 deletions(-) diff --git a/include/proto/server.h b/include/proto/server.h index 7aa09e4d9b..fa36e8deb9 100644 --- a/include/proto/server.h +++ b/include/proto/server.h @@ -58,6 +58,7 @@ const char *update_server_fqdn(struct server *server, const char *fqdn, const ch int snr_resolution_cb(struct dns_requester *requester, struct dns_nameserver *nameserver); int snr_resolution_error_cb(struct dns_requester *requester, int error_code); struct server *snr_check_ip_callback(struct server *srv, void *ip, unsigned char *ip_family); +struct task *srv_cleanup_idle_connections(struct task *task, void *ctx, unsigned short state); /* increase the number of cumulated connections on the designated server */ static void inline srv_inc_sess_ctr(struct server *s) diff --git a/src/cfgparse.c b/src/cfgparse.c index 44eac17d68..1afb49c89a 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -3553,9 +3553,9 @@ out_uri_auth_compat: newsrv->safe_conns = calloc(global.nbthread, sizeof(*newsrv->safe_conns)); if (!newsrv->priv_conns || !newsrv->idle_conns || !newsrv->safe_conns) { - free(srv->safe_conns); srv->safe_conns = NULL; - free(srv->idle_conns); srv->idle_conns = NULL; - free(srv->priv_conns); srv->priv_conns = NULL; + free(newsrv->safe_conns); newsrv->safe_conns = NULL; + free(newsrv->idle_conns); newsrv->idle_conns = NULL; + free(newsrv->priv_conns); newsrv->priv_conns = NULL; ha_alert("parsing [%s:%d] : failed to allocate idle connections for server '%s'.\n", newsrv->conf.file, newsrv->conf.line, newsrv->id); cfgerr++; @@ -3567,6 +3567,27 @@ out_uri_auth_compat: LIST_INIT(&newsrv->idle_conns[i]); LIST_INIT(&newsrv->safe_conns[i]); } + + if (newsrv->max_idle_conns != 0) { + newsrv->idle_orphan_conns = calloc(global.nbthread, sizeof(*newsrv->idle_orphan_conns)); + newsrv->idle_task = calloc(global.nbthread, sizeof(*newsrv->idle_task)); + if (!newsrv->idle_orphan_conns || !newsrv->idle_task) + goto err; + for (i = 0; i < global.nbthread; i++) { + LIST_INIT(&newsrv->idle_orphan_conns[i]); + newsrv->idle_task[i] = task_new(1 << i); + if (!newsrv->idle_task[i]) + goto err; + newsrv->idle_task[i]->process = srv_cleanup_idle_connections; + newsrv->idle_task[i]->context = newsrv; + } + continue; + err: + ha_alert("parsing [%s:%d] : failed to allocate idle connection tasks for server '%s'.\n", + newsrv->conf.file, newsrv->conf.line, newsrv->id); + cfgerr++; + continue; + } } } diff --git a/src/server.c b/src/server.c index 86137f3e5c..312aa1994c 100644 --- a/src/server.c +++ b/src/server.c @@ -50,7 +50,6 @@ static void srv_update_status(struct server *s); static void srv_update_state(struct server *srv, int version, char **params); static int srv_apply_lastaddr(struct server *srv, int *err_code); static int srv_set_fqdn(struct server *srv, const char *fqdn, int dns_locked); -static struct task *cleanup_idle_connections(struct task *task, void *ctx, unsigned short state); /* List head of all known server keywords */ static struct srv_kw_list srv_keywords = { @@ -1938,25 +1937,6 @@ static int server_finalize_init(const char *file, int linenum, char **args, int px->srv_act++; srv_lb_commit_status(srv); - if (srv->max_idle_conns != 0) { - int i; - - srv->idle_orphan_conns = calloc(global.nbthread, sizeof(*srv->idle_orphan_conns)); - if (!srv->idle_orphan_conns) - goto err; - srv->idle_task = calloc(global.nbthread, sizeof(*srv->idle_task)); - if (!srv->idle_task) - goto err; - for (i = 0; i < global.nbthread; i++) { - LIST_INIT(&srv->idle_orphan_conns[i]); - srv->idle_task[i] = task_new(1 << i); - if (!srv->idle_task[i]) - goto err; - srv->idle_task[i]->process = cleanup_idle_connections; - srv->idle_task[i]->context = srv; - } - } - return 0; err: return ERR_ALERT | ERR_FATAL; @@ -2043,24 +2023,6 @@ static int server_template_init(struct server *srv, struct proxy *px) /* Linked backwards first. This will be restablished after parsing. */ newsrv->next = px->srv; px->srv = newsrv; - if (newsrv->max_idle_conns != 0) { - int i; - - newsrv->idle_orphan_conns = calloc(global.nbthread, sizeof(*newsrv->idle_orphan_conns)); - if (!newsrv->idle_orphan_conns) - goto err; - newsrv->idle_task = calloc(global.nbthread, sizeof(*newsrv->idle_task)); - if (!newsrv->idle_task) - goto err; - for (i = 0; i < global.nbthread; i++) { - LIST_INIT(&newsrv->idle_orphan_conns[i]); - newsrv->idle_task[i] = task_new(1 << i); - if (!newsrv->idle_task[i]) - goto err; - newsrv->idle_task[i]->process = cleanup_idle_connections; - newsrv->idle_task[i]->context = newsrv; - } - } } srv_set_id_from_prefix(srv, srv->tmpl_info.prefix, srv->tmpl_info.nb_low); @@ -5343,7 +5305,7 @@ static void srv_update_status(struct server *s) *s->adm_st_chg_cause = 0; } -static struct task *cleanup_idle_connections(struct task *task, void *context, unsigned short state) +struct task *srv_cleanup_idle_connections(struct task *task, void *context, unsigned short state) { struct server *srv = context; struct connection *conn, *conn_back; -- 2.39.5