SHA256
1
0
forked from pool/haproxy
haproxy/0013-MINOR-systemd-wrapper-re-execute-on-SIGUSR2.patch
2014-05-06 15:38:15 +00:00

118 lines
3.0 KiB
Diff

From 07d130730feffcf64ab0709273f09c5374588b85 Mon Sep 17 00:00:00 2001
From: Apollon Oikonomopoulos <apoikos@debian.org>
Date: Thu, 17 Apr 2014 13:39:28 +0300
Subject: [PATCH 13/15] MINOR: systemd wrapper: re-execute on SIGUSR2
MINOR: systemd wrapper: re-execute on SIGUSR2
Re-execute the systemd wrapper on SIGUSR2 and before reloading HAProxy,
making it possible to load a completely new version of HAProxy
(including a new version of the systemd wrapper) gracefully.
Since the wrapper accepts no command-line arguments of its own,
re-execution is signaled using the HAPROXY_SYSTEMD_REEXEC environment
variable.
This is primarily intended to help seamless upgrades of distribution
packages.
---
src/haproxy-systemd-wrapper.c | 54 ++++++++++++++++++++++++++++++++-----------
1 file changed, 40 insertions(+), 14 deletions(-)
diff --git a/src/haproxy-systemd-wrapper.c b/src/haproxy-systemd-wrapper.c
index 8485dcd11da8..e373483d5085 100644
--- a/src/haproxy-systemd-wrapper.c
+++ b/src/haproxy-systemd-wrapper.c
@@ -18,9 +18,11 @@
#include <unistd.h>
#include <sys/wait.h>
+#define REEXEC_FLAG "HAPROXY_SYSTEMD_REEXEC"
+
static char *pid_file = "/run/haproxy.pid";
-static int main_argc;
-static char **main_argv;
+static int wrapper_argc;
+static char **wrapper_argv;
static void locate_haproxy(char *buffer, size_t buffer_size)
{
@@ -42,6 +44,11 @@ static void spawn_haproxy(char **pid_strv, int nb_pid)
{
char haproxy_bin[512];
pid_t pid;
+ int main_argc;
+ char **main_argv;
+
+ main_argc = wrapper_argc - 1;
+ main_argv = wrapper_argv + 1;
pid = fork();
if (!pid) {
@@ -96,15 +103,10 @@ static int read_pids(char ***pid_strv)
static void sigusr2_handler(int signum __attribute__((unused)))
{
- int i;
- char **pid_strv = NULL;
- int nb_pid = read_pids(&pid_strv);
+ setenv(REEXEC_FLAG, "1", 1);
+ printf("haproxy-systemd-wrapper: re-executing\n");
- spawn_haproxy(pid_strv, nb_pid);
-
- for (i = 0; i < nb_pid; ++i)
- free(pid_strv[i]);
- free(pid_strv);
+ execv(wrapper_argv[0], wrapper_argv);
}
static void sigint_handler(int signum __attribute__((unused)))
@@ -140,16 +142,40 @@ int main(int argc, char **argv)
{
int status;
+ wrapper_argc = argc;
+ wrapper_argv = argv;
+
--argc; ++argv;
- main_argc = argc;
- main_argv = argv;
-
init(argc, argv);
signal(SIGINT, &sigint_handler);
signal(SIGUSR2, &sigusr2_handler);
- spawn_haproxy(NULL, 0);
+ if (getenv(REEXEC_FLAG) != NULL) {
+ /* We are being re-executed: restart HAProxy gracefully */
+ int i;
+ char **pid_strv = NULL;
+ int nb_pid = read_pids(&pid_strv);
+ sigset_t sigs;
+
+ unsetenv(REEXEC_FLAG);
+ spawn_haproxy(pid_strv, nb_pid);
+
+ /* Unblock SIGUSR2 which was blocked by the signal handler
+ * before re-exec */
+ sigprocmask(SIG_BLOCK, NULL, &sigs);
+ sigdelset(&sigs, SIGUSR2);
+ sigprocmask(SIG_SETMASK, &sigs, NULL);
+
+ for (i = 0; i < nb_pid; ++i)
+ free(pid_strv[i]);
+ free(pid_strv);
+ }
+ else {
+ /* Start a fresh copy of HAProxy */
+ spawn_haproxy(NULL, 0);
+ }
+
status = -1;
while (-1 != wait(&status) || errno == EINTR)
;
--
1.8.4.5