The motivation for this is to allow iteration of all the connections of a server without the expense of iterating over the global list of connections.
The first use of this will be to implement an option to close connections associated with a server when is is marked as being down or in maintenance mode. --- v3: Rename server element of stuct server to by_srv --- include/proto/session.h | 15 +++++++++++++++ include/types/server.h | 1 + include/types/session.h | 1 + src/cfgparse.c | 1 + src/peers.c | 2 +- src/proto_http.c | 2 +- src/queue.c | 3 ++- src/session.c | 6 +++--- 8 files changed, 25 insertions(+), 6 deletions(-) diff --git a/include/proto/session.h b/include/proto/session.h index c9195f6..a7055bf 100644 --- a/include/proto/session.h +++ b/include/proto/session.h @@ -225,6 +225,21 @@ static void inline session_inc_http_err_ctr(struct session *s) } } +static void inline session_add_srv_conn(struct session *sess, struct server *srv) +{ + sess->srv_conn = srv; + LIST_ADD(&srv->actconns, &sess->server); +} + +static void inline session_del_srv_conn(struct session *sess) +{ + if (!sess->srv_conn) + return; + + sess->srv_conn = NULL; + LIST_DEL(&sess->server); +} + #endif /* _PROTO_SESSION_H */ /* diff --git a/include/types/server.h b/include/types/server.h index fb31215..cf0a0df 100644 --- a/include/types/server.h +++ b/include/types/server.h @@ -101,6 +101,7 @@ struct server { struct srvcounters counters; /* statistics counters */ struct list pendconns; /* pending connections */ + struct list actconns; /* active connections */ struct task *check; /* the task associated to the health check processing */ struct sockaddr_storage addr; /* the address to connect to */ diff --git a/include/types/session.h b/include/types/session.h index 2ac2232..7fde0aa 100644 --- a/include/types/session.h +++ b/include/types/session.h @@ -157,6 +157,7 @@ enum { */ struct session { struct list list; /* position in global sessions list */ + struct list by_srv; /* position in server session list */ struct list back_refs; /* list of users tracking this session */ struct task *task; /* the task associated with this session */ /* application specific below */ diff --git a/src/cfgparse.c b/src/cfgparse.c index 40c46d5..9626e36 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -3921,6 +3921,7 @@ stats_error_parsing: newsrv->conf.file = file; newsrv->conf.line = linenum; + LIST_INIT(&newsrv->actconns); LIST_INIT(&newsrv->pendconns); do_check = 0; newsrv->state = SRV_RUNNING; /* early server setup */ diff --git a/src/peers.c b/src/peers.c index cdc8318..f253280 100644 --- a/src/peers.c +++ b/src/peers.c @@ -1185,7 +1185,7 @@ static struct session *peer_session_create(struct peer *peer, struct peer_sessio stream_sock_prepare_interface(&s->si[1]); s->si[1].release = NULL; - s->srv_conn = NULL; + session_del_srv_conn(s); clear_target(&s->target); s->pend_pos = NULL; diff --git a/src/proto_http.c b/src/proto_http.c index 69232f9..e4c80c1 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -7595,7 +7595,7 @@ void http_reset_txn(struct session *s) s->be = s->fe; s->logs.logwait = s->fe->to_log; - s->srv_conn = NULL; + session_del_srv_conn(s); clear_target(&s->target); /* re-init store persistence */ s->store_count = 0; diff --git a/src/queue.c b/src/queue.c index 48380fc..ea0bfb8 100644 --- a/src/queue.c +++ b/src/queue.c @@ -16,6 +16,7 @@ #include <proto/queue.h> #include <proto/server.h> +#include <proto/session.h> #include <proto/stream_interface.h> #include <proto/task.h> @@ -122,7 +123,7 @@ struct session *pendconn_get_next_sess(struct server *srv, struct proxy *px) /* we want to note that the session has now been assigned a server */ sess->flags |= SN_ASSIGNED; set_target_server(&sess->target, srv); - sess->srv_conn = srv; + session_add_srv_conn(sess, srv); srv->served++; if (px->lbprm.server_take_conn) px->lbprm.server_take_conn(srv); diff --git a/src/session.c b/src/session.c index f32ca9f..56d0c8f 100644 --- a/src/session.c +++ b/src/session.c @@ -201,7 +201,7 @@ int session_accept(struct listener *l, int cfd, struct sockaddr_storage *addr) if (likely(s->fe->options2 & PR_O2_INDEPSTR)) s->si[1].flags |= SI_FL_INDEP_STR; - s->srv_conn = NULL; + session_del_srv_conn(s); clear_target(&s->target); s->pend_pos = NULL; @@ -2140,14 +2140,14 @@ void sess_change_server(struct session *sess, struct server *newsrv) sess->srv_conn->served--; if (sess->srv_conn->proxy->lbprm.server_drop_conn) sess->srv_conn->proxy->lbprm.server_drop_conn(sess->srv_conn); - sess->srv_conn = NULL; + session_del_srv_conn(sess); } if (newsrv) { newsrv->served++; if (newsrv->proxy->lbprm.server_take_conn) newsrv->proxy->lbprm.server_take_conn(newsrv); - sess->srv_conn = newsrv; + session_add_srv_conn(sess, newsrv); } } -- 1.7.5.3