]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: mux: prepare for takeover on private connections
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 20 Mar 2024 14:51:09 +0000 (15:51 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 22 Mar 2024 16:10:06 +0000 (17:10 +0100)
When a backend connection is marked as idle, a special flag TASK_F_USR1
is set on MUX tasklet. When MUX tasklet is reactivated, extra checks are
executed under this flag to ensure no takeover occurred in the meantime.

Previously, only non private connections could be targetted by a
takeover. However, this will change when implementing private idle
connections closure on "delete server" CLI handler. As such, TASK_F_USR1
is now also set for private connections in MUX detach callbacks.

src/mux_fcgi.c
src/mux_h1.c
src/mux_h2.c

index ebd3032cdd12e3a9fe9c30b0ba058b0ead1c59e1..617a9af9f34e4b6c13a648012d8a53ef74f3d511 100644 (file)
@@ -3581,6 +3581,10 @@ static void fcgi_detach(struct sedesc *sd)
                                }
                        }
                        if (eb_is_empty(&fconn->streams_by_id)) {
+                               /* mark that the tasklet may lose its context to another thread and
+                                * that the handler needs to check it under the idle conns lock.
+                                */
+                               HA_ATOMIC_OR(&fconn->wait_event.tasklet->state, TASK_F_USR1);
                                if (session_check_idle_conn(fconn->conn->owner, fconn->conn) != 0) {
                                        /* The connection is destroyed, let's leave */
                                        TRACE_DEVEL("outgoing connection killed", FCGI_EV_STRM_END|FCGI_EV_FCONN_ERR);
index 8e9ec78fd1b5241f1cfbb8220bccc43f9fd824a5..f26b4dc1c8a7b96e53e7497a35cb4e48ed28c40d 100644 (file)
@@ -1019,6 +1019,11 @@ static void h1s_finish_detach(struct h1s *h1s)
                                goto end;
                        }
                        /* Always idle at this step */
+
+                       /* mark that the tasklet may lose its context to another thread and
+                        * that the handler needs to check it under the idle conns lock.
+                        */
+                       HA_ATOMIC_OR(&h1c->wait_event.tasklet->state, TASK_F_USR1);
                        if (session_check_idle_conn(sess, h1c->conn)) {
                                /* The connection got destroyed, let's leave */
                                TRACE_DEVEL("outgoing connection killed", H1_EV_STRM_END|H1_EV_H1C_END);
index e829c49478ffcd47964e3eadaf04d4875b7b460a..c01f61dcd9aaf3d61518a67b553d878e1d399e5d 100644 (file)
@@ -4819,6 +4819,10 @@ static void h2_detach(struct sedesc *sd)
                                        }
                                }
                                if (eb_is_empty(&h2c->streams_by_id)) {
+                                       /* mark that the tasklet may lose its context to another thread and
+                                        * that the handler needs to check it under the idle conns lock.
+                                        */
+                                       HA_ATOMIC_OR(&h2c->wait_event.tasklet->state, TASK_F_USR1);
                                        if (session_check_idle_conn(h2c->conn->owner, h2c->conn) != 0) {
                                                /* At this point either the connection is destroyed, or it's been added to the server idle list, just stop */
                                                TRACE_DEVEL("leaving without reusable idle connection", H2_EV_STRM_END);