]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: server: Do not close other thread groups' connections at deinit
authorOlivier Houchard <ohouchard@haproxy.com>
Wed, 29 Jul 2026 22:59:04 +0000 (00:59 +0200)
committerOlivier Houchard <cognet@ci0.org>
Thu, 30 Jul 2026 11:36:17 +0000 (13:36 +0200)
srv_close_idle_conns() runs at deinit, on the last remaining thread,
and closes the FDs of every thread's idle connections. With
per-thread-group FD tables, the connections of the other thread groups
were already closed by the kernel when the last thread of their group
exited, and their numbers are only meaningful in those groups' tables,
closing them from here would in fact close whatever FD carries the
same number in this thread's own table, and let sock_conn_ctrl_close()
rewrite an unrelated entry of this group's FD table. So in that case,
only release the memory and leave the FDs alone.

src/server.c

index ad7734c008208da995feea31344ec57d6f14046f..348679537833fffa6097661da0b44b0e4522b0fd 100644 (file)
@@ -7794,7 +7794,15 @@ static void srv_close_idle_conns(struct server *srv)
                for (cleaned_tree = conn_trees; *cleaned_tree; ++cleaned_tree) {
                        while ((conn = ceb64_item_first(*cleaned_tree, hash_node.node,
                                                        hash_node.key, struct connection))) {
-                               if (conn->ctrl->ctrl_close)
+                               /*
+                                * Make sure we only close our own fds. If the
+                                * connection was owned by another thread group,
+                                * it should be closed already as all those
+                                * threads exited already.
+                                */
+                               if (conn->ctrl->ctrl_close &&
+                                   (!(global.tune.options & GTUNE_NO_TG_FD_SHARING) ||
+                                    ha_thread_info[i].tgid == tgid))
                                        conn->ctrl->ctrl_close(conn);
                                conn_delete_from_tree(conn, i);
                        }