]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: mworker/cli: implement hard-reload over the master CLI
authorWilliam Lallemand <wlallemand@haproxy.com>
Fri, 24 Nov 2023 20:20:32 +0000 (21:20 +0100)
committerWilliam Lallemand <wlallemand@haproxy.com>
Fri, 24 Nov 2023 20:44:25 +0000 (21:44 +0100)
The mworker mode never had a proper 'hard-stop' (-st) for the reload,
this is a mode which was commonly used with the daemon mode, but it was
never implemented in mworker mode.

This patch fixes the problem by implementing a "hard-reload" command
over the master CLI. It does the same as the "reload" command, but
instead of waiting for the connections to stop in the previous process,
it immediately quits the previous process after binding.

doc/management.txt
include/haproxy/global.h
src/haproxy.c
src/mworker.c

index e052a019ea90f1132853f665f71331582d90a746..b8916b31c8bd79be5d85eab30044eb1007d65935 100644 (file)
@@ -4059,6 +4059,14 @@ experimental-mode [on|off]
 
   See also "experimental-mode" in Section 9.3 and "mcli-debug-mode" in 9.4.1.
 
+hard-reload
+  This command does the same as the "reload" command over the master CLI with
+  the expection that it does a hard-stop (-st) instead of a stop-stop (-sf) of
+  the previous process. This means the previous process does not wait to
+  achieve anything before exiting, so all connections will be closed.
+
+  See also the "reload" command.
+
 mcli-debug-mode [on|off]
   This keyword allows a special mode in the master CLI which enables every
   keywords that were meant for a worker CLI on the master CLI, allowing to debug
@@ -4128,6 +4136,7 @@ reload
   will close the connection to the CLI.
 
   Note that a reload will close all connections to the master CLI.
+  See also the "hard-reload" command.
 
 show proc
   The master CLI introduces a 'show proc' command to surpervise the
index 6eb3ad738c351907dcecbbd9b55ef48716618bc5..fd32109c92e0aa40c9a219fc82b4134478771fcc 100644 (file)
@@ -66,7 +66,7 @@ int compare_current_version(const char *version);
 void display_version();
 
 void mworker_accept_wrapper(int fd);
-void mworker_reload(void);
+void mworker_reload(int hardreload);
 
 /* to be used with warned and WARN_* */
 static inline int already_warned(unsigned int warning)
index a0f5d23e05a6feb13bb0c9417897beaad6aee692..900c897cd89c06b6822191f559f00864a08b8061 100644 (file)
@@ -686,7 +686,7 @@ int delete_oldpid(int pid)
  * When called, this function reexec haproxy with -sf followed by current
  * children PIDs and possibly old children PIDs if they didn't leave yet.
  */
-static void mworker_reexec()
+static void mworker_reexec(int hardreload)
 {
        char **next_argv = NULL;
        int old_argc = 0; /* previous number of argument */
@@ -749,7 +749,10 @@ static void mworker_reexec()
                if (mworker_child_nb() > 0) {
                        struct mworker_proc *child;
 
-                       next_argv[next_argc++] = "-sf";
+                       if (hardreload)
+                               next_argv[next_argc++] = "-st";
+                       else
+                               next_argv[next_argc++] = "-sf";
 
                        list_for_each_entry(child, &proc_list, list) {
                                if (!(child->options & PROC_O_LEAVING) && (child->options & PROC_O_TYPE_WORKER))
@@ -792,16 +795,16 @@ alloc_error:
 static void mworker_reexec_waitmode()
 {
        setenv("HAPROXY_MWORKER_WAIT_ONLY", "1", 1);
-       mworker_reexec();
+       mworker_reexec(0);
 }
 
 /* reload haproxy and emit a warning */
-void mworker_reload()
+void mworker_reload(int hardreload)
 {
        struct mworker_proc *child;
        struct per_thread_deinit_fct *ptdf;
 
-       ha_notice("Reloading HAProxy\n");
+       ha_notice("Reloading HAProxy%s\n", hardreload?" (hard-reload)":"");
 
        /* close the poller FD and the thread waker pipe FD */
        list_for_each_entry(ptdf, &per_thread_deinit_list, list)
@@ -816,7 +819,7 @@ void mworker_reload()
        if (global.tune.options & GTUNE_USE_SYSTEMD)
                sd_notify(0, "RELOADING=1\nSTATUS=Reloading Configuration.\n");
 #endif
-       mworker_reexec();
+       mworker_reexec(hardreload);
 }
 
 static void mworker_loop()
index b773bfe726631f9ed0dfa7514fbb75134b4f40c1..c71446ab8bf802ee5544ea36c4c98e2d6b741e82 100644 (file)
@@ -316,7 +316,7 @@ void mworker_broadcast_signal(struct sig_handler *sh)
  */
 void mworker_catch_sighup(struct sig_handler *sh)
 {
-       mworker_reload();
+       mworker_reload(0);
 }
 
 void mworker_catch_sigterm(struct sig_handler *sh)
@@ -685,10 +685,15 @@ static int cli_parse_reload(char **args, char *payload, struct appctx *appctx, v
        struct stream *strm = NULL;
        struct connection *conn = NULL;
        int fd = -1;
+       int hardreload = 0;
 
        if (!cli_has_level(appctx, ACCESS_LVL_OPER))
                return 1;
 
+       /* hard reload requested */
+       if (*args[0] == 'h')
+               hardreload = 1;
+
        /* This ask for a synchronous reload, which means we will keep this FD
           instead of closing it. */
 
@@ -704,7 +709,7 @@ static int cli_parse_reload(char **args, char *payload, struct appctx *appctx, v
        if (fd != -1 && send_fd_uxst(proc_self->ipc_fd[0], fd) == 0) {
                fd_delete(fd); /* avoid the leak of the FD after sending it via the socketpair */
        }
-       mworker_reload();
+       mworker_reload(hardreload);
 
        return 1;
 }
@@ -807,7 +812,8 @@ static struct cli_kw_list cli_kws = {{ },{
        { { "@!<pid>", NULL },         "@!<pid>                                 : send a command to the <pid> process", cli_parse_default, NULL, NULL, NULL, ACCESS_MASTER_ONLY},
        { { "@master", NULL },         "@master                                 : send a command to the master process", cli_parse_default, NULL, NULL, NULL, ACCESS_MASTER_ONLY},
        { { "show", "proc", NULL },    "show proc                               : show processes status", cli_parse_default, cli_io_handler_show_proc, NULL, NULL, ACCESS_MASTER_ONLY},
-       { { "reload", NULL },          "reload                                  : reload haproxy", cli_parse_reload, NULL, NULL, NULL, ACCESS_MASTER_ONLY},
+       { { "reload", NULL },          "reload                                  : achieve a soft-reload (-sf) of haproxy", cli_parse_reload, NULL, NULL, NULL, ACCESS_MASTER_ONLY},
+       { { "hard-reload", NULL },     "hard-reload                             : achieve a hard-reload (-st) of haproxy", cli_parse_reload, NULL, NULL, NULL, ACCESS_MASTER_ONLY},
        { { "_loadstatus", NULL },     NULL,                                                             cli_parse_default, cli_io_handler_show_loadstatus, NULL, NULL, ACCESS_MASTER_ONLY},
        {{},}
 }};