mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-20 13:21:29 +02:00
MEDIUM: server: close new idle conns if server in maintenance
Currently, when a server is set on maintenance mode, its idle connection are scheduled for purge. However, this does not prevent currently used connection to become idle later on, even if the server is still off. Change this behavior : an idle connection is now rejected by the server if it is in maintenance. This is implemented with a new condition in srv_add_to_idle_list() which returns an error value. In this case, muxes stream detach callback will immediately free the connection. A similar change is also performed in each MUX and SSL I/O handlers and in conn_notify_mux(). An idle connection is not reinserted in its idle list if server is in maintenance, but instead it is immediately freed.
This commit is contained in:
parent
f234b40cde
commit
67df6577ff
@ -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);
|
||||
|
@ -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.
|
||||
|
16
src/mux_h1.c
16
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)
|
||||
|
19
src/mux_h2.c
19
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.
|
||||
|
@ -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.
|
||||
|
@ -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) &&
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user