]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: mworker: mworker_catch_sigchld: use fd_delete instead of close
authorValentine Krasnobaeva <vkrasnobaeva@haproxy.com>
Fri, 4 Oct 2024 08:59:06 +0000 (10:59 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 16 Oct 2024 20:02:39 +0000 (22:02 +0200)
If the worker exits due to failure or due to receiving TERM signal, in the
master context, we can't now simply close the master's fd (ipc_fd[0]) of
the inherited master CLI sockpair.

When the worker is created, in the master process context MASTER proxy listener
is bound to ipc_fd[0]. When this worker fails or exits, master process is
always in its polling loop. So, closing some fd in its context immediately
triggers the BUG_ON(fd->owner), as the poller try to reinsert the "freed" fd
into fdtab and try to reuse it. We must call fd_delete in this case. This will
deinitializes fd auxilary data and closes its properly.

src/mworker.c

index 967bf7cfaee47765f307c44662acc49af5de7d7d..53aaf4bdb5aaf25e0eadaac4b1a90da22faec82d 100644 (file)
@@ -365,7 +365,6 @@ restart_wait:
                                continue;
 
                        LIST_DELETE(&child->list);
-                       close(child->ipc_fd[0]);
                        childfound = 1;
                        break;
                }
@@ -377,6 +376,7 @@ restart_wait:
                        /* check if exited child is a current child */
                        if (!(child->options & PROC_O_LEAVING)) {
                                if (child->options & PROC_O_TYPE_WORKER) {
+                                       fd_delete(child->ipc_fd[0]);
                                        if (status < 128)
                                                ha_warning("Current worker (%d) exited with code %d (%s)\n", exitpid, status, "Exit");
                                        else
@@ -399,6 +399,7 @@ restart_wait:
                                if (exitcode < 0 && status != 0 && status != 143)
                                        exitcode = status;
                        } else {
+                               fd_delete(child->ipc_fd[0]);
                                if (child->options & PROC_O_TYPE_WORKER) {
                                        ha_warning("Former worker (%d) exited with code %d (%s)\n", exitpid, status, (status >= 128) ? strsignal(status - 128) : "Exit");
                                        delete_oldpid(exitpid);