MEDIUM: mworker: Add systemd Type=notify
support
This patch adds support for `Type=notify` to the systemd unit. Supporting `Type=notify` improves both starting as well as reloading of the unit, because systemd will be let known when the action completed. See this quote from `systemd.service(5)`: > Note however that reloading a daemon by sending a signal (as with the > example line above) is usually not a good choice, because this is an > asynchronous operation and hence not suitable to order reloads of > multiple services against each other. It is strongly recommended to > set ExecReload= to a command that not only triggers a configuration > reload of the daemon, but also synchronously waits for it to complete. By making systemd aware of a reload in progress it is able to wait until the reload actually succeeded. This patch introduces both a new `USE_SYSTEMD` build option which controls including the sd-daemon library as well as a `-Ws` runtime option which runs haproxy in master-worker mode with systemd support. When haproxy is running in master-worker mode with systemd support it will send status messages to systemd using `sd_notify(3)` in the following cases: - The master process forked off the worker processes (READY=1) - The master process entered the `mworker_reload()` function (RELOADING=1) - The master process received the SIGUSR1 or SIGTERM signal (STOPPING=1) Change the unit file to specify `Type=notify` and replace master-worker mode (`-W`) with master-worker mode with systemd support (`-Ws`). Future evolutions of this feature could include making use of the `STATUS` feature of `sd_notify()` to send information about the number of active connections to systemd. This would require bidirectional communication between the master and the workers and thus is left for future work.
This commit is contained in:
parent
62dd698070
commit
d6942c8297
7
Makefile
7
Makefile
@ -43,6 +43,7 @@
|
||||
# USE_DEVICEATLAS : enable DeviceAtlas api.
|
||||
# USE_51DEGREES : enable third party device detection library from 51Degrees
|
||||
# USE_WURFL : enable WURFL detection library from Scientiamobile
|
||||
# USE_SYSTEMD : enable sd_notify() support.
|
||||
#
|
||||
# Options can be forced by specifying "USE_xxx=1" or can be disabled by using
|
||||
# "USE_xxx=" (empty string).
|
||||
@ -700,6 +701,12 @@ BUILD_OPTIONS += $(call ignore_implicit,USE_WURFL)
|
||||
OPTIONS_LDFLAGS += $(if $(WURFL_LIB),-L$(WURFL_LIB)) -lwurfl
|
||||
endif
|
||||
|
||||
ifneq ($(USE_SYSTEMD),)
|
||||
BUILD_OPTIONS += $(call ignore_implicit,USE_SYSTEMD)
|
||||
OPTIONS_CFLAGS += -DUSE_SYSTEMD
|
||||
OPTIONS_LDFLAGS += -lsystemd
|
||||
endif
|
||||
|
||||
ifneq ($(USE_PCRE)$(USE_STATIC_PCRE)$(USE_PCRE_JIT),)
|
||||
ifneq ($(USE_PCRE2)$(USE_STATIC_PCRE2)$(USE_PCRE2_JIT),)
|
||||
$(error cannot compile both PCRE and PCRE2 support)
|
||||
|
@ -7,12 +7,12 @@ After=network.target
|
||||
# socket if you want seamless reloads.
|
||||
Environment="CONFIG=/etc/haproxy/haproxy.cfg" "PIDFILE=/run/haproxy.pid"
|
||||
ExecStartPre=@SBINDIR@/haproxy -f $CONFIG -c -q
|
||||
ExecStart=@SBINDIR@/haproxy -W -f $CONFIG -p $PIDFILE
|
||||
ExecStart=@SBINDIR@/haproxy -Ws -f $CONFIG -p $PIDFILE
|
||||
ExecReload=@SBINDIR@/haproxy -f $CONFIG -c -q
|
||||
ExecReload=/bin/kill -USR2 $MAINPID
|
||||
KillMode=mixed
|
||||
Restart=always
|
||||
Type=forking
|
||||
Type=notify
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
@ -66,6 +66,7 @@
|
||||
|
||||
#define GTUNE_SOCKET_TRANSFER (1<<8)
|
||||
#define GTUNE_EXIT_ONFAILURE (1<<9)
|
||||
#define GTUNE_USE_SYSTEMD (1<<10)
|
||||
|
||||
/* Access level for a stats socket */
|
||||
#define ACCESS_LVL_NONE 0
|
||||
|
@ -61,6 +61,9 @@
|
||||
#ifdef DEBUG_FULL
|
||||
#include <assert.h>
|
||||
#endif
|
||||
#if defined(USE_SYSTEMD)
|
||||
#include <systemd/sd-daemon.h>
|
||||
#endif
|
||||
|
||||
#include <common/base64.h>
|
||||
#include <common/cfgparse.h>
|
||||
@ -404,6 +407,9 @@ static void usage(char *name)
|
||||
" -V enters verbose mode (disables quiet mode)\n"
|
||||
" -D goes daemon ; -C changes to <dir> before loading files.\n"
|
||||
" -W master-worker mode.\n"
|
||||
#if defined(USE_SYSTEMD)
|
||||
" -Ws master-worker mode with systemd notify support.\n"
|
||||
#endif
|
||||
" -q quiet mode : don't display messages\n"
|
||||
" -c check mode : only check config files and exit\n"
|
||||
" -n sets the maximum total # of connections (%d)\n"
|
||||
@ -635,6 +641,10 @@ static void mworker_reload()
|
||||
|
||||
mworker_block_signals();
|
||||
mworker_unregister_signals();
|
||||
#if defined(USE_SYSTEMD)
|
||||
if (global.tune.options & GTUNE_USE_SYSTEMD)
|
||||
sd_notify(0, "RELOADING=1");
|
||||
#endif
|
||||
setenv("HAPROXY_MWORKER_REEXEC", "1", 1);
|
||||
|
||||
/* compute length */
|
||||
@ -698,6 +708,11 @@ static void mworker_wait()
|
||||
|
||||
restart_wait:
|
||||
|
||||
#if defined(USE_SYSTEMD)
|
||||
if (global.tune.options & GTUNE_USE_SYSTEMD)
|
||||
sd_notifyf(0, "READY=1\nMAINPID=%lu", (unsigned long)getpid());
|
||||
#endif
|
||||
|
||||
mworker_register_signals();
|
||||
mworker_unblock_signals();
|
||||
|
||||
@ -710,6 +725,11 @@ restart_wait:
|
||||
/* should reach there only if it fail */
|
||||
goto restart_wait;
|
||||
} else {
|
||||
#if defined(USE_SYSTEMD)
|
||||
if ((global.tune.options & GTUNE_USE_SYSTEMD) && (sig == SIGUSR1 || sig == SIGTERM)) {
|
||||
sd_notify(0, "STOPPING=1");
|
||||
}
|
||||
#endif
|
||||
Warning("Exiting Master process...\n");
|
||||
mworker_kill(sig);
|
||||
mworker_unregister_signals();
|
||||
@ -1342,6 +1362,15 @@ static void init(int argc, char **argv)
|
||||
arg_mode |= MODE_CHECK;
|
||||
else if (*flag == 'D')
|
||||
arg_mode |= MODE_DAEMON;
|
||||
else if (*flag == 'W' && flag[1] == 's') {
|
||||
arg_mode |= MODE_MWORKER;
|
||||
#if defined(USE_SYSTEMD)
|
||||
global.tune.options |= GTUNE_USE_SYSTEMD;
|
||||
#else
|
||||
Alert("master-worker mode with systemd support (-Ws) requested, but not compiled. Use master-worker mode (-W) if you are not using Type=notify in your unit file or recompile with USE_SYSTEMD=1.\n\n");
|
||||
usage(progname);
|
||||
#endif
|
||||
}
|
||||
else if (*flag == 'W')
|
||||
arg_mode |= MODE_MWORKER;
|
||||
else if (*flag == 'q')
|
||||
|
Loading…
Reference in New Issue
Block a user