From: Valentine Krasnobaeva Date: Thu, 3 Oct 2024 09:32:16 +0000 (+0200) Subject: MINOR: mworker/cli: create master CLI sockpair before fork X-Git-Tag: v3.1-dev10~34 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6ec38c9a744fdba27961ceef16029402fff03697;p=thirdparty%2Fhaproxy.git MINOR: mworker/cli: create master CLI sockpair before fork The main idea here is to create a master CLI inherited sockpair just before the master-worker fork. And only then after the fork let each process to bind a needed listener to the its end of this sockpair. Like this master and worker processes can close unused "ends" of its sockpair copy (ipc_fd[0] for worker and and ipc_fd[1] for master). When this sockpair creation happens inside the mworker_cli_global_proxy_new_listener() is not possible for the master to close ipc_fd[1] bound to the GLOBAL proxy listener, as this triggers a BUG_ON(fd->owner) in fd_insert() in master context, because master process has alredy entered in its polling loop and poller in its turn tries to reused closed fd. --- diff --git a/src/cli.c b/src/cli.c index e60113d927..bbd11c1d12 100644 --- a/src/cli.c +++ b/src/cli.c @@ -3487,7 +3487,7 @@ err: } /* - * Creates a sockpair, a "master-socket" bind conf and a listener. Assigns + * Creates a "master-socket" bind conf and a listener. Assigns * this new listener to the one "end" of the given process sockpair in * order to have a new master CLI listening socket for this process. */ @@ -3498,12 +3498,6 @@ int mworker_cli_global_proxy_new_listener(struct mworker_proc *proc) char *path = NULL; char *err = NULL; - /* master pipe to ensure the master is still alive */ - if (socketpair(AF_UNIX, SOCK_STREAM, 0, proc->ipc_fd) < 0) { - ha_alert("Cannot create worker socketpair.\n"); - return -1; - } - /* XXX: we might want to use a separate frontend at some point */ if (!global.cli_fe) { if ((global.cli_fe = cli_alloc_fe("GLOBAL", "master-socket", 0)) == NULL) { diff --git a/src/haproxy.c b/src/haproxy.c index 62e1732925..e20f360527 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -109,6 +109,7 @@ #include #include #include +#include #include #include #include @@ -2096,8 +2097,18 @@ static void init(int argc, char **argv) } tmproc->options |= PROC_O_TYPE_WORKER; /* worker */ - if (mworker_cli_global_proxy_new_listener(tmproc) < 0) + /* create a sockpair to copy it via fork(), thus it will be in + * master and in worker processes + */ + if (socketpair(AF_UNIX, SOCK_STREAM, 0, tmproc->ipc_fd) < 0) { + ha_alert("Cannot create worker master CLI socketpair.\n"); + exit(EXIT_FAILURE); + } + if (mworker_cli_global_proxy_new_listener(tmproc) < 0) { + close(tmproc->ipc_fd[0]); + close(tmproc->ipc_fd[1]); exit(EXIT_FAILURE); + } LIST_APPEND(&proc_list, &tmproc->list); }