From 2ab42dddc470c38348e9fac1b0cedef2bcce91aa Mon Sep 17 00:00:00 2001 From: William Lallemand Date: Fri, 26 Apr 2024 15:08:31 +0200 Subject: [PATCH] BUG/MINOR: mworker: reintroduce way to disable seamless reload with -x /dev/null Since the introduction of the automatic seamless reload using the internal socketpair, there is no way of disabling the seamless reload. Previously we just needed to remove -x from the startup command line, and remove any "expose-fd" keyword on stats socket lines. This was introduced in 2be557f7c ("MEDIUM: mworker: seamless reload use the internal sockpairs"). The patch copy /dev/null again and pass it to the next exec so we never try to get socket from the -x. Must be backported as far as 2.6. --- doc/management.txt | 15 ++++++++++----- src/haproxy.c | 14 ++++++++++++-- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/doc/management.txt b/doc/management.txt index 2fc8ea2e6..85f7f1364 100644 --- a/doc/management.txt +++ b/doc/management.txt @@ -471,11 +471,16 @@ list of options is : -x : connect to the specified socket and try to retrieve any listening sockets from the old process, and use them instead of trying to bind new ones. This is useful to avoid missing any new connection when - reloading the configuration on Linux. The capability must be enable on the - stats socket using "expose-fd listeners" in your configuration. - In master-worker mode, the master will use this option upon a reload with - the "sockpair@" syntax, which allows the master to connect directly to a - worker without using stats socket declared in the configuration. + reloading the configuration on Linux. + + Without master-worker mode, the capability must be enable on the stats + socket using "expose-fd listeners" in your configuration. + + In master-worker mode, it does not need "expose-fd listeners", the master + will use automatically this option upon a reload with the "sockpair@" + syntax, which allows the master to connect directly to a worker without using + any stats socket declared in the configuration. If you want to disable this, + you can pass -x /dev/null. A safe way to start HAProxy from an init file consists in forcing the daemon mode, storing existing pids to a pid file and using this pid file to notify diff --git a/src/haproxy.c b/src/haproxy.c index 411cd100e..38119ac92 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -721,6 +721,7 @@ static void mworker_reexec(int hardreload) char *msg = NULL; struct rlimit limit; struct mworker_proc *current_child = NULL; + int x_off = 0; /* disable -x by putting -x /dev/null */ mworker_block_signals(); setenv("HAPROXY_MWORKER_REEXEC", "1", 1); @@ -768,6 +769,10 @@ static void mworker_reexec(int hardreload) /* copy the program name */ next_argv[next_argc++] = old_argv[0]; + /* we need to reintroduce /dev/null everytime */ + if (old_unixsocket && strcmp(old_unixsocket, "/dev/null") == 0) + x_off = 1; + /* insert the new options just after argv[0] in case we have a -- */ if (getenv("HAPROXY_MWORKER_WAIT_ONLY") == NULL) { @@ -791,8 +796,7 @@ static void mworker_reexec(int hardreload) msg = NULL; } } - - if (current_child) { + if (!x_off && current_child) { /* add the -x option with the socketpair of the current worker */ next_argv[next_argc++] = "-x"; if ((next_argv[next_argc++] = memprintf(&msg, "sockpair@%d", current_child->ipc_fd[0])) == NULL) @@ -801,6 +805,12 @@ static void mworker_reexec(int hardreload) } } + if (x_off) { + /* if the cmdline contained a -x /dev/null, continue to use it */ + next_argv[next_argc++] = "-x"; + next_argv[next_argc++] = "/dev/null"; + } + /* copy the previous options */ for (i = 1; i < old_argc; i++) next_argv[next_argc++] = old_argv[i];