From: Willy Tarreau Date: Thu, 7 Feb 2019 13:46:29 +0000 (+0100) Subject: BUG/MEDIUM: server: initialize the idle conns list after parsing the config X-Git-Tag: v2.0-dev1~54 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=835daa119e75a54689375da9c77e5d0e6bd7362f;p=thirdparty%2Fhaproxy.git 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 3ed58f3930..44eac17d68 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -3543,6 +3543,31 @@ out_uri_auth_compat: /* 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 50325de41c..86137f3e5c 100644 --- a/src/server.c +++ b/src/server.c @@ -1713,7 +1713,6 @@ static void srv_settings_cpy(struct server *srv, struct server *src, int srv_tmp struct server *new_server(struct proxy *proxy) { struct server *srv; - int i; srv = calloc(1, sizeof *srv); if (!srv) @@ -1724,19 +1723,6 @@ struct server *new_server(struct proxy *proxy) 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 @@ struct server *new_server(struct proxy *proxy) 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; } /*