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.
This commit is contained in:
Valentine Krasnobaeva 2024-10-03 11:32:16 +02:00 committed by Willy Tarreau
parent cc1a631beb
commit 6ec38c9a74
2 changed files with 13 additions and 8 deletions

View File

@ -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) {

View File

@ -109,6 +109,7 @@
#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);
}