From 3500865bc112633b9c946a51be8f35f06fa4b2fc Mon Sep 17 00:00:00 2001 From: Valentine Krasnobaeva Date: Fri, 22 Nov 2024 23:42:17 +0100 Subject: [PATCH] REORG: startup: move mworker_apply_master_worker_mode in mworker.c mworker_apply_master_worker_mode() is called only in master-worker mode, so let's move it mworker.c --- include/haproxy/mworker.h | 1 + src/haproxy.c | 110 -------------------------------------- src/mworker.c | 110 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 110 deletions(-) diff --git a/include/haproxy/mworker.h b/include/haproxy/mworker.h index fbfcdd524426b..57d62643d000f 100644 --- a/include/haproxy/mworker.h +++ b/include/haproxy/mworker.h @@ -54,5 +54,6 @@ void mworker_create_master_cli(void); void mworker_prepare_master(void); void mworker_run_master(void); +void mworker_apply_master_worker_mode(void); #endif /* _HAPROXY_MWORKER_H_ */ diff --git a/src/haproxy.c b/src/haproxy.c index 4590ea364d27d..06eaf61ffac0f 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -1794,116 +1794,6 @@ static void handle_pidfile() DISGUISE(write(pidfd, pidstr, strlen(pidstr))); } -/* This function at first does master-worker fork. It creates then GLOBAL and - * MASTER proxies, allocates listeners for these proxies and binds a GLOBAL - * proxy listener in worker process on ipc_fd[1] and MASTER proxy listener - * in master process on ipc_fd[0]. ipc_fd[0] and ipc_fd[1] are the "ends" of the - * sockpair, created in prepare_master(). This sockpair is copied via fork to - * each process and serves as communication channel between master and worker - * (master CLI applet is attached in master process to MASTER proxy). This - * function returns only if everything is OK. If something fails, it exits. - */ -static void mworker_apply_master_worker_mode() -{ - int worker_pid; - struct mworker_proc *child; - char *sock_name = NULL; - char *errmsg = NULL; - - worker_pid = fork(); - switch (worker_pid) { - case -1: - ha_alert("[%s.main()] Cannot fork.\n", progname); - - exit(EXIT_FAILURE); - case 0: - /* This one must not be exported, it's internal! */ - unsetenv("HAPROXY_MWORKER_REEXEC"); - ha_random_jump96(1); - - list_for_each_entry(child, &proc_list, list) { - 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) - exit(EXIT_FAILURE); - - break; - } - - /* need to close reload sockpair fds, inherited after master's execvp and fork(), - * we can't close these fds in master before the fork(), as ipc_fd[1] serves after - * the mworker_reexec to obtain the MCLI client connection fd, like this we can - * write to this connection fd the content of the startup_logs ring. - */ - if (child->options & PROC_O_TYPE_MASTER) { - if (child->ipc_fd[0] > 0) - close(child->ipc_fd[0]); - if (child->ipc_fd[1] > 0) - close(child->ipc_fd[1]); - } - } - break; - default: - /* in parent */ - ha_notice("Initializing new worker (%d)\n", worker_pid); - master = 1; - - /* in exec mode, there's always exactly one thread. Failure to - * set these ones now will result in nbthread being detected - * automatically. - */ - global.nbtgroups = 1; - global.nbthread = 1; - - /* creates MASTER proxy */ - if (mworker_cli_create_master_proxy(&errmsg) < 0) { - ha_alert("Can't create MASTER proxy: %s\n", errmsg); - free(errmsg); - exit(EXIT_FAILURE); - } - - /* attaches servers to all existed workers on its shared MCLI sockpair ends, ipc_fd[0] */ - if (mworker_cli_attach_server(&errmsg) < 0) { - ha_alert("Can't attach servers needed for master CLI %s\n", errmsg ? errmsg : ""); - free(errmsg); - exit(EXIT_FAILURE); - } - - /* 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; - } - } - } -} - static void get_listeners_fd() { /* Try to get the listeners FD from the previous process using diff --git a/src/mworker.c b/src/mworker.c index 0d974468a8e20..a5ceff7077b66 100644 --- a/src/mworker.c +++ b/src/mworker.c @@ -1227,6 +1227,116 @@ void mworker_run_master(void) exit(0); } +/* This function at first does master-worker fork. It creates then GLOBAL and + * MASTER proxies, allocates listeners for these proxies and binds a GLOBAL + * proxy listener in worker process on ipc_fd[1] and MASTER proxy listener + * in master process on ipc_fd[0]. ipc_fd[0] and ipc_fd[1] are the "ends" of the + * sockpair, created in prepare_master(). This sockpair is copied via fork to + * each process and serves as communication channel between master and worker + * (master CLI applet is attached in master process to MASTER proxy). This + * function returns only if everything is OK. If something fails, it exits. + */ +void mworker_apply_master_worker_mode(void) +{ + int worker_pid; + struct mworker_proc *child; + char *sock_name = NULL; + char *errmsg = NULL; + + worker_pid = fork(); + switch (worker_pid) { + case -1: + ha_alert("[%s.main()] Cannot fork.\n", progname); + + exit(EXIT_FAILURE); + case 0: + /* This one must not be exported, it's internal! */ + unsetenv("HAPROXY_MWORKER_REEXEC"); + ha_random_jump96(1); + + list_for_each_entry(child, &proc_list, list) { + 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) + exit(EXIT_FAILURE); + + break; + } + + /* need to close reload sockpair fds, inherited after master's execvp and fork(), + * we can't close these fds in master before the fork(), as ipc_fd[1] serves after + * the mworker_reexec to obtain the MCLI client connection fd, like this we can + * write to this connection fd the content of the startup_logs ring. + */ + if (child->options & PROC_O_TYPE_MASTER) { + if (child->ipc_fd[0] > 0) + close(child->ipc_fd[0]); + if (child->ipc_fd[1] > 0) + close(child->ipc_fd[1]); + } + } + break; + default: + /* in parent */ + ha_notice("Initializing new worker (%d)\n", worker_pid); + master = 1; + + /* in exec mode, there's always exactly one thread. Failure to + * set these ones now will result in nbthread being detected + * automatically. + */ + global.nbtgroups = 1; + global.nbthread = 1; + + /* creates MASTER proxy */ + if (mworker_cli_create_master_proxy(&errmsg) < 0) { + ha_alert("Can't create MASTER proxy: %s\n", errmsg); + free(errmsg); + exit(EXIT_FAILURE); + } + + /* attaches servers to all existed workers on its shared MCLI sockpair ends, ipc_fd[0] */ + if (mworker_cli_attach_server(&errmsg) < 0) { + ha_alert("Can't attach servers needed for master CLI %s\n", errmsg ? errmsg : ""); + free(errmsg); + exit(EXIT_FAILURE); + } + + /* 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; + } + } + } +} + static struct cfg_kw_list mworker_kws = {{ }, { { CFG_GLOBAL, "mworker-max-reloads", mworker_parse_global_max_reloads, KWF_DISCOVERY }, { 0, NULL, NULL },