]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: mworker/cli: create master CLI sockpair before fork
authorValentine Krasnobaeva <vkrasnobaeva@haproxy.com>
Thu, 3 Oct 2024 09:32:16 +0000 (11:32 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 16 Oct 2024 20:02:39 +0000 (22:02 +0200)
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.

src/cli.c
src/haproxy.c

index e60113d927c6b53d12a00c3b5bb524778f39c970..bbd11c1d12c3f23b02f76cfecc4fdc4dd20c6f87 100644 (file)
--- 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 <proc> 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) {
index 62e1732925b8fa4639cc85e7b4131158a83db201..e20f36052770fb573d1e8fc565891bbd8431fc48 100644 (file)
 #include <haproxy/peers.h>
 #include <haproxy/pool.h>
 #include <haproxy/protocol.h>
+#include <haproxy/proto_sockpair.h>
 #include <haproxy/proto_tcp.h>
 #include <haproxy/proxy.h>
 #include <haproxy/regex.h>
@@ -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);
        }