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.
diff --git a/include/proto/server.h b/include/proto/server.h
index 7aa09e4..fa36e8d 100644
--- a/include/proto/server.h
+++ b/include/proto/server.h
@@ -58,6 +58,7 @@
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 44eac17..1afb49c 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -3553,9 +3553,9 @@
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 @@
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 86137f3..312aa19 100644
--- a/src/server.c
+++ b/src/server.c
@@ -50,7 +50,6 @@
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 @@
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 @@
/* 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 @@
*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;