From: Valentine Krasnobaeva Date: Thu, 3 Oct 2024 09:44:04 +0000 (+0200) Subject: MEDIUM: mworker/cli: close child and parent fds, setup listeners X-Git-Tag: v3.1-dev10~31 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cf150fd73d5ee139d07e5200d4ddef4ebc33a6e2;p=thirdparty%2Fhaproxy.git MEDIUM: mworker/cli: close child and parent fds, setup listeners Basically, this is the continuation of the previous commits. So, here after the fork, worker process closes the "master" end of the copied CLI sockpair and binds its end, ipc_fd[1], to the GLOBAL proxy listener. mworker_cli_global_proxy_new_listener() guarantees that GLOBAL proxy will be created, if it wasn't the case before. Master process, at first, allocates the MASTER proxy, creates master CLI listener (-S command line option) and reload sockpair and then closes the "worker" end of the copied CLI sockpair and binds its end, ipc_fd[0], to the created MASTER proxy. Usage of the new PROC_O_INIT state helps to reduce test conditions to find the newly forked worker. --- diff --git a/src/haproxy.c b/src/haproxy.c index c6107e0dae..8d69ead64e 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -2104,11 +2104,6 @@ static void init(int argc, char **argv) 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); } @@ -2158,6 +2153,7 @@ static void init(int argc, char **argv) int worker_pid; struct mworker_proc *child; struct ring *tmp_startup_logs = NULL; + char *sock_name = NULL; worker_pid = fork(); switch (worker_pid) { @@ -2176,41 +2172,34 @@ static void init(int argc, char **argv) /* This one must not be exported, it's internal! */ unsetenv("HAPROXY_MWORKER_REEXEC"); ha_random_jump96(1); - /* proc_self needs to point to the new forked worker in - * worker's context, as it's dereferenced in - * mworker_sockpair_register_per_thread(), called for - * master and for worker. - */ + list_for_each_entry(child, &proc_list, list) { - if (child->options & PROC_O_TYPE_WORKER && - child->reloads == 0 && - child->pid == -1) { + if ((child->options & PROC_O_TYPE_WORKER) && (child->options & PROC_O_INIT)) { + close(child->ipc_fd[0]); + child->ipc_fd[0] = -1; + /* proc_self needs to point to the new forked worker in + * worker's context, as it's dereferenced in + * mworker_sockpair_register_per_thread(), called for + * master and for worker. + */ proc_self = child; + /* attach listener to GLOBAL proxy on child->ipc_fd[1] */ + if (mworker_cli_global_proxy_new_listener(child) < 0) { + close(child->ipc_fd[1]); + exit(EXIT_FAILURE); + } + break; } } - break; default: /* in parent */ + ha_notice("Initializing new worker (%d)\n", worker_pid); master = 1; atexit_flag = 1; atexit(exit_on_failure); - ha_notice("Initializing new worker (%d)\n", worker_pid); - /* find the right mworker_proc */ - list_for_each_entry(child, &proc_list, list) { - if (child->reloads == 0 && child->options & PROC_O_TYPE_WORKER && child->pid == -1) { - child->timestamp = date.tv_sec; - child->pid = worker_pid; - child->version = strdup(haproxy_version); - /* at this step the fd is bound for the worker, set it to -1 so - * it could be close in case of errors in mworker_cleanup_proc() */ - child->ipc_fd[1] = -1; - - break; - } - } /* in exec mode, there's always exactly one thread. Failure to * set these ones now will result in nbthread being detected * automatically. @@ -2226,6 +2215,28 @@ static void init(int argc, char **argv) /* creates reload sockpair and listeners for master CLI (-S) */ mworker_create_master_cli(); + + /* find the right mworker_proc */ + list_for_each_entry(child, &proc_list, list) { + if ((child->options & PROC_O_TYPE_WORKER) && (child->options & PROC_O_INIT)) { + child->timestamp = date.tv_sec; + child->pid = worker_pid; + child->version = strdup(haproxy_version); + + close(child->ipc_fd[1]); + child->ipc_fd[1] = -1; + + /* attach listener to MASTER proxy on child->ipc_fd[0] */ + memprintf(&sock_name, "sockpair@%d", child->ipc_fd[0]); + if (mworker_cli_master_proxy_new_listener(sock_name) == NULL) { + ha_free(&sock_name); + exit(EXIT_FAILURE); + } + ha_free(&sock_name); + + break; + } + } } }