From: Valentine Krasnobaeva Date: Fri, 4 Oct 2024 08:59:06 +0000 (+0200) Subject: MINOR: mworker: mworker_catch_sigchld: use fd_delete instead of close X-Git-Tag: v3.1-dev10~30 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9b27f82da3cc406dd3935cb106802c2fa4f5ba9e;p=thirdparty%2Fhaproxy.git MINOR: mworker: mworker_catch_sigchld: use fd_delete instead of close 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. --- diff --git a/src/mworker.c b/src/mworker.c index 967bf7cfae..53aaf4bdb5 100644 --- a/src/mworker.c +++ b/src/mworker.c @@ -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);