diff --git a/src/connection.c b/src/connection.c index be03b0d47..6dbca2c12 100644 --- a/src/connection.c +++ b/src/connection.c @@ -213,6 +213,13 @@ int conn_notify_mux(struct connection *conn, int old_flags, int forced_wake) goto done; if (conn_in_list) { + if (srv->cur_admin & SRV_ADMF_MAINT) { + /* Do not store an idle conn if server in maintenance. */ + conn->mux->destroy(conn->ctx); + ret = -1; + goto done; + } + HA_SPIN_LOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock); _srv_add_idle(srv, conn, conn_in_list == CO_FL_SAFE_LIST); HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock); diff --git a/src/mux_fcgi.c b/src/mux_fcgi.c index 0b143b893..949ef19c1 100644 --- a/src/mux_fcgi.c +++ b/src/mux_fcgi.c @@ -3091,11 +3091,21 @@ struct task *fcgi_io_cb(struct task *t, void *ctx, unsigned int state) if (!ret && conn_in_list) { struct server *srv = __objt_server(conn->target); - HA_SPIN_LOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock); - _srv_add_idle(srv, conn, conn_in_list == CO_FL_SAFE_LIST); - HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock); + if (!(srv->cur_admin & SRV_ADMF_MAINT)) { + HA_SPIN_LOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock); + _srv_add_idle(srv, conn, conn_in_list == CO_FL_SAFE_LIST); + HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock); + } + else { + /* Do not store an idle conn if server in maintenance. */ + goto release; + } } return t; + + release: + fcgi_release(fconn); + return NULL; } /* callback called on any event by the connection handler. diff --git a/src/mux_h1.c b/src/mux_h1.c index a8a6efa93..8aeec3931 100644 --- a/src/mux_h1.c +++ b/src/mux_h1.c @@ -4328,11 +4328,21 @@ struct task *h1_io_cb(struct task *t, void *ctx, unsigned int state) if (!ret && conn_in_list) { struct server *srv = __objt_server(conn->target); - HA_SPIN_LOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock); - _srv_add_idle(srv, conn, conn_in_list == CO_FL_SAFE_LIST); - HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock); + if (!(srv->cur_admin & SRV_ADMF_MAINT)) { + HA_SPIN_LOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock); + _srv_add_idle(srv, conn, conn_in_list == CO_FL_SAFE_LIST); + HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock); + } + else { + /* Do not store an idle conn if server in maintenance. */ + goto release; + } } return t; + + release: + h1_release(h1c); + return NULL; } static int h1_wake(struct connection *conn) diff --git a/src/mux_h2.c b/src/mux_h2.c index 9ae45d261..bf678e26e 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -4995,14 +4995,25 @@ struct task *h2_io_cb(struct task *t, void *ctx, unsigned int state) if (!ret && conn_in_list) { struct server *srv = __objt_server(conn->target); - HA_SPIN_LOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock); - _srv_add_idle(srv, conn, conn_in_list == CO_FL_SAFE_LIST); - HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock); + if (!(srv->cur_admin & SRV_ADMF_MAINT)) { + HA_SPIN_LOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock); + _srv_add_idle(srv, conn, conn_in_list == CO_FL_SAFE_LIST); + HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock); + } + else { + /* Do not store an idle conn if server in maintenance. */ + goto release; + } } -leave: + leave: TRACE_LEAVE(H2_EV_H2C_WAKE); return t; + + release: + TRACE_LEAVE(H2_EV_H2C_WAKE); + h2_release(h2c); + return NULL; } /* callback called on any event by the connection handler. diff --git a/src/mux_spop.c b/src/mux_spop.c index 95000e02b..77ee3a242 100644 --- a/src/mux_spop.c +++ b/src/mux_spop.c @@ -2587,11 +2587,21 @@ static struct task *spop_io_cb(struct task *t, void *ctx, unsigned int state) if (!ret && conn_in_list) { struct server *srv = __objt_server(conn->target); - HA_SPIN_LOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock); - _srv_add_idle(srv, conn, conn_in_list == CO_FL_SAFE_LIST); - HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock); + if (!(srv->cur_admin & SRV_ADMF_MAINT)) { + HA_SPIN_LOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock); + _srv_add_idle(srv, conn, conn_in_list == CO_FL_SAFE_LIST); + HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock); + } + else { + /* Do not store an idle conn if server in maintenance. */ + goto release; + } } return t; + + release: + spop_release(spop_conn); + return NULL; } /* callback called on any event by the connection handler. diff --git a/src/server.c b/src/server.c index b469b7ca8..d736362f7 100644 --- a/src/server.c +++ b/src/server.c @@ -7327,6 +7327,7 @@ int srv_add_to_idle_list(struct server *srv, struct connection *conn, int is_saf */ if (!(conn->flags & CO_FL_PRIVATE) && srv && srv->pool_purge_delay > 0 && + !(srv->cur_admin & SRV_ADMF_MAINT) && ((srv->proxy->options & PR_O_REUSE_MASK) != PR_O_REUSE_NEVR) && ha_used_fds < global.tune.pool_high_count && (srv->max_idle_conns == -1 || srv->max_idle_conns > srv->curr_idle_conns) && diff --git a/src/ssl_sock.c b/src/ssl_sock.c index fc4e5a602..9342bd6d1 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -6478,12 +6478,22 @@ struct task *ssl_sock_io_cb(struct task *t, void *context, unsigned int state) #endif leave: if (!ret && conn_in_list) { - struct server *srv = objt_server(conn->target); + struct server *srv = __objt_server(conn->target); - TRACE_DEVEL("adding conn back to idle list", SSL_EV_CONN_IO_CB, conn); - HA_SPIN_LOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock); - _srv_add_idle(srv, conn, conn_in_list == CO_FL_SAFE_LIST); - HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock); + if (!(srv->cur_admin & SRV_ADMF_MAINT)) { + TRACE_DEVEL("adding conn back to idle list", SSL_EV_CONN_IO_CB, conn); + HA_SPIN_LOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock); + _srv_add_idle(srv, conn, conn_in_list == CO_FL_SAFE_LIST); + HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock); + } + else { + /* Do not store an idle conn if server in maintenance. */ + + /* Connection is idle which means MUX layer is already initialized. */ + BUG_ON(!conn->mux); + conn->mux->destroy(conn->ctx); + t = NULL; + } } TRACE_LEAVE(SSL_EV_CONN_IO_CB, conn); return t;