From: Olivier Houchard Date: Wed, 29 Jul 2026 22:59:04 +0000 (+0200) Subject: MEDIUM: resolvers: Do not close another thread group's socket at deinit X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=c4bccd7ff2a0599343ff1274c2439bdb5d051ba8;p=thirdparty%2Fhaproxy.git 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. --- 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); }