]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: mworker/cli: close child and parent fds, setup listeners
authorValentine Krasnobaeva <vkrasnobaeva@haproxy.com>
Thu, 3 Oct 2024 09:44:04 +0000 (11:44 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 16 Oct 2024 20:02:39 +0000 (22:02 +0200)
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.

src/haproxy.c

index c6107e0daef41bd029d170378a0fd892534c2e36..8d69ead64e7ccce23779376da191099641695d8a 100644 (file)
@@ -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;
+                               }
+                       }
                }
        }