]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: mworker: create the mcli_reload socketpairs in case of upgrade
authorWilliam Lallemand <wlallemand@haproxy.org>
Wed, 7 Dec 2022 13:25:41 +0000 (14:25 +0100)
committerWilliam Lallemand <wlallemand@haproxy.org>
Wed, 7 Dec 2022 14:30:52 +0000 (15:30 +0100)
In ticket #1956, it was reported that an upgrade from 2.6 to 2.7 via a
reload would stop the master process.

When upgrading the binary, the new process is considered reexec and does
not try to creates the socketpair for the mcli_reload listener, then
tries to bind on -1 since the socket doesn't exit. The failure provokes
an exit() of the master.

This patch fixes the issue by trying to create the mcli_reload sockets
only when they don't exist, instead of creating them at first start.
This way we also avoid possible fd leak since we always try to use the
existing FDs first.

Must be backported in 2.7.

src/haproxy.c

index 072526175615a2d24d807165488c4bd0aa5e2e62..7e67f001cd0a7247e79b1fe4c7eafc5e4b02dec9 100644 (file)
@@ -2132,19 +2132,6 @@ static void init(int argc, char **argv)
                        tmproc->options |= PROC_O_TYPE_MASTER; /* master */
                        tmproc->pid = pid;
                        tmproc->timestamp = start_date.tv_sec;
-
-                       /* Creates the mcli_reload listener, which is the listener used
-                        * to retrieve the master CLI session which asked for the reload.
-                        *
-                        * ipc_fd[1] will be used as a listener, and ipc_fd[0]
-                        * will be used to send the FD of the session.
-                        *
-                        * Both FDs will be kept in the master.
-                        */
-                       if (socketpair(AF_UNIX, SOCK_STREAM, 0, tmproc->ipc_fd) < 0) {
-                               ha_alert("cannot create the mcli_reload socketpair.\n");
-                               exit(EXIT_FAILURE);
-                       }
                        proc_self = tmproc;
 
                        LIST_APPEND(&proc_list, &tmproc->list);
@@ -2199,6 +2186,21 @@ static void init(int argc, char **argv)
                                free(c->s);
                                free(c);
                        }
+                       /* Creates the mcli_reload listener, which is the listener used
+                        * to retrieve the master CLI session which asked for the reload.
+                        *
+                        * ipc_fd[1] will be used as a listener, and ipc_fd[0]
+                        * will be used to send the FD of the session.
+                        *
+                        * Both FDs will be kept in the master. The sockets are
+                        * created only if they weren't inherited.
+                        */
+                       if ((proc_self->ipc_fd[1] == -1) &&
+                            socketpair(AF_UNIX, SOCK_STREAM, 0, proc_self->ipc_fd) < 0) {
+                               ha_alert("cannot create the mcli_reload socketpair.\n");
+                               exit(EXIT_FAILURE);
+                       }
+
                        /* Create the mcli_reload listener from the proc_self struct */
                        memprintf(&path, "sockpair@%d", proc_self->ipc_fd[1]);
                        mcli_reload_bind_conf = mworker_cli_proxy_new_listener(path);