From 835daa119e75a54689375da9c77e5d0e6bd7362f Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Thu, 7 Feb 2019 14:46:29 +0100 Subject: [PATCH] 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. --- src/cfgparse.c | 25 +++++++++++++++++++++++++ src/server.c | 22 ---------------------- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/cfgparse.c b/src/cfgparse.c index 3ed58f393..44eac17d6 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -3543,6 +3543,31 @@ int check_config_validity() /* 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 50325de41..86137f3e5 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; } /*