BUG/MEDIUM: server: initialize the idle conns list after parsing the config
The idle conns lists are sized according to the number of threads. As such
they cannot be initialized during the parsing since nbthread can be set
later, as revealed by this simple config which randomly crashes when used.
Let's do this at the end instead.
listen proxy
bind :4445
mode http
timeout client 10s
timeout server 10s
timeout connect 10s
http-reuse always
server s1 127.0.0.1:8000
global
nbthread 8
This fix must be backported to 1.9 and 1.8.
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 3ed58f3..44eac17 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -3543,6 +3543,31 @@
/* update the mux */
newsrv->mux_proto = mux_ent;
}
+
+ /* initialize idle conns lists */
+ for (newsrv = curproxy->srv; newsrv; newsrv = newsrv->next) {
+ int i;
+
+ newsrv->priv_conns = calloc(global.nbthread, sizeof(*newsrv->priv_conns));
+ newsrv->idle_conns = calloc(global.nbthread, sizeof(*newsrv->idle_conns));
+ 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;
+ ha_alert("parsing [%s:%d] : failed to allocate idle connections for server '%s'.\n",
+ newsrv->conf.file, newsrv->conf.line, newsrv->id);
+ cfgerr++;
+ continue;
+ }
+
+ for (i = 0; i < global.nbthread; i++) {
+ LIST_INIT(&newsrv->priv_conns[i]);
+ LIST_INIT(&newsrv->idle_conns[i]);
+ LIST_INIT(&newsrv->safe_conns[i]);
+ }
+ }
}
/***********************************************************/
diff --git a/src/server.c b/src/server.c
index 50325de..86137f3 100644
--- a/src/server.c
+++ b/src/server.c
@@ -1713,7 +1713,6 @@
struct server *new_server(struct proxy *proxy)
{
struct server *srv;
- int i;
srv = calloc(1, sizeof *srv);
if (!srv)
@@ -1724,19 +1723,6 @@
LIST_INIT(&srv->actconns);
srv->pendconns = EB_ROOT;
- if ((srv->priv_conns = calloc(global.nbthread, sizeof(*srv->priv_conns))) == NULL)
- goto free_srv;
- if ((srv->idle_conns = calloc(global.nbthread, sizeof(*srv->idle_conns))) == NULL)
- goto free_priv_conns;
- if ((srv->safe_conns = calloc(global.nbthread, sizeof(*srv->safe_conns))) == NULL)
- goto free_idle_conns;
-
- for (i = 0; i < global.nbthread; i++) {
- LIST_INIT(&srv->priv_conns[i]);
- LIST_INIT(&srv->idle_conns[i]);
- LIST_INIT(&srv->safe_conns[i]);
- }
-
srv->next_state = SRV_ST_RUNNING; /* early server setup */
srv->last_change = now.tv_sec;
@@ -1755,14 +1741,6 @@
srv->max_reuse = -1;
return srv;
-
- free_idle_conns:
- free(srv->idle_conns);
- free_priv_conns:
- free(srv->priv_conns);
- free_srv:
- free(srv);
- return NULL;
}
/*