From c4bccd7ff2a0599343ff1274c2439bdb5d051ba8 Mon Sep 17 00:00:00 2001 From: Olivier Houchard Date: Thu, 30 Jul 2026 00:59:04 +0200 Subject: [PATCH] MEDIUM: resolvers: Do not close another thread group's socket at deinit resolvers_destroy() runs at deinit, on the last remaining thread, and closes the UDP nameserver sockets, which were created by the thread their resolvers section's task was pinned to. With per-thread-group FD tables, when that thread belongs to another group, its group's FD table died with its last thread and already closed the socket, and the stored number is only meaningful in that table, closing it from here would actually close whatever FD carries the same number in this thread's own table. So in that case, leave the FD alone. --- src/resolvers.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/resolvers.c b/src/resolvers.c index 6a2467564..706882767 100644 --- a/src/resolvers.c +++ b/src/resolvers.c @@ -2680,7 +2680,16 @@ static void resolvers_destroy(struct resolvers *resolvers) free(ns->id); free((char *)ns->conf.file); if (ns->dgram) { - if (ns->dgram->conn.t.sock.fd != -1) { + /* with per-thread-group FD tables, the socket belongs + * to the group of the resolvers task's thread; if it + * is not ours, it was already closed by the kernel + * when the last thread of that group exited, and its + * number is not valid in this thread's tables. + */ + if (ns->dgram->conn.t.sock.fd != -1 && + (!(global.tune.options & GTUNE_NO_TG_FD_SHARING) || + (resolvers->t && + ha_thread_info[resolvers->t->tid].tgid == tgid))) { fd_delete(ns->dgram->conn.t.sock.fd); close(ns->dgram->conn.t.sock.fd); } -- 2.47.3