Accepting request 207942 from network:ha-clustering:Factory

Backported the systemd-wrapper from upstream and patched it to work on openSUSE.

OBS-URL: https://build.opensuse.org/request/show/207942
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/haproxy?expand=0&rev=3
This commit is contained in:
Stephan Kulow 2013-12-18 15:53:39 +00:00 committed by Git OBS Bridge
parent 77c26b3d4b
commit a0959c3526
12 changed files with 991 additions and 24 deletions

View File

@ -0,0 +1,56 @@
From 4a190f7d08857fec82fa0c07e29e8754d0ba9794 Mon Sep 17 00:00:00 2001
From: Marc-Antoine Perennou <Marc-Antoine@Perennou.com>
Date: Fri, 22 Nov 2013 08:28:03 +0100
Subject: [PATCH 1/5] MEDIUM: add systemd service
---
.gitignore | 1 +
contrib/systemd/Makefile | 8 ++++++++
contrib/systemd/haproxy.service.in | 11 +++++++++++
3 files changed, 20 insertions(+)
create mode 100644 contrib/systemd/Makefile
create mode 100644 contrib/systemd/haproxy.service.in
diff --git a/.gitignore b/.gitignore
index 5d9576af102e..83d84083ca3e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,3 +15,4 @@ haproxy-*
make-*
dlmalloc.c
00*.patch
+*.service
diff --git a/contrib/systemd/Makefile b/contrib/systemd/Makefile
new file mode 100644
index 000000000000..e542c2387c79
--- /dev/null
+++ b/contrib/systemd/Makefile
@@ -0,0 +1,8 @@
+PREFIX = /usr/local
+SBINDIR = $(PREFIX)/sbin
+
+haproxy.service: haproxy.service.in
+ sed -e 's:@SBINDIR@:'$(strip $(SBINDIR))':' $< > $@
+
+clean:
+ rm -f haproxy.service
diff --git a/contrib/systemd/haproxy.service.in b/contrib/systemd/haproxy.service.in
new file mode 100644
index 000000000000..1a3d2c050f49
--- /dev/null
+++ b/contrib/systemd/haproxy.service.in
@@ -0,0 +1,11 @@
+[Unit]
+Description=HAProxy Load Balancer
+After=network.target
+
+[Service]
+ExecStart=@SBINDIR@/haproxy-systemd-wrapper -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid
+ExecReload=/bin/kill -USR2 $MAINPID
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
--
1.8.4

View File

@ -0,0 +1,227 @@
From 2e52a44546db246b89817711efec6b046c06d453 Mon Sep 17 00:00:00 2001
From: Marc-Antoine Perennou <Marc-Antoine@Perennou.com>
Date: Fri, 22 Nov 2013 08:29:29 +0100
Subject: [PATCH 2/5] MEDIUM: add haproxy-systemd-wrapper
Currently, to reload haproxy configuration, you have to use "-sf".
There is a problem with this way of doing things. First of all, in the systemd world,
reload commands should be "oneshot" ones, which means they should not be the new main
process but rather a tool which makes a call to it and then exits. With the current approach,
the reload command is the new main command and moreover, it makes the previous one exit.
Systemd only tracks the main program, seeing it ending, it assumes it either finished or failed,
and kills everything remaining as a grabage collector. We then end up with no haproxy running
at all.
This patch adds wrapper around haproxy, no changes at all have been made into it,
so it's not intrusive and doesn't change anything for other hosts. What this wrapper does
is basically launching haproxy as a child, listen to the SIGUSR2 (not to conflict with
haproxy itself) signal, and spawing a new haproxy with "-sf" as a child to relay the
first one.
Signed-off-by: Marc-Antoine Perennou <Marc-Antoine@Perennou.com>
---
.gitignore | 1 +
Makefile | 16 +++++-
src/haproxy-systemd-wrapper.c | 114 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 129 insertions(+), 2 deletions(-)
create mode 100644 src/haproxy-systemd-wrapper.c
diff --git a/.gitignore b/.gitignore
index 83d84083ca3e..ec1545a7a3df 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,6 +12,7 @@ src/*.o
*.log*
*.trace*
haproxy-*
+!src/*.c
make-*
dlmalloc.c
00*.patch
diff --git a/Makefile b/Makefile
index 57692fe51ba6..6bb231a0213a 100644
--- a/Makefile
+++ b/Makefile
@@ -519,7 +519,7 @@ all:
@echo
@exit 1
else
-all: haproxy
+all: haproxy haproxy-systemd-wrapper
endif
OBJS = src/haproxy.o src/sessionhash.o src/base64.o src/protocols.o \
@@ -537,12 +537,17 @@ EBTREE_OBJS = $(EBTREE_DIR)/ebtree.o \
$(EBTREE_DIR)/ebmbtree.o $(EBTREE_DIR)/ebsttree.o \
$(EBTREE_DIR)/ebimtree.o $(EBTREE_DIR)/ebistree.o
+WRAPPER_OBJS = src/haproxy-systemd-wrapper.o
+
# Not used right now
LIB_EBTREE = $(EBTREE_DIR)/libebtree.a
haproxy: $(OBJS) $(OPTIONS_OBJS) $(EBTREE_OBJS)
$(LD) $(LDFLAGS) -o $@ $^ $(LDOPTS)
+haproxy-systemd-wrapper: $(WRAPPER_OBJS)
+ $(LD) $(LDFLAGS) -o $@ $^ $(LDOPTS)
+
$(LIB_EBTREE): $(EBTREE_OBJS)
$(AR) rv $@ $^
@@ -562,6 +567,11 @@ src/haproxy.o: src/haproxy.c
-DBUILD_OPTIONS='"$(strip $(BUILD_OPTIONS))"' \
-c -o $@ $<
+src/haproxy-systemd-wrapper.o: src/haproxy-systemd-wrapper.c
+ $(CC) $(COPTS) \
+ -DSBINDIR='"$(strip $(SBINDIR))"' \
+ -c -o $@ $<
+
src/dlmalloc.o: $(DLMALLOC_SRC)
$(CC) $(COPTS) -DDEFAULT_MMAP_THRESHOLD=$(DLMALLOC_THRES) -c -o $@ $<
@@ -575,9 +585,10 @@ install-doc:
install -m 644 doc/$$x.txt $(DESTDIR)$(DOCDIR) ; \
done
-install-bin: haproxy
+install-bin: haproxy haproxy-systemd-wrapper
install -d $(DESTDIR)$(SBINDIR)
install haproxy $(DESTDIR)$(SBINDIR)
+ install haproxy-systemd-wrapper $(DESTDIR)$(SBINDIR)
install: install-bin install-man install-doc
@@ -586,6 +597,7 @@ clean:
for dir in . src include/* doc ebtree; do rm -f $$dir/*~ $$dir/*.rej $$dir/core; done
rm -f haproxy-$(VERSION).tar.gz haproxy-$(VERSION)$(SUBVERS).tar.gz
rm -f haproxy-$(VERSION) nohup.out gmon.out
+ rm -f haproxy-systemd-wrapper
tags:
find src include \( -name '*.c' -o -name '*.h' \) -print0 | \
diff --git a/src/haproxy-systemd-wrapper.c b/src/haproxy-systemd-wrapper.c
new file mode 100644
index 000000000000..596801591b9e
--- /dev/null
+++ b/src/haproxy-systemd-wrapper.c
@@ -0,0 +1,114 @@
+/*
+ * Wrapper to make haproxy systemd-compliant.
+ *
+ * Copyright 2013 Marc-Antoine Perennou <Marc-Antoine@Perennou.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <errno.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+static pid_t pid = 0;
+static char *pid_file = "/run/haproxy.pid";
+static int main_argc;
+static char **main_argv;
+
+static pid_t spawn_haproxy(char **pid_strv, int nb_pid)
+{
+ pid_t pid = fork();
+ if (!pid) {
+ /* 3 for "haproxy -Ds -sf" */
+ char **argv = calloc(4 + main_argc + nb_pid + 1, sizeof(char *));
+ int i;
+ int argno = 0;
+ argv[argno++] = SBINDIR"/haproxy";
+ for (i = 0; i < main_argc; ++i)
+ argv[argno++] = main_argv[i];
+ argv[argno++] = "-Ds";
+ if (nb_pid > 0) {
+ argv[argno++] = "-sf";
+ for (i = 0; i < nb_pid; ++i)
+ argv[argno++] = pid_strv[i];
+ }
+ argv[argno] = NULL;
+ execv(argv[0], argv);
+ exit(0);
+ }
+ return pid;
+}
+
+static int read_pids(char ***pid_strv)
+{
+ FILE *f = fopen(pid_file, "r");
+ int read = 0, allocated = 8;
+ char pid_str[10];
+
+ if (!f)
+ return 0;
+
+ *pid_strv = malloc(allocated * sizeof(char *));
+ while (1 == fscanf(f, "%s\n", pid_str)) {
+ if (read == allocated) {
+ allocated *= 2;
+ *pid_strv = realloc(*pid_strv, allocated * sizeof(char *));
+ }
+ (*pid_strv)[read++] = strdup(pid_str);
+ }
+
+ fclose(f);
+
+ return read;
+}
+
+static void signal_handler(int signum __attribute__((unused)))
+{
+ int i;
+ char **pid_strv = NULL;
+ int nb_pid = read_pids(&pid_strv);
+
+ pid = spawn_haproxy(pid_strv, nb_pid);
+
+ for (i = 0; i < nb_pid; ++i)
+ free(pid_strv[i]);
+ free(pid_strv);
+}
+
+static void init(int argc, char **argv)
+{
+ while (argc > 1) {
+ if (**argv == '-') {
+ char *flag = *argv + 1;
+ --argc; ++argv;
+ if (*flag == 'p')
+ pid_file = *argv;
+ }
+ --argc; ++argv;
+ }
+}
+
+int main(int argc, char **argv)
+{
+ --argc; ++argv;
+ main_argc = argc;
+ main_argv = argv;
+
+ init(argc, argv);
+
+ signal(SIGUSR2, &signal_handler);
+
+ pid = spawn_haproxy(NULL, 0);
+ while (-1 != waitpid(pid, NULL, 0) || errno == EINTR);
+
+ return EXIT_SUCCESS;
+}
--
1.8.4

View File

@ -0,0 +1,157 @@
From 8b79e7c45c86ef57317cbdbf451e49896a8ac239 Mon Sep 17 00:00:00 2001
From: Marc-Antoine Perennou <Marc-Antoine@Perennou.com>
Date: Fri, 22 Nov 2013 08:34:52 +0100
Subject: [PATCH 3/5] MEDIUM: New cli option -Ds for systemd compatibility
This patch adds a new option "-Ds" which is exactly like "-D", but instead of
forking n times to get n jobs running and then exiting, prefers to wait for all the
children it just created. With this done, haproxy becomes more systemd-compliant,
without changing anything for other systems.
Signed-off-by: Marc-Antoine Perennou <Marc-Antoine@Perennou.com>
---
doc/haproxy.1 | 4 ++++
include/types/global.h | 1 +
src/haproxy.c | 35 +++++++++++++++++++++++------------
3 files changed, 28 insertions(+), 12 deletions(-)
diff --git a/doc/haproxy.1 b/doc/haproxy.1
index 001de15a2ff9..48717adefab4 100644
--- a/doc/haproxy.1
+++ b/doc/haproxy.1
@@ -57,6 +57,10 @@ starting up.
Start in daemon mode.
.TP
+\fB\-Ds\fP
+Start in systemd daemon mode, keeping a process in foreground.
+
+.TP
\fB\-q\fP
Disable messages on output.
diff --git a/include/types/global.h b/include/types/global.h
index 7c5346b00b2d..d871939db21d 100644
--- a/include/types/global.h
+++ b/include/types/global.h
@@ -38,6 +38,7 @@
#define MODE_VERBOSE 0x10
#define MODE_STARTING 0x20
#define MODE_FOREGROUND 0x40
+#define MODE_SYSTEMD 0x80
/* list of last checks to perform, depending on config options */
#define LSTCHK_CAP_BIND 0x00000001 /* check that we can bind to any port */
diff --git a/src/haproxy.c b/src/haproxy.c
index 7a09e3fbfd72..494de5c85c29 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -42,6 +42,7 @@
#include <signal.h>
#include <stdarg.h>
#include <sys/resource.h>
+#include <sys/wait.h>
#include <time.h>
#include <syslog.h>
#include <grp.h>
@@ -488,8 +489,11 @@ void init(int argc, char **argv)
arg_mode |= MODE_DEBUG;
else if (*flag == 'c')
arg_mode |= MODE_CHECK;
- else if (*flag == 'D')
+ else if (*flag == 'D') {
arg_mode |= MODE_DAEMON;
+ if (flag[1] == 's') /* -Ds */
+ arg_mode |= MODE_SYSTEMD;
+ }
else if (*flag == 'q')
arg_mode |= MODE_QUIET;
else if (*flag == 's' && (flag[1] == 'f' || flag[1] == 't')) {
@@ -541,7 +545,7 @@ void init(int argc, char **argv)
}
global.mode = MODE_STARTING | /* during startup, we want most of the alerts */
- (arg_mode & (MODE_DAEMON | MODE_FOREGROUND | MODE_VERBOSE
+ (arg_mode & (MODE_DAEMON | MODE_SYSTEMD | MODE_FOREGROUND | MODE_VERBOSE
| MODE_QUIET | MODE_CHECK | MODE_DEBUG));
if (LIST_ISEMPTY(&cfg_cfgfiles))
@@ -649,24 +653,24 @@ void init(int argc, char **argv)
if (arg_mode & (MODE_DEBUG | MODE_FOREGROUND)) {
/* command line debug mode inhibits configuration mode */
- global.mode &= ~(MODE_DAEMON | MODE_QUIET);
+ global.mode &= ~(MODE_DAEMON | MODE_SYSTEMD | MODE_QUIET);
global.mode |= (arg_mode & (MODE_DEBUG | MODE_FOREGROUND));
}
- if (arg_mode & MODE_DAEMON) {
+ if (arg_mode & (MODE_DAEMON | MODE_SYSTEMD)) {
/* command line daemon mode inhibits foreground and debug modes mode */
global.mode &= ~(MODE_DEBUG | MODE_FOREGROUND);
- global.mode |= (arg_mode & MODE_DAEMON);
+ global.mode |= (arg_mode & (MODE_DAEMON | MODE_SYSTEMD));
}
global.mode |= (arg_mode & (MODE_QUIET | MODE_VERBOSE));
- if ((global.mode & MODE_DEBUG) && (global.mode & (MODE_DAEMON | MODE_QUIET))) {
- Warning("<debug> mode incompatible with <quiet> and <daemon>. Keeping <debug> only.\n");
- global.mode &= ~(MODE_DAEMON | MODE_QUIET);
+ if ((global.mode & MODE_DEBUG) && (global.mode & (MODE_DAEMON | MODE_SYSTEMD | MODE_QUIET))) {
+ Warning("<debug> mode incompatible with <quiet>, <daemon> and <systemd>. Keeping <debug> only.\n");
+ global.mode &= ~(MODE_DAEMON | MODE_SYSTEMD | MODE_QUIET);
}
- if ((global.nbproc > 1) && !(global.mode & MODE_DAEMON)) {
+ if ((global.nbproc > 1) && !(global.mode & (MODE_DAEMON | MODE_SYSTEMD))) {
if (!(global.mode & (MODE_FOREGROUND | MODE_DEBUG)))
Warning("<nbproc> is only meaningful in daemon mode. Setting limit to 1 process.\n");
global.nbproc = 1;
@@ -1132,7 +1136,7 @@ int main(int argc, char **argv)
}
/* open log & pid files before the chroot */
- if (global.mode & MODE_DAEMON && global.pidfile != NULL) {
+ if (global.mode & (MODE_DAEMON | MODE_SYSTEMD) && global.pidfile != NULL) {
int pidfd;
unlink(global.pidfile);
pidfd = open(global.pidfile, O_CREAT | O_WRONLY | O_TRUNC, 0644);
@@ -1222,9 +1226,10 @@ int main(int argc, char **argv)
argv[0], (int)limit.rlim_cur, global.maxconn, global.maxsock, global.maxsock);
}
- if (global.mode & MODE_DAEMON) {
+ if (global.mode & (MODE_DAEMON | MODE_SYSTEMD)) {
struct proxy *px;
int ret = 0;
+ int *children = calloc(global.nbproc, sizeof(int));
int proc;
/* the father launches the required number of processes */
@@ -1237,6 +1242,7 @@ int main(int argc, char **argv)
}
else if (ret == 0) /* child breaks here */
break;
+ children[proc] = ret;
if (pidfile != NULL) {
fprintf(pidfile, "%d\n", ret);
fflush(pidfile);
@@ -1262,8 +1268,13 @@ int main(int argc, char **argv)
px = px->next;
}
- if (proc == global.nbproc)
+ if (proc == global.nbproc) {
+ if (global.mode & MODE_SYSTEMD) {
+ for (proc = 0; proc < global.nbproc; proc++)
+ while (waitpid(children[proc], NULL, 0) == -1 && errno == EINTR);
+ }
exit(0); /* parent must leave */
+ }
/* if we're NOT in QUIET mode, we should now close the 3 first FDs to ensure
* that we can detach from the TTY. We MUST NOT do it in other cases since
--
1.8.4

View File

@ -0,0 +1,64 @@
From f0b6dab91180d0f719ff486b4bdf4ba518436174 Mon Sep 17 00:00:00 2001
From: Marc-Antoine Perennou <Marc-Antoine@Perennou.com>
Date: Fri, 22 Nov 2013 08:36:01 +0100
Subject: [PATCH 4/5] BUG/MEDIUM: systemd-wrapper: don't leak zombie processes
Formerly, if A was replaced by B, and then B by C before
A finished exiting, we didn't wait for B to finish so it
ended up as a zombie process.
Fix this by waiting randomly every child we spawn.
Signed-off-by: Marc-Antoine Perennou <Marc-Antoine@Perennou.com>
---
src/haproxy-systemd-wrapper.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/src/haproxy-systemd-wrapper.c b/src/haproxy-systemd-wrapper.c
index 596801591b9e..8499b35188c5 100644
--- a/src/haproxy-systemd-wrapper.c
+++ b/src/haproxy-systemd-wrapper.c
@@ -19,12 +19,11 @@
#include <unistd.h>
#include <sys/wait.h>
-static pid_t pid = 0;
static char *pid_file = "/run/haproxy.pid";
static int main_argc;
static char **main_argv;
-static pid_t spawn_haproxy(char **pid_strv, int nb_pid)
+static void spawn_haproxy(char **pid_strv, int nb_pid)
{
pid_t pid = fork();
if (!pid) {
@@ -45,7 +44,6 @@ static pid_t spawn_haproxy(char **pid_strv, int nb_pid)
execv(argv[0], argv);
exit(0);
}
- return pid;
}
static int read_pids(char ***pid_strv)
@@ -77,7 +75,7 @@ static void signal_handler(int signum __attribute__((unused)))
char **pid_strv = NULL;
int nb_pid = read_pids(&pid_strv);
- pid = spawn_haproxy(pid_strv, nb_pid);
+ spawn_haproxy(pid_strv, nb_pid);
for (i = 0; i < nb_pid; ++i)
free(pid_strv[i]);
@@ -107,8 +105,8 @@ int main(int argc, char **argv)
signal(SIGUSR2, &signal_handler);
- pid = spawn_haproxy(NULL, 0);
- while (-1 != waitpid(pid, NULL, 0) || errno == EINTR);
+ spawn_haproxy(NULL, 0);
+ while (-1 != wait(NULL) || errno == EINTR);
return EXIT_SUCCESS;
}
--
1.8.4

View File

@ -0,0 +1,25 @@
From 18d4a296b1a3bcdf6de904582d4766c1345a1b2f Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Fri, 22 Nov 2013 08:37:33 +0100
Subject: [PATCH 5/5] BUILD: stdbool is not portable (again)
Another build issue on Solaris without c99. Please don't use stdbool.
---
src/haproxy-systemd-wrapper.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/haproxy-systemd-wrapper.c b/src/haproxy-systemd-wrapper.c
index 8499b35188c5..fb1a7fd92724 100644
--- a/src/haproxy-systemd-wrapper.c
+++ b/src/haproxy-systemd-wrapper.c
@@ -12,7 +12,6 @@
#include <errno.h>
#include <signal.h>
-#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
--
1.8.4

View File

@ -0,0 +1,124 @@
From bf1c645a89c2c6df3c35cf489b3dba53e91e69c5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kristoffer=20Gr=C3=B6nlund?= <krig@koru.se>
Date: Fri, 22 Nov 2013 10:47:27 +0100
Subject: [PATCH] MEDIUM: haproxy-systemd-wrapper: Revised implementation
* Locate haproxy using location of the wrapper
* Kill children when killed
* Write information to stdout
---
src/haproxy-systemd-wrapper.c | 57 +++++++++++++++++++++++++++++++++++++------
1 file changed, 50 insertions(+), 7 deletions(-)
diff --git a/src/haproxy-systemd-wrapper.c b/src/haproxy-systemd-wrapper.c
index fb1a7fd92724..4ca86dd3b8c0 100644
--- a/src/haproxy-systemd-wrapper.c
+++ b/src/haproxy-systemd-wrapper.c
@@ -22,15 +22,30 @@ static char *pid_file = "/run/haproxy.pid";
static int main_argc;
static char **main_argv;
+static void locate_haproxy(char *buffer, size_t buffer_size)
+{
+ char* end;
+ readlink("/proc/self/exe", buffer, buffer_size);
+ end = strrchr(buffer, '/');
+ if (end == NULL)
+ strncpy(buffer, "/usr/sbin/haproxy", buffer_size);
+ end[1] = '\0';
+ strncat(buffer, "haproxy", buffer_size);
+}
+
static void spawn_haproxy(char **pid_strv, int nb_pid)
{
- pid_t pid = fork();
+ char haproxy_bin[512];
+ pid_t pid;
+
+ pid = fork();
if (!pid) {
/* 3 for "haproxy -Ds -sf" */
char **argv = calloc(4 + main_argc + nb_pid + 1, sizeof(char *));
int i;
int argno = 0;
- argv[argno++] = SBINDIR"/haproxy";
+ locate_haproxy(haproxy_bin, 512);
+ argv[argno++] = haproxy_bin;
for (i = 0; i < main_argc; ++i)
argv[argno++] = main_argv[i];
argv[argno++] = "-Ds";
@@ -40,6 +55,12 @@ static void spawn_haproxy(char **pid_strv, int nb_pid)
argv[argno++] = pid_strv[i];
}
argv[argno] = NULL;
+
+ printf("%s", "haproxy-systemd-wrapper: executing ");
+ for (i = 0; argv[i]; ++i)
+ printf("%s ", argv[i]);
+ puts("");
+
execv(argv[0], argv);
exit(0);
}
@@ -68,7 +89,7 @@ static int read_pids(char ***pid_strv)
return read;
}
-static void signal_handler(int signum __attribute__((unused)))
+static void sigusr2_handler(int signum __attribute__((unused)))
{
int i;
char **pid_strv = NULL;
@@ -81,6 +102,22 @@ static void signal_handler(int signum __attribute__((unused)))
free(pid_strv);
}
+static void sigint_handler(int signum __attribute__((unused)))
+{
+ int i, pid;
+ char **pid_strv = NULL;
+ int nb_pid = read_pids(&pid_strv);
+ for (i = 0; i < nb_pid; ++i) {
+ pid = atoi(pid_strv[i]);
+ if (pid > 0) {
+ printf("haproxy-systemd-wrapper: SIGINT -> %d\n", pid);
+ kill(pid, SIGINT);
+ free(pid_strv[i]);
+ }
+ }
+ free(pid_strv);
+}
+
static void init(int argc, char **argv)
{
while (argc > 1) {
@@ -96,16 +133,22 @@ static void init(int argc, char **argv)
int main(int argc, char **argv)
{
+ int status;
+
--argc; ++argv;
- main_argc = argc;
- main_argv = argv;
+ main_argc = argc;
+ main_argv = argv;
init(argc, argv);
- signal(SIGUSR2, &signal_handler);
+ signal(SIGINT, &sigint_handler);
+ signal(SIGUSR2, &sigusr2_handler);
spawn_haproxy(NULL, 0);
- while (-1 != wait(NULL) || errno == EINTR);
+ status = -1;
+ while (-1 != wait(&status) || errno == EINTR)
+ ;
+ printf("haproxy-systemd-wrapper: exit, haproxy RC=%d\n", status);
return EXIT_SUCCESS;
}
--
1.8.4

View File

@ -1,3 +1,20 @@
-------------------------------------------------------------------
Fri Nov 22 09:54:48 UTC 2013 - kgronlund@suse.com
- Backport haproxy-systemd-wrapper from upstream
- Patch haproxy-systemd-wrapper to work on openSUSE
-------------------------------------------------------------------
Thu Oct 31 12:46:04 UTC 2013 - kgronlund@suse.com
- Remove duplicate Requires: from .spec file.
-------------------------------------------------------------------
Thu Oct 31 12:41:12 UTC 2013 - kgronlund@suse.com
- Re-enable sysvinit support for older versions
(server:http still builds for older versions)
-------------------------------------------------------------------
Mon Oct 28 14:32:00 UTC 2013 - p.drouand@gmail.com

248
haproxy.init Normal file
View File

@ -0,0 +1,248 @@
#!/bin/sh
#
### BEGIN INIT INFO
# Provides: haproxy
# Required-Start: $syslog $remote_fs
# Should-Start: $time ypbind sendmail
# Required-Stop: $syslog $remote_fs
# Should-Stop: $time ypbind sendmail
# Default-Start: 3 5
# Default-Stop: 0 1 2 6
# Short-Description: haproxy
# Description: Start haproxy a reliable, high performance TCP/HTTP load balancer
### END INIT INFO
#
# Any extensions to the keywords given above should be preceeded by
# X-VendorTag- (X-UnitedLinux- X-SuSE- for us) according to LSB.
#
# Notes on Required-Start/Should-Start:
# * There are two different issues that are solved by Required-Start
# and Should-Start
# (a) Hard dependencies: This is used by the runlevel editor to determine
# which services absolutely need to be started to make the start of
# this service make sense. Example: nfsserver should have
# Required-Start: $portmap
# Also, required services are started before the dependent ones.
# The runlevel editor will warn about such missing hard dependencies
# and suggest enabling. During system startup, you may expect an error,
# if the dependency is not fulfilled.
# (b) Specifying the init script ordering, not real (hard) dependencies.
# This is needed by insserv to determine which service should be
# started first (and at a later stage what services can be started
# in parallel). The tag Should-Start: is used for this.
# It tells, that if a service is available, it should be started
# before. If not, never mind.
# * When specifying hard dependencies or ordering requirements, you can
# use names of services (contents of their Provides: section)
# or pseudo names starting with a $. The following ones are available
# according to LSB (1.1):
# $local_fs all local file systems are mounted
# (most services should need this!)
# $remote_fs all remote file systems are mounted
# (note that /usr may be remote, so
# many services should Require this!)
# $syslog system logging facility up
# $network low level networking (eth card, ...)
# $named hostname resolution available
# $netdaemons all network daemons are running
# The $netdaemons pseudo service has been removed in LSB 1.2.
# For now, we still offer it for backward compatibility.
# These are new (LSB 1.2):
# $time the system time has been set correctly
# $portmap SunRPC portmapping service available
# UnitedLinux extensions:
# $ALL indicates that a script should be inserted
# at the end
# * The services specified in the stop tags
# (Required-Stop/Should-Stop)
# specify which services need to be still running when this service
# is shut down. Often the entries there are just copies or a subset
# from the respective start tag.
# * Should-Start/Stop are now part of LSB as of 2.0,
# formerly SUSE/Unitedlinux used X-UnitedLinux-Should-Start/-Stop.
# insserv does support both variants.
# * X-UnitedLinux-Default-Enabled: yes/no is used at installation time
# (%fillup_and_insserv macro in %post of many RPMs) to specify whether
# a startup script should default to be enabled after installation.
# It's not used by insserv.
#
# Note on runlevels:
# 0 - halt/poweroff 6 - reboot
# 1 - single user 2 - multiuser without network exported
# 3 - multiuser w/ network (text mode) 5 - multiuser w/ network and X11 (xdm)
#
# Note on script names:
# http://www.linuxbase.org/spec/refspecs/LSB_1.3.0/gLSB/gLSB/scrptnames.html
# A registry has been set up to manage the init script namespace.
# http://www.lanana.org/
# Please use the names already registered or register one or use a
# vendor prefix.
# Check for missing binaries (stale symlinks should not happen)
# Note: Special treatment of stop for LSB conformance
HAPROXY_BIN=/usr/sbin/haproxy
test -x $HAPROXY_BIN || { echo "$HAPROXY_BIN not installed";
if [ "$1" = "stop" ]; then exit 0;
else exit 5; fi; }
HAPROXY_PID="/var/run/haproxy.pid"
HAPROXY_CONF="/etc/haproxy/haproxy.cfg"
## Check for existence of needed config file and read it
#HAPROXY_CONFIG=/etc/sysconfig/haproxy
#test -r $HAPROXY_CONFIG || { echo "$HAPROXY_CONFIG not existing";
# if [ "$1" = "stop" ]; then exit 0;
# else exit 6; fi; }
#
## Read config
#. $HAPROXY_CONFIG
# Source LSB init functions
# providing start_daemon, killproc, pidofproc,
# log_success_msg, log_failure_msg and log_warning_msg.
# This is currently not used by UnitedLinux based distributions and
# not needed for init scripts for UnitedLinux only. If it is used,
# the functions from rc.status should not be sourced or used.
#. /lib/lsb/init-functions
# Shell functions sourced from /etc/rc.status:
# rc_check check and set local and overall rc status
# rc_status check and set local and overall rc status
# rc_status -v be verbose in local rc status and clear it afterwards
# rc_status -v -r ditto and clear both the local and overall rc status
# rc_status -s display "skipped" and exit with status 3
# rc_status -u display "unused" and exit with status 3
# rc_failed set local and overall rc status to failed
# rc_failed <num> set local and overall rc status to <num>
# rc_reset clear both the local and overall rc status
# rc_exit exit appropriate to overall rc status
# rc_active checks whether a service is activated by symlinks
. /etc/rc.status
# Reset status of this service
rc_reset
# Return values acc. to LSB for all commands but status:
# 0 - success
# 1 - generic or unspecified error
# 2 - invalid or excess argument(s)
# 3 - unimplemented feature (e.g. "reload")
# 4 - user had insufficient privileges
# 5 - program is not installed
# 6 - program is not configured
# 7 - program is not running
# 8--199 - reserved (8--99 LSB, 100--149 distrib, 150--199 appl)
#
# Note that starting an already running service, stopping
# or restarting a not-running service as well as the restart
# with force-reload (in case signaling is not supported) are
# considered a success.
function haproxy_check() {
HAPROXY_CONFIG_CHECK="$($HAPROXY_BIN -c -q -f $HAPROXY_CONF 2>&1)"
if [ $? -ne 0 ] ; then
echo "" >&2
echo "$HAPROXY_CONFIG_CHECK" >&2
rc_failed
rc_status -v
exit 1
else
return 0
fi
}
case "$1" in
start)
echo -n "Starting haproxy "
## Start daemon with startproc(8). If this fails
## the return value is set appropriately by startproc.
haproxy_check
/sbin/startproc $HAPROXY_BIN -D -f $HAPROXY_CONF -p $HAPROXY_PID
# Remember status and be verbose
rc_status -v
;;
stop)
echo -n "Shutting down haproxy "
## Stop daemon with killproc(8) and if this fails
## killproc sets the return value according to LSB.
/sbin/killproc -TERM $HAPROXY_BIN
# Remember status and be verbose
rc_status -v
;;
try-restart|condrestart)
## Do a restart only if the service was active before.
## Note: try-restart is now part of LSB (as of 1.9).
## RH has a similar command named condrestart.
if test "$1" = "condrestart"; then
echo "${attn} Use try-restart ${done}(LSB)${attn} rather than condrestart ${warn}(RH)${norm}"
fi
$0 status
if test $? = 0; then
# we us reload here for a graceful restart during update
$0 reload
else
rc_reset # Not running is not a failure.
fi
# Remember status and be quiet
rc_status
;;
restart)
## Stop the service and regardless of whether it was
## running or not, start it again.
haproxy_check
$0 stop
$0 start
# Remember status and be quiet
rc_status
;;
check)
## Stop the service and regardless of whether it was
## running or not, start it again.
echo -n "Checking config of haproxy "
haproxy_check
rc_status -v
;;
reload|force-reload)
## Like force-reload, but if daemon does not support
## signaling, do nothing (!)
haproxy_check
# If it supports signaling:
echo -n "Reload service haproxy "
$HAPROXY_BIN -p $HAPROXY_PID -D -f $HAPROXY_CONF -sf $(cat $HAPROXY_PID)
rc_status -v
;;
status)
echo -n "Checking for service haproxy "
## Check status with checkproc(8), if process is running
## checkproc will return with exit status 0.
# Return value is slightly different for the status command:
# 0 - service up and running
# 1 - service dead, but /var/run/ pid file exists
# 2 - service dead, but /var/lock/ lock file exists
# 3 - service not running (unused)
# 4 - service status unknown :-(
# 5--199 reserved (5--99 LSB, 100--149 distro, 150--199 appl.)
# NOTE: checkproc returns LSB compliant status values.
/sbin/checkproc $HAPROXY_BIN
# NOTE: rc_status knows that we called this init script with
# "status" option and adapts its messages accordingly.
rc_status -v
;;
probe)
## Optional: Probe for the necessity of a reload, print out the
## argument to this init script which is required for a reload.
## Note: probe is not (yet) part of LSB (as of 1.9)
test $HAPROXY_CONF -nt $HAPROXY_PID && echo reload
;;
*)
echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload|probe}"
exit 1
;;
esac
rc_exit

View File

@ -1,13 +0,0 @@
[Unit]
Description=HAProxy For TCP And HTTP Based Applications
After=network.target
[Service]
Type=forking
PIDFile=/run/haproxy.pid
ExecStartPre=/usr/sbin/haproxy -c -q -f /etc/haproxy/haproxy.cfg
ExecStart=/usr/sbin/haproxy -D -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid
ExecReload=/bin/bash -c "exec /usr/sbin/haproxy -D -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -sf $MAINPID"
[Install]
WantedBy=multi-user.target

View File

@ -13,33 +13,47 @@
# published by the Open Source Initiative.
# Please submit bugfixes or comments via http://bugs.opensuse.org/
#
Name: haproxy
Version: 1.4.24
Release: 0
#
License: GPL-2.0+ and LGPL-2.1+
Group: Productivity/Networking/Web/Proxy
#
BuildRequires: libgcrypt-devel
BuildRequires: pcre-devel libgcrypt-devel
BuildRequires: udev
%if 0%{?suse_version} >= 1230
BuildRequires: pkgconfig(systemd)
%endif
BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildRequires: libgcrypt-devel
BuildRequires: pcre-devel
BuildRequires: udev
%define pkg_name haproxy
%define pkg_home /var/lib/%{pkg_name}
#
Url: http://haproxy.1wt.eu/
Source: http://haproxy.1wt.eu/download/1.4/src/haproxy-%{version}.tar.gz
Source1: %{pkg_name}.service
Source1: %{pkg_name}.init
Source2: http://haproxy.1wt.eu/download/contrib/haproxy.vim
Patch1: haproxy-1.2.16_config_haproxy_user.patch
Patch2: haproxy-makefile_lib.patch
Patch1: 0001-MEDIUM-add-systemd-service.patch
Patch2: 0002-MEDIUM-add-haproxy-systemd-wrapper.patch
Patch3: 0003-MEDIUM-New-cli-option-Ds-for-systemd-compatibility.patch
Patch4: 0004-BUG-MEDIUM-systemd-wrapper-don-t-leak-zombie-process.patch
Patch5: 0005-BUILD-stdbool-is-not-portable-again.patch
Patch6: 0006-haproxy-1.2.16_config_haproxy_user.patch
Patch7: 0007-haproxy-makefile_lib.patch
Patch8: 0008-MEDIUM-haproxy-systemd-wrapper-Revised-implementatio.patch
Source99: haproxy-rpmlintrc
#
Summary: The Reliable, High Performance TCP/HTTP Load Balancer
License: GPL-2.0+ and LGPL-2.1+
Group: Productivity/Networking/Web/Proxy
Provides: %{name}-doc = %{version}
Obsoletes: %{name}-doc < %{version}
%if 0%{?suse_version} >= 1230
%{?systemd_requires}
%endif
%description
HAProxy implements an event-driven, mono-process model which enables support
@ -54,8 +68,14 @@ the most work done from every CPU cycle.
%prep
%setup -q
%patch1
%patch2
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p0
%patch7 -p0
%patch8 -p1
%build
%{__make} \
@ -66,20 +86,37 @@ the most work done from every CPU cycle.
LIB="%{_lib}" \
DEBUG="%{optflags} -fno-strict-aliasing"
%{__make} PREFIX="%{_prefix}" -C contrib/systemd
%install
%{__install} -D -m 0755 %{pkg_name} %{buildroot}%{_sbindir}/%{pkg_name}
%{__install} -D -m 0644 examples/%{pkg_name}.cfg %{buildroot}%{_sysconfdir}/%{pkg_name}/%{pkg_name}.cfg
%{__install} -D -m 0755 %{S:1} %{buildroot}%{_unitdir}/%{pkg_name}.service
%if 0%{?suse_version} >= 1230
%{__install} -D -m 0755 haproxy-systemd-wrapper %{buildroot}%{_sbindir}/haproxy-systemd-wrapper
%{__install} -D -m 0755 contrib/systemd/%{pkg_name}.service %{buildroot}%{_unitdir}/%{pkg_name}.service
ln -sf /sbin/service %{buildroot}%{_sbindir}/rc%{pkg_name}
%else
%{__install} -D -m 0755 %{S:1} %{buildroot}%{_sysconfdir}/init.d/%{pkg_name}
%{__ln_s} -f %{_sysconfdir}/init.d/%{pkg_name} %{buildroot}%{_sbindir}/rc%{pkg_name}
%endif
%{__install} -d -m 0755 %{buildroot}%{pkg_home}
%{__install} -D -m 0644 %{S:2} %{buildroot}%{_datadir}/%{pkg_name}/%{pkg_name}.vim
%{__install} -D -m 0644 doc/%{pkg_name}.1 %{buildroot}%{_mandir}/man1/%{pkg_name}.1
gzip %{buildroot}%{_mandir}/man1/%{pkg_name}.1
%if 0%{?suse_version} < 1230
%clean
%{?buildroot:%{__rm} -rf %{buildroot}}
%endif
%pre
/usr/sbin/groupadd -r %{pkg_name} &>/dev/null ||:
/usr/sbin/useradd -g %{pkg_name} -s /bin/false -r -c "user for %{pkg_name}" -d %{pkg_home} %{pkg_name} &>/dev/null ||:
%if 0%{?suse_version} >= 1230
%post
%service_add_post %{pkg_name}.service
@ -89,13 +126,38 @@ gzip %{buildroot}%{_mandir}/man1/%{pkg_name}.1
%postun
%service_del_postun %{pkg_name}.service
%else
%post
%fillup_and_insserv %{pkg_name}
%preun
%stop_on_removal %{pkg_name}
%postun
%restart_on_update %{pkg_name}
%{insserv_cleanup}
%endif
%files
%defattr(-,root,root,-)
%doc CHANGELOG README LICENSE
%doc ROADMAP TODO doc/* examples
%dir %{_sysconfdir}/%{pkg_name}
%config(noreplace) %{_sysconfdir}/%{pkg_name}/%{pkg_name}.cfg
%if 0%{?suse_version} >= 1230
%{_unitdir}/%{pkg_name}.service
%{_sbindir}/haproxy-systemd-wrapper
%else
%config(noreplace) %{_sysconfdir}/init.d/%{pkg_name}
%endif
%{_sbindir}/haproxy
%{_sbindir}/rchaproxy
%{pkg_home}