haproxy: remove old patches
- remove old patches from 1.6 - fix download url for 1.7 - fixes #3687 Signed-off-by: heil <heil@terminal-consulting.de>
This commit is contained in:
parent
6fa5f409e7
commit
0f9bf14e66
32 changed files with 1 additions and 1722 deletions
|
@ -13,7 +13,7 @@ PKG_VERSION:=1.7.1
|
|||
PKG_RELEASE:=00
|
||||
|
||||
PKG_SOURCE:=haproxy-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=http://haproxy.1wt.eu/download/1.6/src/
|
||||
PKG_SOURCE_URL:=http://haproxy.1wt.eu/download/1.7/src/
|
||||
PKG_MD5SUM:=d0acaae02e444039e11892ea31dde478
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
From 42ccea00f69abdd1bb748494f7e17d8369ccae31 Mon Sep 17 00:00:00 2001
|
||||
From: Dinko Korunic <dinko.korunic@gmail.com>
|
||||
Date: Fri, 9 Sep 2016 09:41:15 +0200
|
||||
Subject: [PATCH 01/26] BUG/MINOR: Fix OSX compilation errors
|
||||
|
||||
SOL_IPV6 is not defined on OSX, breaking the compile. Also libcrypt is
|
||||
not available for installation neither in Macports nor as a Brew recipe,
|
||||
so we're disabling implicit dependancy.
|
||||
|
||||
Signed-off-by: Dinko Korunic <dinko.korunic@gmail.com>
|
||||
(cherry picked from commit 7276f3aa3d687fca64bb9becc66c8e0dbb8b378a)
|
||||
---
|
||||
Makefile | 1 -
|
||||
src/proto_tcp.c | 4 ++--
|
||||
2 files changed, 2 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 1bf778d..1d0f2bc 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -301,7 +301,6 @@ ifeq ($(TARGET),osx)
|
||||
USE_POLL = implicit
|
||||
USE_KQUEUE = implicit
|
||||
USE_TPROXY = implicit
|
||||
- USE_LIBCRYPT = implicit
|
||||
else
|
||||
ifeq ($(TARGET),openbsd)
|
||||
# This is for OpenBSD >= 3.0
|
||||
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
|
||||
index 2c81fb4..4f5d88d 100644
|
||||
--- a/src/proto_tcp.c
|
||||
+++ b/src/proto_tcp.c
|
||||
@@ -206,7 +206,7 @@ int tcp_bind_socket(int fd, int flags, struct sockaddr_storage *local, struct so
|
||||
case AF_INET6:
|
||||
if (flags && ip6_transp_working) {
|
||||
if (0
|
||||
-#if defined(IPV6_TRANSPARENT)
|
||||
+#if defined(IPV6_TRANSPARENT) && defined(SOL_IPV6)
|
||||
|| (setsockopt(fd, SOL_IPV6, IPV6_TRANSPARENT, &one, sizeof(one)) == 0)
|
||||
#endif
|
||||
#if defined(IP_FREEBIND)
|
||||
@@ -854,7 +854,7 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen)
|
||||
break;
|
||||
case AF_INET6:
|
||||
if (1
|
||||
-#if defined(IPV6_TRANSPARENT)
|
||||
+#if defined(IPV6_TRANSPARENT) && defined(SOL_IPV6)
|
||||
&& (setsockopt(fd, SOL_IPV6, IPV6_TRANSPARENT, &one, sizeof(one)) == -1)
|
||||
#endif
|
||||
#if defined(IP_FREEBIND)
|
||||
--
|
||||
2.7.3
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
From 3a011f15a8d61cd0088cc0e46743bdc7699db1af Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Tribus <luky-37@hotmail.com>
|
||||
Date: Mon, 12 Sep 2016 21:42:00 +0000
|
||||
Subject: [PATCH 02/26] BUG/MINOR: displayed PCRE version is running release
|
||||
|
||||
pcre_version() returns the running PCRE release, not the release
|
||||
haproxy was built with.
|
||||
|
||||
This simple string fix should be backported to supported releases,
|
||||
as the output may be confusing.
|
||||
(cherry picked from commit d64788d9c610163756cac6c91220875e51cba3ef)
|
||||
---
|
||||
src/haproxy.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/haproxy.c b/src/haproxy.c
|
||||
index d70cf63..44d32b9 100644
|
||||
--- a/src/haproxy.c
|
||||
+++ b/src/haproxy.c
|
||||
@@ -347,7 +347,7 @@ void display_build_opts()
|
||||
#endif
|
||||
|
||||
#ifdef USE_PCRE
|
||||
- printf("Built with PCRE version : %s", pcre_version());
|
||||
+ printf("Running on PCRE version : %s", pcre_version());
|
||||
printf("\nPCRE library supports JIT : ");
|
||||
#ifdef USE_PCRE_JIT
|
||||
{
|
||||
--
|
||||
2.7.3
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
From dcdd2ae7d6809f45c5f6bbe2ba6fe9c70802bb42 Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Tribus <luky-37@hotmail.com>
|
||||
Date: Mon, 12 Sep 2016 21:42:07 +0000
|
||||
Subject: [PATCH 03/26] MINOR: show Built with PCRE version
|
||||
|
||||
Inspired by PCRE's pcre_version.c and improved with Willy's
|
||||
suggestions. Reusable parts have been added to
|
||||
include/common/standard.h.
|
||||
(cherry picked from commit dcbc5c5ecf6506b5ad55b98bbec910b29f011f14)
|
||||
---
|
||||
include/common/standard.h | 9 +++++++++
|
||||
src/haproxy.c | 3 +++
|
||||
2 files changed, 12 insertions(+)
|
||||
|
||||
diff --git a/include/common/standard.h b/include/common/standard.h
|
||||
index 6098550..26a52ff 100644
|
||||
--- a/include/common/standard.h
|
||||
+++ b/include/common/standard.h
|
||||
@@ -1065,4 +1065,13 @@ static inline void *my_realloc2(void *ptr, size_t size)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+/* HAP_STRING() makes a string from a literal while HAP_XSTRING() first
|
||||
+ * evaluates the argument and is suited to pass macros.
|
||||
+ *
|
||||
+ * They allow macros like PCRE_MAJOR to be defined without quotes, which
|
||||
+ * is convenient for applications that want to test its value.
|
||||
+ */
|
||||
+#define HAP_STRING(...) #__VA_ARGS__
|
||||
+#define HAP_XSTRING(...) HAP_STRING(__VA_ARGS__)
|
||||
+
|
||||
#endif /* _COMMON_STANDARD_H */
|
||||
diff --git a/src/haproxy.c b/src/haproxy.c
|
||||
index 44d32b9..37d700b 100644
|
||||
--- a/src/haproxy.c
|
||||
+++ b/src/haproxy.c
|
||||
@@ -347,6 +347,9 @@ void display_build_opts()
|
||||
#endif
|
||||
|
||||
#ifdef USE_PCRE
|
||||
+ printf("Built with PCRE version : %s\n", (HAP_XSTRING(Z PCRE_PRERELEASE)[1] == 0)?
|
||||
+ HAP_XSTRING(PCRE_MAJOR.PCRE_MINOR PCRE_DATE) :
|
||||
+ HAP_XSTRING(PCRE_MAJOR.PCRE_MINOR) HAP_XSTRING(PCRE_PRERELEASE PCRE_DATE));
|
||||
printf("Running on PCRE version : %s", pcre_version());
|
||||
printf("\nPCRE library supports JIT : ");
|
||||
#ifdef USE_PCRE_JIT
|
||||
--
|
||||
2.7.3
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
From 9d59ff222cc81ee356594cfa780349dd91376fd9 Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Tribus <luky-37@hotmail.com>
|
||||
Date: Mon, 12 Sep 2016 21:42:14 +0000
|
||||
Subject: [PATCH 04/26] MINOR: show Running on zlib version
|
||||
|
||||
(cherry picked from commit 255cc5184dc8483e4377d9de25670bd6e226cdba)
|
||||
---
|
||||
src/haproxy.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/src/haproxy.c b/src/haproxy.c
|
||||
index 37d700b..9f5878a 100644
|
||||
--- a/src/haproxy.c
|
||||
+++ b/src/haproxy.c
|
||||
@@ -287,6 +287,7 @@ void display_build_opts()
|
||||
|
||||
#ifdef USE_ZLIB
|
||||
printf("Built with zlib version : " ZLIB_VERSION "\n");
|
||||
+ printf("Running on zlib version : %s\n", zlibVersion());
|
||||
#elif defined(USE_SLZ)
|
||||
printf("Built with libslz for stateless compression.\n");
|
||||
#else /* USE_ZLIB */
|
||||
--
|
||||
2.7.3
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
From 7397526d0c80251b3006b1b45af754f5ad7adb76 Mon Sep 17 00:00:00 2001
|
||||
From: Nenad Merdanovic <nmerdan@anine.io>
|
||||
Date: Mon, 3 Oct 2016 04:57:37 +0200
|
||||
Subject: [PATCH 05/26] MINOR: Add fe_req_rate sample fetch
|
||||
|
||||
The fe_req_rate is similar to fe_sess_rate, but fetches the number
|
||||
of HTTP requests per second instead of connections/sessions per second.
|
||||
|
||||
Signed-off-by: Nenad Merdanovic <nmerdan@anine.io>
|
||||
(cherry picked from commit ad9a7e9770e673a70fb56ab95be18bf88666d92a)
|
||||
---
|
||||
doc/configuration.txt | 5 +++++
|
||||
src/frontend.c | 14 ++++++++++++++
|
||||
2 files changed, 19 insertions(+)
|
||||
|
||||
diff --git a/doc/configuration.txt b/doc/configuration.txt
|
||||
index d4b1744..d18c399 100644
|
||||
--- a/doc/configuration.txt
|
||||
+++ b/doc/configuration.txt
|
||||
@@ -12253,6 +12253,11 @@ fe_conn([<frontend>]) : integer
|
||||
statistics to servers in HTTP headers. See also the "dst_conn", "be_conn",
|
||||
"fe_sess_rate" fetches.
|
||||
|
||||
+fe_req_rate([<frontend>]) : integer
|
||||
+ Returns an integer value corresponding to the number of HTTP requests per
|
||||
+ second sent to a frontend. This number can differ from "fe_sess_rate" in
|
||||
+ situations where client-side keep-alive is enabled.
|
||||
+
|
||||
fe_sess_rate([<frontend>]) : integer
|
||||
Returns an integer value corresponding to the sessions creation rate on the
|
||||
frontend, in number of new sessions per second. This is used with ACLs to
|
||||
diff --git a/src/frontend.c b/src/frontend.c
|
||||
index 74ec0ab..5cc6202 100644
|
||||
--- a/src/frontend.c
|
||||
+++ b/src/frontend.c
|
||||
@@ -167,6 +167,19 @@ smp_fetch_fe_id(const struct arg *args, struct sample *smp, const char *kw, void
|
||||
return 1;
|
||||
}
|
||||
|
||||
+/* set temp integer to the number of HTTP requests per second reaching the frontend.
|
||||
+ * Accepts exactly 1 argument. Argument is a frontend, other types will cause
|
||||
+ * an undefined behaviour.
|
||||
+ */
|
||||
+static int
|
||||
+smp_fetch_fe_req_rate(const struct arg *args, struct sample *smp, const char *kw, void *private)
|
||||
+{
|
||||
+ smp->flags = SMP_F_VOL_TEST;
|
||||
+ smp->data.type = SMP_T_SINT;
|
||||
+ smp->data.u.sint = read_freq_ctr(&args->data.prx->fe_req_per_sec);
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
/* set temp integer to the number of connections per second reaching the frontend.
|
||||
* Accepts exactly 1 argument. Argument is a frontend, other types will cause
|
||||
* an undefined behaviour.
|
||||
@@ -200,6 +213,7 @@ smp_fetch_fe_conn(const struct arg *args, struct sample *smp, const char *kw, vo
|
||||
static struct sample_fetch_kw_list smp_kws = {ILH, {
|
||||
{ "fe_conn", smp_fetch_fe_conn, ARG1(1,FE), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
{ "fe_id", smp_fetch_fe_id, 0, NULL, SMP_T_SINT, SMP_USE_FTEND, },
|
||||
+ { "fe_req_rate", smp_fetch_fe_req_rate, ARG1(1,FE), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
{ "fe_sess_rate", smp_fetch_fe_sess_rate, ARG1(1,FE), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
{ /* END */ },
|
||||
}};
|
||||
--
|
||||
2.7.3
|
||||
|
|
@ -1,134 +0,0 @@
|
|||
From 3dd981c016ac7ad636ee546c2b9b685f7e8500d4 Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Tribus <luky-37@hotmail.com>
|
||||
Date: Mon, 12 Sep 2016 21:42:20 +0000
|
||||
Subject: [PATCH 06/26] MEDIUM: make SO_REUSEPORT configurable
|
||||
|
||||
With Linux officially introducing SO_REUSEPORT support in 3.9 and
|
||||
its mainstream adoption we have seen more people running into strange
|
||||
SO_REUSEPORT related issues (a process management issue turning into
|
||||
hard to diagnose problems because the kernel load-balances between the
|
||||
new and an obsolete haproxy instance).
|
||||
|
||||
Also some people simply want the guarantee that the bind fails when
|
||||
the old process is still bound.
|
||||
|
||||
This change makes SO_REUSEPORT configurable, introducing the command
|
||||
line argument "-dR" and the noreuseport configuration directive.
|
||||
|
||||
A backport to 1.6 should be considered.
|
||||
(cherry picked from commit a0bcbdcb04d52c3ca71045f90aac33d9dd7965bf)
|
||||
---
|
||||
doc/configuration.txt | 5 +++++
|
||||
include/types/global.h | 1 +
|
||||
src/cfgparse.c | 5 +++++
|
||||
src/haproxy.c | 10 ++++++++++
|
||||
src/proto_tcp.c | 6 +++---
|
||||
5 files changed, 24 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/doc/configuration.txt b/doc/configuration.txt
|
||||
index d18c399..e725ce2 100644
|
||||
--- a/doc/configuration.txt
|
||||
+++ b/doc/configuration.txt
|
||||
@@ -570,6 +570,7 @@ The following keywords are supported in the "global" section :
|
||||
- nopoll
|
||||
- nosplice
|
||||
- nogetaddrinfo
|
||||
+ - noreuseport
|
||||
- spread-checks
|
||||
- server-state-base
|
||||
- server-state-file
|
||||
@@ -1090,6 +1091,10 @@ nogetaddrinfo
|
||||
Disables the use of getaddrinfo(3) for name resolving. It is equivalent to
|
||||
the command line argument "-dG". Deprecated gethostbyname(3) will be used.
|
||||
|
||||
+noreuseport
|
||||
+ Disables the use of SO_REUSEPORT - see socket(7). It is equivalent to the
|
||||
+ command line argument "-dR".
|
||||
+
|
||||
spread-checks <0..50, in percent>
|
||||
Sometimes it is desirable to avoid sending agent and health checks to
|
||||
servers at exact intervals, for instance when many logical servers are
|
||||
diff --git a/include/types/global.h b/include/types/global.h
|
||||
index 61f0391..2e24d3f 100644
|
||||
--- a/include/types/global.h
|
||||
+++ b/include/types/global.h
|
||||
@@ -63,6 +63,7 @@
|
||||
/* platform-specific options */
|
||||
#define GTUNE_USE_SPLICE (1<<4)
|
||||
#define GTUNE_USE_GAI (1<<5)
|
||||
+#define GTUNE_USE_REUSEPORT (1<<6)
|
||||
|
||||
/* Access level for a stats socket */
|
||||
#define ACCESS_LVL_NONE 0
|
||||
diff --git a/src/cfgparse.c b/src/cfgparse.c
|
||||
index 55086fd..f2a104d 100644
|
||||
--- a/src/cfgparse.c
|
||||
+++ b/src/cfgparse.c
|
||||
@@ -662,6 +662,11 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
|
||||
goto out;
|
||||
global.tune.options &= ~GTUNE_USE_GAI;
|
||||
}
|
||||
+ else if (!strcmp(args[0], "noreuseport")) {
|
||||
+ if (alertif_too_many_args(0, file, linenum, args, &err_code))
|
||||
+ goto out;
|
||||
+ global.tune.options &= ~GTUNE_USE_REUSEPORT;
|
||||
+ }
|
||||
else if (!strcmp(args[0], "quiet")) {
|
||||
if (alertif_too_many_args(0, file, linenum, args, &err_code))
|
||||
goto out;
|
||||
diff --git a/src/haproxy.c b/src/haproxy.c
|
||||
index 9f5878a..a657dc4 100644
|
||||
--- a/src/haproxy.c
|
||||
+++ b/src/haproxy.c
|
||||
@@ -452,6 +452,9 @@ void usage(char *name)
|
||||
#if defined(USE_GETADDRINFO)
|
||||
" -dG disables getaddrinfo() usage\n"
|
||||
#endif
|
||||
+#if defined(SO_REUSEPORT)
|
||||
+ " -dR disables SO_REUSEPORT usage\n"
|
||||
+#endif
|
||||
" -dV disables SSL verify on servers side\n"
|
||||
" -sf/-st [pid ]* finishes/terminates old pids.\n"
|
||||
"\n",
|
||||
@@ -623,6 +626,9 @@ void init(int argc, char **argv)
|
||||
#if defined(USE_GETADDRINFO)
|
||||
global.tune.options |= GTUNE_USE_GAI;
|
||||
#endif
|
||||
+#if defined(SO_REUSEPORT)
|
||||
+ global.tune.options |= GTUNE_USE_REUSEPORT;
|
||||
+#endif
|
||||
|
||||
pid = getpid();
|
||||
progname = *argv;
|
||||
@@ -666,6 +672,10 @@ void init(int argc, char **argv)
|
||||
else if (*flag == 'd' && flag[1] == 'G')
|
||||
global.tune.options &= ~GTUNE_USE_GAI;
|
||||
#endif
|
||||
+#if defined(SO_REUSEPORT)
|
||||
+ else if (*flag == 'd' && flag[1] == 'R')
|
||||
+ global.tune.options &= ~GTUNE_USE_REUSEPORT;
|
||||
+#endif
|
||||
else if (*flag == 'd' && flag[1] == 'V')
|
||||
global.ssl_server_verify = SSL_SERVER_VERIFY_NONE;
|
||||
else if (*flag == 'V')
|
||||
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
|
||||
index 4f5d88d..0f20fde 100644
|
||||
--- a/src/proto_tcp.c
|
||||
+++ b/src/proto_tcp.c
|
||||
@@ -824,10 +824,10 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen)
|
||||
setsockopt(fd, SOL_SOCKET, SO_LINGER, &nolinger, sizeof(struct linger));
|
||||
|
||||
#ifdef SO_REUSEPORT
|
||||
- /* OpenBSD supports this. As it's present in old libc versions of Linux,
|
||||
- * it might return an error that we will silently ignore.
|
||||
+ /* OpenBSD and Linux 3.9 support this. As it's present in old libc versions of
|
||||
+ * Linux, it might return an error that we will silently ignore.
|
||||
*/
|
||||
- if (!ext)
|
||||
+ if (!ext && (global.tune.options & GTUNE_USE_REUSEPORT))
|
||||
setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one));
|
||||
#endif
|
||||
|
||||
--
|
||||
2.7.3
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
From 21877a43afd6300518140c415ccec2dba0a0591f Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Fri, 21 Oct 2016 17:13:24 +0200
|
||||
Subject: [PATCH 07/26] BUG/MINOR: vars: use sess and not s->sess in
|
||||
action_store()
|
||||
|
||||
This causes the stream to be dereferenced when not needed. It will
|
||||
cause trouble when variables are used outside of a stream.
|
||||
(cherry picked from commit 108a8fd8be0c78a4bf147a2028fd9bda3343c93c)
|
||||
---
|
||||
src/vars.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/vars.c b/src/vars.c
|
||||
index 56fade5..b22c3bf 100644
|
||||
--- a/src/vars.c
|
||||
+++ b/src/vars.c
|
||||
@@ -507,7 +507,7 @@ static enum act_return action_store(struct act_rule *rule, struct proxy *px,
|
||||
|
||||
/* Process the expression. */
|
||||
memset(&smp, 0, sizeof(smp));
|
||||
- if (!sample_process(px, s->sess, s, dir|SMP_OPT_FINAL,
|
||||
+ if (!sample_process(px, sess, s, dir|SMP_OPT_FINAL,
|
||||
rule->arg.vars.expr, &smp))
|
||||
return ACT_RET_CONT;
|
||||
|
||||
--
|
||||
2.7.3
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
From ff403602edc917b8bef2062dc0d5dec2017e3232 Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Fri, 21 Oct 2016 17:14:35 +0200
|
||||
Subject: [PATCH 08/26] BUG/MINOR: vars: make smp_fetch_var() more robust
|
||||
against misuses
|
||||
|
||||
smp_fetch_var() may be called from everywhere since it just reads a
|
||||
variable. It must ensure that the stream exists before trying to return
|
||||
a stream-dependant variable. For now there is no impact but it will
|
||||
cause trouble with tcp-request session rules.
|
||||
(cherry picked from commit 7513d001c8a6b7d1cf8e7d5469942cd39d6e8160)
|
||||
---
|
||||
src/vars.c | 16 +++++++++++++---
|
||||
1 file changed, 13 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/vars.c b/src/vars.c
|
||||
index b22c3bf..4a0c4ed 100644
|
||||
--- a/src/vars.c
|
||||
+++ b/src/vars.c
|
||||
@@ -242,11 +242,21 @@ static int smp_fetch_var(const struct arg *args, struct sample *smp, const char
|
||||
|
||||
/* Check the availibity of the variable. */
|
||||
switch (var_desc->scope) {
|
||||
- case SCOPE_SESS: vars = &smp->sess->vars; break;
|
||||
- case SCOPE_TXN: vars = &smp->strm->vars_txn; break;
|
||||
+ case SCOPE_SESS:
|
||||
+ vars = &smp->sess->vars;
|
||||
+ break;
|
||||
+ case SCOPE_TXN:
|
||||
+ if (!smp->strm)
|
||||
+ return 0;
|
||||
+ vars = &smp->strm->vars_txn;
|
||||
+ break;
|
||||
case SCOPE_REQ:
|
||||
case SCOPE_RES:
|
||||
- default: vars = &smp->strm->vars_reqres; break;
|
||||
+ default:
|
||||
+ if (!smp->strm)
|
||||
+ return 0;
|
||||
+ vars = &smp->strm->vars_reqres;
|
||||
+ break;
|
||||
}
|
||||
if (vars->scope != var_desc->scope)
|
||||
return 0;
|
||||
--
|
||||
2.7.3
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
From 3810ab9e71a19e7f04a9e18580abc77c276d0ff1 Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Fri, 21 Oct 2016 17:17:18 +0200
|
||||
Subject: [PATCH 09/26] BUG/MINOR: vars: smp_fetch_var() doesn't depend on HTTP
|
||||
but on the session
|
||||
|
||||
Thus the SMP_USE_HTTP_ANY dependency is incorrect, we have to depend on
|
||||
SMP_USE_L5_CLI (the session). It's particularly important for session-wide
|
||||
variables which are kept across HTTP requests. For now there is no impact
|
||||
but it will make a difference with tcp-request session rules.
|
||||
(cherry picked from commit 87846e42a478fe2aa0fbc1e162ba5fb227be49b7)
|
||||
---
|
||||
src/vars.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/vars.c b/src/vars.c
|
||||
index 4a0c4ed..a3dd85c 100644
|
||||
--- a/src/vars.c
|
||||
+++ b/src/vars.c
|
||||
@@ -654,7 +654,7 @@ static int vars_max_size_reqres(char **args, int section_type, struct proxy *cur
|
||||
|
||||
static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
|
||||
|
||||
- { "var", smp_fetch_var, ARG1(1,STR), smp_check_var, SMP_T_STR, SMP_USE_HTTP_ANY },
|
||||
+ { "var", smp_fetch_var, ARG1(1,STR), smp_check_var, SMP_T_STR, SMP_USE_L5CLI },
|
||||
{ /* END */ },
|
||||
}};
|
||||
|
||||
--
|
||||
2.7.3
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
From 2d7ed4ae91383cd35fe07cd34d01c23b4a5d03f5 Mon Sep 17 00:00:00 2001
|
||||
From: "Thierry FOURNIER / OZON.IO" <thierry.fournier@ozon.io>
|
||||
Date: Thu, 6 Oct 2016 10:35:29 +0200
|
||||
Subject: [PATCH 10/26] BUG/MINOR: ssl: Check malloc return code
|
||||
|
||||
If malloc() can't allocate memory and return NULL, a segfaut will raises.
|
||||
|
||||
This patch should be backported in the 1.6 and 1.5 version.
|
||||
(cherry picked from commit 7a3bd3b9dc43509bb1869389dcf91e35c0155f9b)
|
||||
---
|
||||
src/ssl_sock.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
|
||||
index 0535a3b..5f9a203 100644
|
||||
--- a/src/ssl_sock.c
|
||||
+++ b/src/ssl_sock.c
|
||||
@@ -1572,6 +1572,8 @@ static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name,
|
||||
int j, len;
|
||||
len = strlen(name);
|
||||
sc = malloc(sizeof(struct sni_ctx) + len + 1);
|
||||
+ if (!sc)
|
||||
+ return order;
|
||||
for (j = 0; j < len; j++)
|
||||
sc->name.key[j] = tolower(name[j]);
|
||||
sc->name.key[len] = 0;
|
||||
--
|
||||
2.7.3
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
From b2b0eab46a8ae36f2dd49159e65c90c1089a0f96 Mon Sep 17 00:00:00 2001
|
||||
From: "Thierry FOURNIER / OZON.IO" <thierry.fournier@ozon.io>
|
||||
Date: Thu, 6 Oct 2016 10:56:48 +0200
|
||||
Subject: [PATCH 11/26] BUG/MINOR: ssl: prevent multiple entries for the same
|
||||
certificate
|
||||
|
||||
Today, the certificate are indexed int he SNI tree using their CN and the
|
||||
list of thier AltNames. So, Some certificates have the same names in the
|
||||
CN and one of the AltNames entries.
|
||||
|
||||
Typically Let's Encrypt duplicate the the DNS name in the CN and the
|
||||
AltName.
|
||||
|
||||
This patch prevents the creation of identical entries in the trees. It
|
||||
checks the same DNS name and the same SSL context.
|
||||
|
||||
If the same certificate is registered two time it will be duplicated.
|
||||
|
||||
This patch should be backported in the 1.6 and 1.5 version.
|
||||
(cherry picked from commit 07c3d78c2c0693ee37db71c34723597638b6ab3f)
|
||||
---
|
||||
src/ssl_sock.c | 22 +++++++++++++++++++---
|
||||
1 file changed, 19 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
|
||||
index 5f9a203..ad8054d 100644
|
||||
--- a/src/ssl_sock.c
|
||||
+++ b/src/ssl_sock.c
|
||||
@@ -1556,6 +1556,7 @@ static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name,
|
||||
{
|
||||
struct sni_ctx *sc;
|
||||
int wild = 0, neg = 0;
|
||||
+ struct ebmb_node *node;
|
||||
|
||||
if (*name == '!') {
|
||||
neg = 1;
|
||||
@@ -1571,12 +1572,27 @@ static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name,
|
||||
if (*name) {
|
||||
int j, len;
|
||||
len = strlen(name);
|
||||
+ for (j = 0; j < len && j < trash.size; j++)
|
||||
+ trash.str[j] = tolower(name[j]);
|
||||
+ if (j >= trash.size)
|
||||
+ return order;
|
||||
+ trash.str[j] = 0;
|
||||
+
|
||||
+ /* Check for duplicates. */
|
||||
+ if (wild)
|
||||
+ node = ebst_lookup(&s->sni_w_ctx, trash.str);
|
||||
+ else
|
||||
+ node = ebst_lookup(&s->sni_ctx, trash.str);
|
||||
+ for (; node; node = ebmb_next_dup(node)) {
|
||||
+ sc = ebmb_entry(node, struct sni_ctx, name);
|
||||
+ if (sc->ctx == ctx && sc->neg == neg)
|
||||
+ return order;
|
||||
+ }
|
||||
+
|
||||
sc = malloc(sizeof(struct sni_ctx) + len + 1);
|
||||
if (!sc)
|
||||
return order;
|
||||
- for (j = 0; j < len; j++)
|
||||
- sc->name.key[j] = tolower(name[j]);
|
||||
- sc->name.key[len] = 0;
|
||||
+ memcpy(sc->name.key, trash.str, len + 1);
|
||||
sc->ctx = ctx;
|
||||
sc->order = order++;
|
||||
sc->neg = neg;
|
||||
--
|
||||
2.7.3
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
From 03c706d71e2d314670d2ebb4dfa48fd3b793b361 Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Tue, 25 Oct 2016 15:50:47 +0200
|
||||
Subject: [PATCH 12/26] BUG/MINOR: systemd: make the wrapper return a non-null
|
||||
status code on error
|
||||
|
||||
When execv() fails to execute the haproxy executable, it's important to
|
||||
return an error instead of pretending everything is cool. This fix should
|
||||
be backported to 1.6 and 1.5 in order to improve the overall reliability
|
||||
under systemd.
|
||||
(cherry picked from commit 7643d09dca4d0eed97ba3c29d4f4fd1f037f96ae)
|
||||
---
|
||||
src/haproxy-systemd-wrapper.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/haproxy-systemd-wrapper.c b/src/haproxy-systemd-wrapper.c
|
||||
index d118ec6..a78e75b 100644
|
||||
--- a/src/haproxy-systemd-wrapper.c
|
||||
+++ b/src/haproxy-systemd-wrapper.c
|
||||
@@ -94,7 +94,7 @@ static void spawn_haproxy(char **pid_strv, int nb_pid)
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
execv(argv[0], argv);
|
||||
- exit(0);
|
||||
+ exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.7.3
|
||||
|
|
@ -1,117 +0,0 @@
|
|||
From 7a7eada6f4ecfc54325a18cf20c3035994a901c4 Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Tue, 25 Oct 2016 16:49:31 +0200
|
||||
Subject: [PATCH 13/26] BUG/MINOR: systemd: always restore signals before
|
||||
execve()
|
||||
|
||||
Since signals are inherited, we must restore them before calling execve()
|
||||
and intercept them again after a failed execve(). In order to cleanly deal
|
||||
with the SIGUSR2/SIGHUP loops where we re-exec the wrapper, we ignore these
|
||||
two signals during a re-exec, and restore them to defaults when spawning
|
||||
haproxy.
|
||||
|
||||
This should be backported to 1.6 and 1.5.
|
||||
(cherry picked from commit 4351ea61fbddf88c960179d60b0e0f1b090f0b70)
|
||||
---
|
||||
src/haproxy-systemd-wrapper.c | 49 ++++++++++++++++++++++++++++++++++++-------
|
||||
1 file changed, 41 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/src/haproxy-systemd-wrapper.c b/src/haproxy-systemd-wrapper.c
|
||||
index a78e75b..84d2e17 100644
|
||||
--- a/src/haproxy-systemd-wrapper.c
|
||||
+++ b/src/haproxy-systemd-wrapper.c
|
||||
@@ -28,6 +28,11 @@ static char *pid_file = "/run/haproxy.pid";
|
||||
static int wrapper_argc;
|
||||
static char **wrapper_argv;
|
||||
|
||||
+static void setup_signal_handler();
|
||||
+static void pause_signal_handler();
|
||||
+static void reset_signal_handler();
|
||||
+
|
||||
+
|
||||
/* returns the path to the haproxy binary into <buffer>, whose size indicated
|
||||
* in <buffer_size> must be at least 1 byte long.
|
||||
*/
|
||||
@@ -76,6 +81,8 @@ static void spawn_haproxy(char **pid_strv, int nb_pid)
|
||||
char **argv = calloc(4 + main_argc + nb_pid + 1, sizeof(char *));
|
||||
int i;
|
||||
int argno = 0;
|
||||
+
|
||||
+ reset_signal_handler();
|
||||
locate_haproxy(haproxy_bin, 512);
|
||||
argv[argno++] = haproxy_bin;
|
||||
for (i = 0; i < main_argc; ++i)
|
||||
@@ -127,6 +134,34 @@ static void signal_handler(int signum)
|
||||
caught_signal = signum;
|
||||
}
|
||||
|
||||
+static void setup_signal_handler()
|
||||
+{
|
||||
+ struct sigaction sa;
|
||||
+
|
||||
+ memset(&sa, 0, sizeof(struct sigaction));
|
||||
+ sa.sa_handler = &signal_handler;
|
||||
+ sigaction(SIGUSR2, &sa, NULL);
|
||||
+ sigaction(SIGHUP, &sa, NULL);
|
||||
+ sigaction(SIGINT, &sa, NULL);
|
||||
+ sigaction(SIGTERM, &sa, NULL);
|
||||
+}
|
||||
+
|
||||
+static void pause_signal_handler()
|
||||
+{
|
||||
+ signal(SIGUSR2, SIG_IGN);
|
||||
+ signal(SIGHUP, SIG_IGN);
|
||||
+ signal(SIGINT, SIG_DFL);
|
||||
+ signal(SIGTERM, SIG_DFL);
|
||||
+}
|
||||
+
|
||||
+static void reset_signal_handler()
|
||||
+{
|
||||
+ signal(SIGUSR2, SIG_DFL);
|
||||
+ signal(SIGHUP, SIG_DFL);
|
||||
+ signal(SIGINT, SIG_DFL);
|
||||
+ signal(SIGTERM, SIG_DFL);
|
||||
+}
|
||||
+
|
||||
/* handles SIGUSR2 and SIGHUP only */
|
||||
static void do_restart(int sig)
|
||||
{
|
||||
@@ -134,7 +169,11 @@ static void do_restart(int sig)
|
||||
fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: re-executing on %s.\n",
|
||||
sig == SIGUSR2 ? "SIGUSR2" : "SIGHUP");
|
||||
|
||||
+ /* don't let the other process take one of those signals by accident */
|
||||
+ pause_signal_handler();
|
||||
execv(wrapper_argv[0], wrapper_argv);
|
||||
+ /* failed, let's reinstall the signal handler and continue */
|
||||
+ setup_signal_handler();
|
||||
}
|
||||
|
||||
/* handles SIGTERM and SIGINT only */
|
||||
@@ -168,7 +207,8 @@ static void init(int argc, char **argv)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int status;
|
||||
- struct sigaction sa;
|
||||
+
|
||||
+ setup_signal_handler();
|
||||
|
||||
wrapper_argc = argc;
|
||||
wrapper_argv = argv;
|
||||
@@ -176,13 +216,6 @@ int main(int argc, char **argv)
|
||||
--argc; ++argv;
|
||||
init(argc, argv);
|
||||
|
||||
- memset(&sa, 0, sizeof(struct sigaction));
|
||||
- sa.sa_handler = &signal_handler;
|
||||
- sigaction(SIGUSR2, &sa, NULL);
|
||||
- sigaction(SIGHUP, &sa, NULL);
|
||||
- sigaction(SIGINT, &sa, NULL);
|
||||
- sigaction(SIGTERM, &sa, NULL);
|
||||
-
|
||||
if (getenv(REEXEC_FLAG) != NULL) {
|
||||
/* We are being re-executed: restart HAProxy gracefully */
|
||||
int i;
|
||||
--
|
||||
2.7.3
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
From 106cb89907ea6eab0073708bb8d6f56d7fc64509 Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Tue, 25 Oct 2016 17:05:56 +0200
|
||||
Subject: [PATCH 14/26] BUG/MINOR: systemd: check return value of calloc()
|
||||
|
||||
The wrapper is not the best reliable thing in the universe, so start
|
||||
by adding at least the minimum expected controls :-/
|
||||
|
||||
To be backported to 1.5 and 1.6.
|
||||
(cherry picked from commit 3747ea07ce6b647b86559383f7d09b42550d42f3)
|
||||
---
|
||||
src/haproxy-systemd-wrapper.c | 10 ++++++++--
|
||||
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/haproxy-systemd-wrapper.c b/src/haproxy-systemd-wrapper.c
|
||||
index 84d2e17..15c48ca 100644
|
||||
--- a/src/haproxy-systemd-wrapper.c
|
||||
+++ b/src/haproxy-systemd-wrapper.c
|
||||
@@ -77,11 +77,17 @@ static void spawn_haproxy(char **pid_strv, int nb_pid)
|
||||
|
||||
pid = fork();
|
||||
if (!pid) {
|
||||
- /* 3 for "haproxy -Ds -sf" */
|
||||
- char **argv = calloc(4 + main_argc + nb_pid + 1, sizeof(char *));
|
||||
+ char **argv;
|
||||
int i;
|
||||
int argno = 0;
|
||||
|
||||
+ /* 3 for "haproxy -Ds -sf" */
|
||||
+ argv = calloc(4 + main_argc + nb_pid + 1, sizeof(char *));
|
||||
+ if (!argv) {
|
||||
+ fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: failed to calloc(), please try again later.\n");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
reset_signal_handler();
|
||||
locate_haproxy(haproxy_bin, 512);
|
||||
argv[argno++] = haproxy_bin;
|
||||
--
|
||||
2.7.3
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
From 3bc0a399d2875e9e0627a70906c1403eef60ec60 Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Tue, 25 Oct 2016 16:51:40 +0200
|
||||
Subject: [PATCH 15/26] MINOR: systemd: report it when execve() fails
|
||||
|
||||
It's important to know that a signal sent to the wrapper had no effect
|
||||
because something failed during execve(). Ideally more info (strerror)
|
||||
should be reported. It would be nice to backport this to 1.6 and 1.5.
|
||||
(cherry picked from commit a785269b4e09114224062081f02b443b6008c524)
|
||||
---
|
||||
src/haproxy-systemd-wrapper.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/src/haproxy-systemd-wrapper.c b/src/haproxy-systemd-wrapper.c
|
||||
index 15c48ca..f4fcab1 100644
|
||||
--- a/src/haproxy-systemd-wrapper.c
|
||||
+++ b/src/haproxy-systemd-wrapper.c
|
||||
@@ -107,8 +107,12 @@ static void spawn_haproxy(char **pid_strv, int nb_pid)
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
execv(argv[0], argv);
|
||||
+ fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: execv(%s) failed, please try again later.\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
+ else if (pid == -1) {
|
||||
+ fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: failed to fork(), please try again later.\n");
|
||||
+ }
|
||||
}
|
||||
|
||||
static int read_pids(char ***pid_strv)
|
||||
@@ -180,6 +184,7 @@ static void do_restart(int sig)
|
||||
execv(wrapper_argv[0], wrapper_argv);
|
||||
/* failed, let's reinstall the signal handler and continue */
|
||||
setup_signal_handler();
|
||||
+ fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: re-exec(%s) failed.\n", wrapper_argv[0]);
|
||||
}
|
||||
|
||||
/* handles SIGTERM and SIGINT only */
|
||||
--
|
||||
2.7.3
|
||||
|
|
@ -1,144 +0,0 @@
|
|||
From ff81ac47267c4e0227d1e3fbc5b1dedfd81a2a2f Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Tue, 25 Oct 2016 17:20:24 +0200
|
||||
Subject: [PATCH 16/26] BUG/MEDIUM: systemd: let the wrapper know that haproxy
|
||||
has completed or failed
|
||||
|
||||
Pierre Cheynier found that there's a persistent issue with the systemd
|
||||
wrapper. Too fast reloads can lead to certain old processes not being
|
||||
signaled at all and continuing to run. The problem was tracked down as
|
||||
a race between the startup and the signal processing : nothing prevents
|
||||
the wrapper from starting new processes while others are still starting,
|
||||
and the resulting pid file will only contain the latest pids in this
|
||||
case. This can happen with large configs and/or when a lot of SSL
|
||||
certificates are involved.
|
||||
|
||||
In order to solve this we want the wrapper to wait for the new processes
|
||||
to complete their startup. But we also want to ensure it doesn't wait for
|
||||
nothing in case of error.
|
||||
|
||||
The solution found here is to create a pipe between the wrapper and the
|
||||
sub-processes. The wrapper waits on the pipe and the sub-processes are
|
||||
expected to close this pipe once they completed their startup. That way
|
||||
we don't queue up new processes until the previous ones have registered
|
||||
their pids to the pid file. And if anything goes wrong, the wrapper is
|
||||
immediately released. The only thing is that we need the sub-processes
|
||||
to know the pipe's file descriptor. We pass it in an environment variable
|
||||
called HAPROXY_WRAPPER_FD.
|
||||
|
||||
It was confirmed both by Pierre and myself that this completely solves
|
||||
the "zombie" process issue so that only the new processes continue to
|
||||
listen on the sockets.
|
||||
|
||||
It seems that in the future this stuff could be moved to the haproxy
|
||||
master process, also getting rid of an environment variable.
|
||||
|
||||
This fix needs to be backported to 1.6 and 1.5.
|
||||
(cherry picked from commit b957109727f7fed556c049d40bacf45f0df211db)
|
||||
---
|
||||
src/haproxy-systemd-wrapper.c | 36 ++++++++++++++++++++++++++++++++++++
|
||||
src/haproxy.c | 10 ++++++++++
|
||||
2 files changed, 46 insertions(+)
|
||||
|
||||
diff --git a/src/haproxy-systemd-wrapper.c b/src/haproxy-systemd-wrapper.c
|
||||
index f4fcab1..b426f96 100644
|
||||
--- a/src/haproxy-systemd-wrapper.c
|
||||
+++ b/src/haproxy-systemd-wrapper.c
|
||||
@@ -65,16 +65,30 @@ static void locate_haproxy(char *buffer, size_t buffer_size)
|
||||
return;
|
||||
}
|
||||
|
||||
+/* Note: this function must not exit in case of error (except in the child), as
|
||||
+ * it is only dedicated the starting a new haproxy process. By keeping the
|
||||
+ * process alive it will ensure that future signal delivery may get rid of
|
||||
+ * the issue. If the first startup fails, the wrapper will notice it and
|
||||
+ * return an error thanks to wait() returning ECHILD.
|
||||
+ */
|
||||
static void spawn_haproxy(char **pid_strv, int nb_pid)
|
||||
{
|
||||
char haproxy_bin[512];
|
||||
pid_t pid;
|
||||
int main_argc;
|
||||
char **main_argv;
|
||||
+ int pipefd[2];
|
||||
+ char fdstr[20];
|
||||
+ int ret;
|
||||
|
||||
main_argc = wrapper_argc - 1;
|
||||
main_argv = wrapper_argv + 1;
|
||||
|
||||
+ if (pipe(pipefd) != 0) {
|
||||
+ fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: failed to create a pipe, please try again later.\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
pid = fork();
|
||||
if (!pid) {
|
||||
char **argv;
|
||||
@@ -89,6 +103,15 @@ static void spawn_haproxy(char **pid_strv, int nb_pid)
|
||||
}
|
||||
|
||||
reset_signal_handler();
|
||||
+
|
||||
+ close(pipefd[0]); /* close the read side */
|
||||
+
|
||||
+ snprintf(fdstr, sizeof(fdstr), "%d", pipefd[1]);
|
||||
+ if (setenv("HAPROXY_WRAPPER_FD", fdstr, 1) != 0) {
|
||||
+ fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: failed to setenv(), please try again later.\n");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
locate_haproxy(haproxy_bin, 512);
|
||||
argv[argno++] = haproxy_bin;
|
||||
for (i = 0; i < main_argc; ++i)
|
||||
@@ -113,6 +136,19 @@ static void spawn_haproxy(char **pid_strv, int nb_pid)
|
||||
else if (pid == -1) {
|
||||
fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: failed to fork(), please try again later.\n");
|
||||
}
|
||||
+
|
||||
+ /* The parent closes the write side and waits for the child to close it
|
||||
+ * as well. Also deal the case where the fd would unexpectedly be 1 or 2
|
||||
+ * by silently draining all data.
|
||||
+ */
|
||||
+ close(pipefd[1]);
|
||||
+
|
||||
+ do {
|
||||
+ char c;
|
||||
+ ret = read(pipefd[0], &c, sizeof(c));
|
||||
+ } while ((ret > 0) || (ret == -1 && errno == EINTR));
|
||||
+ /* the child has finished starting up */
|
||||
+ close(pipefd[0]);
|
||||
}
|
||||
|
||||
static int read_pids(char ***pid_strv)
|
||||
diff --git a/src/haproxy.c b/src/haproxy.c
|
||||
index a657dc4..2d476f2 100644
|
||||
--- a/src/haproxy.c
|
||||
+++ b/src/haproxy.c
|
||||
@@ -1843,6 +1843,7 @@ int main(int argc, char **argv)
|
||||
int ret = 0;
|
||||
int *children = calloc(global.nbproc, sizeof(int));
|
||||
int proc;
|
||||
+ char *wrapper_fd;
|
||||
|
||||
/* the father launches the required number of processes */
|
||||
for (proc = 0; proc < global.nbproc; proc++) {
|
||||
@@ -1879,6 +1880,15 @@ int main(int argc, char **argv)
|
||||
close(pidfd);
|
||||
}
|
||||
|
||||
+ /* each child must notify the wrapper that it's ready by closing the requested fd */
|
||||
+ wrapper_fd = getenv("HAPROXY_WRAPPER_FD");
|
||||
+ if (wrapper_fd) {
|
||||
+ int pipe_fd = atoi(wrapper_fd);
|
||||
+
|
||||
+ if (pipe_fd >= 0)
|
||||
+ close(pipe_fd);
|
||||
+ }
|
||||
+
|
||||
/* We won't ever use this anymore */
|
||||
free(oldpids); oldpids = NULL;
|
||||
free(global.chroot); global.chroot = NULL;
|
||||
--
|
||||
2.7.3
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
From 4fc2ce4a4bb83862679e40c09c684dbf266099f2 Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Wed, 10 Aug 2016 18:24:48 +0200
|
||||
Subject: [PATCH 17/26] BUILD: protocol: fix some build errors on OpenBSD
|
||||
|
||||
Building 1.6 and above on OpenBSD 5.2 fails due to protocol.c not
|
||||
including sys/types.h before sys/socket.h :
|
||||
|
||||
In file included from src/protocol.c:14:
|
||||
/usr/include/sys/socket.h:162: error: expected specifier-qualifier-list before 'u_int8_t'
|
||||
|
||||
This fix needs to be backported to 1.6.
|
||||
(cherry picked from commit a6e3be7ae977ba907ec6ed028c5ab50a6a51886a)
|
||||
---
|
||||
src/protocol.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/src/protocol.c b/src/protocol.c
|
||||
index 3caccb6..7884ef7 100644
|
||||
--- a/src/protocol.c
|
||||
+++ b/src/protocol.c
|
||||
@@ -10,6 +10,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
+#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <common/config.h>
|
||||
--
|
||||
2.7.3
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
From 27f28950d4f9e44e776db5a5d2bc8d07df45eb30 Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Wed, 10 Aug 2016 18:30:56 +0200
|
||||
Subject: [PATCH 18/26] BUILD: log: iovec requires to include sys/uio.h on
|
||||
OpenBSD
|
||||
|
||||
The following commit merged into 1.6-dev6 broke the build on OpenBSD :
|
||||
|
||||
609ac2a ("MEDIUM: log: replace sendto() with sendmsg() in __send_log()")
|
||||
|
||||
Including sys/uio.h is enough to fix this. This fix needs to be backported
|
||||
to 1.6.
|
||||
(cherry picked from commit 077edcba2e5c25524b720f905417d9f0616cd252)
|
||||
---
|
||||
src/log.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/src/log.c b/src/log.c
|
||||
index 1ddc06d..293a034 100644
|
||||
--- a/src/log.c
|
||||
+++ b/src/log.c
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/time.h>
|
||||
+#include <sys/uio.h>
|
||||
|
||||
#include <common/config.h>
|
||||
#include <common/compat.h>
|
||||
--
|
||||
2.7.3
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
From 2a63a2b7e32bba4a33c5f4081647124565929f6a Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Wed, 10 Aug 2016 18:42:17 +0200
|
||||
Subject: [PATCH 19/26] BUILD: tcp: do not include netinet/ip.h for IP_TTL
|
||||
|
||||
On OpenBSD, netinet/ip.h fails unless in_systm.h is included. This
|
||||
include was added by the silent-drop feature introduced with commit
|
||||
2d392c2 ("MEDIUM: tcp: add new tcp action "silent-drop"") in 1.6-dev6,
|
||||
but we don't need it, IP_TTL is defined in netinet/in.h, so let's drop
|
||||
this useless include.
|
||||
|
||||
This fix needs to be backported to 1.6.
|
||||
(cherry picked from commit 7f3e3c0159401cdf47575bc82304696b3a98a2ab)
|
||||
---
|
||||
src/proto_tcp.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
|
||||
index 0f20fde..83b862a 100644
|
||||
--- a/src/proto_tcp.c
|
||||
+++ b/src/proto_tcp.c
|
||||
@@ -31,7 +31,6 @@
|
||||
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/in.h>
|
||||
-#include <netinet/ip.h>
|
||||
|
||||
#include <common/cfgparse.h>
|
||||
#include <common/compat.h>
|
||||
--
|
||||
2.7.3
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
From a581cf03110f13c61faeaf87efa5b4e2777087d0 Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Wed, 10 Aug 2016 19:29:09 +0200
|
||||
Subject: [PATCH 20/26] BUILD: checks: remove the last strcat and eliminate a
|
||||
warning on OpenBSD
|
||||
|
||||
OpenBSD emits warnings on usages of strcpy, strcat and sprintf (and
|
||||
probably a few others). Here we have a single such warning in all the code
|
||||
reintroduced by commit 0ba0e4a ("MEDIUM: Support sending email alerts") in
|
||||
1.6-dev1. Let's get rid of it, the open-coding of strcat is as small as its
|
||||
usage and the the result is even more efficient.
|
||||
|
||||
This fix needs to be backported to 1.6.
|
||||
(cherry picked from commit 64345aaaf0dc2739983902cce4667089ad926a49)
|
||||
---
|
||||
src/checks.c | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/checks.c b/src/checks.c
|
||||
index 80b2fc3..55c13a9 100644
|
||||
--- a/src/checks.c
|
||||
+++ b/src/checks.c
|
||||
@@ -3164,6 +3164,8 @@ static int add_tcpcheck_expect_str(struct list *list, const char *str)
|
||||
static int add_tcpcheck_send_strs(struct list *list, const char * const *strs)
|
||||
{
|
||||
struct tcpcheck_rule *tcpcheck;
|
||||
+ const char *in;
|
||||
+ char *dst;
|
||||
int i;
|
||||
|
||||
tcpcheck = calloc(1, sizeof *tcpcheck);
|
||||
@@ -3181,10 +3183,11 @@ static int add_tcpcheck_send_strs(struct list *list, const char * const *strs)
|
||||
free(tcpcheck);
|
||||
return 0;
|
||||
}
|
||||
- tcpcheck->string[0] = '\0';
|
||||
|
||||
+ dst = tcpcheck->string;
|
||||
for (i = 0; strs[i]; i++)
|
||||
- strcat(tcpcheck->string, strs[i]);
|
||||
+ for (in = strs[i]; (*dst = *in++); dst++);
|
||||
+ *dst = 0;
|
||||
|
||||
LIST_ADDQ(list, &tcpcheck->list);
|
||||
return 1;
|
||||
--
|
||||
2.7.3
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
From a19f5bfb0d1e606dc2eb80af903c229ca41d5057 Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Wed, 10 Aug 2016 21:21:57 +0200
|
||||
Subject: [PATCH 21/26] BUILD: poll: remove unused hap_fd_isset() which causes
|
||||
a warning with clang
|
||||
|
||||
Clang reports that this function is not used :
|
||||
|
||||
src/ev_poll.c:34:28: warning: unused function 'hap_fd_isset' [-Wunused-function]
|
||||
static inline unsigned int hap_fd_isset(int fd, unsigned int *evts)
|
||||
|
||||
It's been true since the rework of the pollers in 1.5 and it's unlikely we'll
|
||||
ever need it anymore, so better remove it now to provide clean builds.
|
||||
|
||||
This fix can be backported to 1.6 and 1.5 now.
|
||||
(cherry picked from commit 091e86e1ee8ec51bd5a3c1935666a822a51b9051)
|
||||
---
|
||||
src/ev_poll.c | 5 -----
|
||||
1 file changed, 5 deletions(-)
|
||||
|
||||
diff --git a/src/ev_poll.c b/src/ev_poll.c
|
||||
index 44a2b9b..80d88eb 100644
|
||||
--- a/src/ev_poll.c
|
||||
+++ b/src/ev_poll.c
|
||||
@@ -31,11 +31,6 @@ static unsigned int *fd_evts[2];
|
||||
static struct pollfd *poll_events = NULL;
|
||||
|
||||
|
||||
-static inline unsigned int hap_fd_isset(int fd, unsigned int *evts)
|
||||
-{
|
||||
- return evts[fd / (8*sizeof(*evts))] & (1U << (fd & (8*sizeof(*evts) - 1)));
|
||||
-}
|
||||
-
|
||||
static inline void hap_fd_set(int fd, unsigned int *evts)
|
||||
{
|
||||
evts[fd / (8*sizeof(*evts))] |= 1U << (fd & (8*sizeof(*evts) - 1));
|
||||
--
|
||||
2.7.3
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
From e871cc2f15ad121e1e840191f59c6c86d6d0580d Mon Sep 17 00:00:00 2001
|
||||
From: David Carlier <devnexen@gmail.com>
|
||||
Date: Mon, 22 Aug 2016 23:27:42 +0100
|
||||
Subject: [PATCH 22/26] MINOR: cfgparse: few memory leaks fixes.
|
||||
|
||||
Some minor memory leak during the config parsing.
|
||||
(cherry picked from commit 70d604593d507f50fd99cebecee4b2c47c1d9b73)
|
||||
---
|
||||
src/cfgparse.c | 7 ++++++-
|
||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/cfgparse.c b/src/cfgparse.c
|
||||
index f2a104d..b8289a2 100644
|
||||
--- a/src/cfgparse.c
|
||||
+++ b/src/cfgparse.c
|
||||
@@ -1597,6 +1597,7 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
|
||||
if (logsrv->format < 0) {
|
||||
Alert("parsing [%s:%d] : unknown log format '%s'\n", file, linenum, args[arg+3]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
+ free(logsrv);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -6777,9 +6778,10 @@ cfg_parse_users(const char *file, int linenum, char **args, int kwm)
|
||||
}
|
||||
|
||||
ag->name = strdup(args[1]);
|
||||
- if (!ag) {
|
||||
+ if (!ag->name) {
|
||||
Alert("parsing [%s:%d]: out of memory.\n", file, linenum);
|
||||
err_code |= ERR_ALERT | ERR_ABORT;
|
||||
+ free(ag);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -6794,6 +6796,9 @@ cfg_parse_users(const char *file, int linenum, char **args, int kwm)
|
||||
Alert("parsing [%s:%d]: '%s' only supports 'users' option.\n",
|
||||
file, linenum, args[0]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
+ free(ag->groupusers);
|
||||
+ free(ag->name);
|
||||
+ free(ag);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
--
|
||||
2.7.3
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
From 5370c6774a333b2b3989639275d4093fdc541db9 Mon Sep 17 00:00:00 2001
|
||||
From: Bertrand Jacquin <bertrand@jacquin.bzh>
|
||||
Date: Thu, 6 Oct 2016 00:32:39 +0100
|
||||
Subject: [PATCH 23/26] MINOR: build: Allow linking to device-atlas library
|
||||
file
|
||||
|
||||
DeviceAtlas might be installed in a location where a user might not have
|
||||
enough permissions to write json.o and dac.o
|
||||
(cherry picked from commit 3a2661d6b4218704c828c8a712c87d651bfe29b5)
|
||||
---
|
||||
Makefile | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 1d0f2bc..0242cae 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -615,8 +615,12 @@ endif
|
||||
DEVICEATLAS_SRC =
|
||||
DEVICEATLAS_INC = $(DEVICEATLAS_SRC)
|
||||
DEVICEATLAS_LIB = $(DEVICEATLAS_SRC)
|
||||
+ifeq ($(DEVICEATLAS_SRC),)
|
||||
+OPTIONS_LDFLAGS += -lda
|
||||
+else
|
||||
OPTIONS_OBJS += $(DEVICEATLAS_LIB)/json.o
|
||||
OPTIONS_OBJS += $(DEVICEATLAS_LIB)/dac.o
|
||||
+endif
|
||||
OPTIONS_OBJS += src/da.o
|
||||
OPTIONS_CFLAGS += -DUSE_DEVICEATLAS $(if $(DEVICEATLAS_INC),-I$(DEVICEATLAS_INC))
|
||||
BUILD_OPTIONS += $(call ignore_implicit,USE_DEVICEATLAS)
|
||||
--
|
||||
2.7.3
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
From f95dc972e2e9e3c245862e45336ff4f014ad5666 Mon Sep 17 00:00:00 2001
|
||||
From: Jorrit Schippers <jorrit@ncode.nl>
|
||||
Date: Sat, 9 Apr 2016 20:30:38 +0200
|
||||
Subject: [PATCH 24/26] DOC: Fix typo in description of `-st` parameter in man
|
||||
page
|
||||
|
||||
extra "wait".
|
||||
(cherry picked from commit 1458fdbe974562158fc40fd72d745d5fd644c939)
|
||||
---
|
||||
doc/haproxy.1 | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/doc/haproxy.1 b/doc/haproxy.1
|
||||
index a836d5d..20c9343 100644
|
||||
--- a/doc/haproxy.1
|
||||
+++ b/doc/haproxy.1
|
||||
@@ -149,9 +149,9 @@ PIDs. Technically speaking, \fBSIGTTOU\fP and \fBSIGUSR1\fP are sent.
|
||||
.TP
|
||||
\fB\-st <pidlist>\fP
|
||||
Send TERMINATE signal to the pids in pidlist after startup. The processes
|
||||
-which receive this signal will wait immediately terminate, closing all
|
||||
-active sessions. This option must be specified last, followed by any number
|
||||
-of PIDs. Technically speaking, \fBSIGTTOU\fP and \fBSIGTERM\fP are sent.
|
||||
+which receive this signal will terminate immediately, closing all active
|
||||
+sessions. This option must be specified last, followed by any number of
|
||||
+PIDs. Technically speaking, \fBSIGTTOU\fP and \fBSIGTERM\fP are sent.
|
||||
|
||||
.SH LOGGING
|
||||
Since HAProxy can run inside a chroot, it cannot reliably access /dev/log.
|
||||
--
|
||||
2.7.3
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
From 6026323cd0c235d6ab7ec039e5d735e7ea2e28bf Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Mon, 31 Oct 2016 17:32:20 +0100
|
||||
Subject: [PATCH 25/26] BUG/MEDIUM: peers: on shutdown, wake up the appctx, not
|
||||
the stream
|
||||
|
||||
This part was missed when peers were ported to the new applet
|
||||
infrastructure in 1.6, the main stream is woken up instead of the
|
||||
appctx. This creates a race condition by which it is possible to
|
||||
wake the stream at the wrong moment and miss an event. This bug
|
||||
might be at least partially responsible for some of the CLOSE_WAIT
|
||||
that were reported on peers session upon reload in version 1.6.
|
||||
|
||||
This fix must be backported to 1.6.
|
||||
(cherry picked from commit 78c0c50705a5e9d48607b9377adf030bb9d97b34)
|
||||
---
|
||||
src/peers.c | 4 +---
|
||||
1 file changed, 1 insertion(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/peers.c b/src/peers.c
|
||||
index 7e1523f..db1f608 100644
|
||||
--- a/src/peers.c
|
||||
+++ b/src/peers.c
|
||||
@@ -1637,11 +1637,9 @@ static void peer_session_forceshutdown(struct stream * stream)
|
||||
if (ps)
|
||||
ps->reconnect = tick_add(now_ms, MS_TO_TICKS(50 + random() % 2000));
|
||||
|
||||
- /* call release to reinit resync states if needed */
|
||||
- peer_session_release(appctx);
|
||||
appctx->st0 = PEER_SESS_ST_END;
|
||||
appctx->ctx.peers.ptr = NULL;
|
||||
- task_wakeup(stream->task, TASK_WOKEN_MSG);
|
||||
+ appctx_wakeup(appctx);
|
||||
}
|
||||
|
||||
/* Pre-configures a peers frontend to accept incoming connections */
|
||||
--
|
||||
2.7.3
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
From ab45181e36b6c4f7d31c5284035937c2d0be37eb Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Mon, 31 Oct 2016 17:46:57 +0100
|
||||
Subject: [PATCH 26/26] BUG/MEDIUM: peers: fix use after free in
|
||||
peer_session_create()
|
||||
|
||||
In case of resource allocation error, peer_session_create() frees
|
||||
everything allocated and returns a pointer to the stream/session that
|
||||
was put back into the free pool. This stream/session is then assigned
|
||||
to ps->{stream,session} with no error control. This means that it is
|
||||
perfectly possible to have a new stream or session being both used for
|
||||
a regular communication and for a peer at the same time.
|
||||
|
||||
In fact it is the only way (for now) to explain a CLOSE_WAIT on peers
|
||||
connections that was caught in this dump with the stream interface in
|
||||
SI_ST_CON state while the error field proves the state ought to have
|
||||
been SI_ST_DIS, very likely indicating two concurrent accesses on the
|
||||
same area :
|
||||
|
||||
0x7dbd50: [31/Oct/2016:17:53:41.267510] id=0 proto=tcpv4
|
||||
flags=0x23006, conn_retries=0, srv_conn=(nil), pend_pos=(nil)
|
||||
frontend=myhost2 (id=4294967295 mode=tcp), listener=? (id=0)
|
||||
backend=<NONE> (id=-1 mode=-) addr=127.0.0.1:41432
|
||||
server=<NONE> (id=-1) addr=127.0.0.1:8521
|
||||
task=0x7dbcd8 (state=0x08 nice=0 calls=2 exp=<NEVER> age=1m5s)
|
||||
si[0]=0x7dbf48 (state=CLO flags=0x4040 endp0=APPCTX:0x7d99c8 exp=<NEVER>, et=0x000)
|
||||
si[1]=0x7dbf68 (state=CON flags=0x50 endp1=CONN:0x7dc0b8 exp=<NEVER>, et=0x020)
|
||||
app0=0x7d99c8 st0=11 st1=0 st2=0 applet=<PEER>
|
||||
co1=0x7dc0b8 ctrl=tcpv4 xprt=RAW data=STRM target=PROXY:0x7fe62028a010
|
||||
flags=0x0020b310 fd=7 fd.state=22 fd.cache=0 updt=0
|
||||
req=0x7dbd60 (f=0x80a020 an=0x0 pipe=0 tofwd=0 total=0)
|
||||
an_exp=<NEVER> rex=<NEVER> wex=<NEVER>
|
||||
buf=0x78a3c0 data=0x78a3d4 o=0 p=0 req.next=0 i=0 size=0
|
||||
res=0x7dbda0 (f=0x80402020 an=0x0 pipe=0 tofwd=0 total=0)
|
||||
an_exp=<NEVER> rex=<NEVER> wex=<NEVER>
|
||||
buf=0x78a3c0 data=0x78a3d4 o=0 p=0 rsp.next=0 i=0 size=0
|
||||
|
||||
Special thanks to Arnaud Gavara who provided lots of valuable input and
|
||||
ran some validation testing on this patch.
|
||||
|
||||
This fix must be backported to 1.6 and 1.5. Note that in 1.5 the
|
||||
session is not assigned from within the function so some extra checks
|
||||
may be needed in the callers.
|
||||
(cherry picked from commit b21d08e2492bfbf9d2341ce9f148cb9845927862)
|
||||
---
|
||||
src/peers.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/peers.c b/src/peers.c
|
||||
index db1f608..c8be59a 100644
|
||||
--- a/src/peers.c
|
||||
+++ b/src/peers.c
|
||||
@@ -1747,7 +1747,7 @@ static struct stream *peer_session_create(struct peers *peers, struct peer *peer
|
||||
out_free_appctx:
|
||||
appctx_free(appctx);
|
||||
out_close:
|
||||
- return s;
|
||||
+ return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
--
|
||||
2.7.3
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
From 0a2117dc29147ed990732d1b2fc9779835820f3e Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Thu, 3 Nov 2016 20:31:40 +0100
|
||||
Subject: [PATCH 27/31] BUG/MEDIUM: systemd-wrapper: return correct exit codes
|
||||
|
||||
Gabriele Cerami reported the the exit codes of the systemd-wrapper are
|
||||
wrong. In short, it directly returns the output of the wait syscall's
|
||||
status, which is a composite value made of error code an signal numbers.
|
||||
In general it contains the signal number on the lower bits and the error
|
||||
code on the higher bits, but exit() truncates it to the lowest 8 bits,
|
||||
causing config validations to incorrectly report a success. Example :
|
||||
|
||||
$ ./haproxy-systemd-wrapper -c -f /dev/null
|
||||
<7>haproxy-systemd-wrapper: executing /tmp/haproxy -c -f /dev/null -Ds
|
||||
Configuration file has no error but will not start (no listener) => exit(2).
|
||||
<5>haproxy-systemd-wrapper: exit, haproxy RC=512
|
||||
$ echo $?
|
||||
0
|
||||
|
||||
If the process is killed however, the signal number is directly reported
|
||||
in the exit code.
|
||||
|
||||
Let's fix all this to ensure that the exit code matches what the shell does,
|
||||
which means that codes 0..127 are for exit codes, codes 128..254 for signals,
|
||||
and code 255 for unknown exit code. Now the return code is correct :
|
||||
|
||||
$ ./haproxy-systemd-wrapper -c -f /dev/null
|
||||
<7>haproxy-systemd-wrapper: executing /tmp/haproxy -c -f /dev/null -Ds
|
||||
Configuration file has no error but will not start (no listener) => exit(2).
|
||||
<5>haproxy-systemd-wrapper: exit, haproxy RC=2
|
||||
$ echo $?
|
||||
2
|
||||
|
||||
$ ./haproxy-systemd-wrapper -f /tmp/cfg.conf
|
||||
<7>haproxy-systemd-wrapper: executing /tmp/haproxy -f /dev/null -Ds
|
||||
^C
|
||||
<5>haproxy-systemd-wrapper: exit, haproxy RC=130
|
||||
$ echo $?
|
||||
130
|
||||
|
||||
This fix must be backported to 1.6 and 1.5.
|
||||
(cherry picked from commit f7659cb10cb0420c7ca06fad1067207021d2a078)
|
||||
---
|
||||
src/haproxy-systemd-wrapper.c | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/src/haproxy-systemd-wrapper.c b/src/haproxy-systemd-wrapper.c
|
||||
index b426f96..f6a9c85 100644
|
||||
--- a/src/haproxy-systemd-wrapper.c
|
||||
+++ b/src/haproxy-systemd-wrapper.c
|
||||
@@ -295,6 +295,16 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
+ /* return either exit code or signal+128 */
|
||||
+ if (WIFEXITED(status))
|
||||
+ status = WEXITSTATUS(status);
|
||||
+ else if (WIFSIGNALED(status))
|
||||
+ status = 128 + WTERMSIG(status);
|
||||
+ else if (WIFSTOPPED(status))
|
||||
+ status = 128 + WSTOPSIG(status);
|
||||
+ else
|
||||
+ status = 255;
|
||||
+
|
||||
fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: exit, haproxy RC=%d\n",
|
||||
status);
|
||||
return status;
|
||||
--
|
||||
2.7.3
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
From 74ffd0cd0cecaeec3cfa848cbc03beb08999cc72 Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Thu, 3 Nov 2016 18:19:49 +0100
|
||||
Subject: [PATCH 28/31] BUG/MEDIUM: srv-state: properly restore the DRAIN state
|
||||
|
||||
There were seveal reports about the DRAIN state not being properly
|
||||
restored upon reload.
|
||||
|
||||
It happens that the condition in the code does exactly the opposite
|
||||
of what the comment says, and the comment is right so the code is
|
||||
wrong.
|
||||
|
||||
It's worth noting that the conditions are complex here due to the 2
|
||||
available methods to set the drain state (CLI/agent, and config's
|
||||
weight). To paraphrase the updated comment in the code, there are
|
||||
two possible reasons for FDRAIN to have been present :
|
||||
- previous config weight was zero
|
||||
- "set server b/s drain" was sent to the CLI
|
||||
|
||||
In the first case, we simply want to drop this drain state if the new
|
||||
weight is not zero anymore, meaning the administrator has intentionally
|
||||
turned the weight back to a positive value to enable the server again
|
||||
after an operation. In the second case, the drain state was forced on
|
||||
the CLI regardless of the config's weight so we don't want a change to
|
||||
the config weight to lose this status. What this means is :
|
||||
- if previous weight was 0 and new one is >0, drop the DRAIN state.
|
||||
- if the previous weight was >0, keep it.
|
||||
|
||||
This fix must be backported to 1.6.
|
||||
(cherry picked from commit 22cace2f4c3cbeca27c1941c647e7ae38ec8c0c0)
|
||||
---
|
||||
src/server.c | 22 +++++++++++++++-------
|
||||
1 file changed, 15 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/src/server.c b/src/server.c
|
||||
index 79b3cb2..b9e72b7 100644
|
||||
--- a/src/server.c
|
||||
+++ b/src/server.c
|
||||
@@ -2093,15 +2093,23 @@ static void srv_update_state(struct server *srv, int version, char **params)
|
||||
/* apply drain mode if server is currently enabled */
|
||||
if (!(srv->admin & SRV_ADMF_FMAINT) && (srv_admin_state & SRV_ADMF_FDRAIN)) {
|
||||
/* The SRV_ADMF_FDRAIN flag is inherited when srv->iweight is 0
|
||||
- * (srv->iweight is the weight set up in configuration)
|
||||
- * so we don't want to apply it when srv_iweight is 0 and
|
||||
- * srv->iweight is greater than 0. Purpose is to give the
|
||||
- * chance to the admin to re-enable this server from configuration
|
||||
- * file by setting a new weight > 0.
|
||||
+ * (srv->iweight is the weight set up in configuration).
|
||||
+ * There are two possible reasons for FDRAIN to have been present :
|
||||
+ * - previous config weight was zero
|
||||
+ * - "set server b/s drain" was sent to the CLI
|
||||
+ *
|
||||
+ * In the first case, we simply want to drop this drain state
|
||||
+ * if the new weight is not zero anymore, meaning the administrator
|
||||
+ * has intentionally turned the weight back to a positive value to
|
||||
+ * enable the server again after an operation. In the second case,
|
||||
+ * the drain state was forced on the CLI regardless of the config's
|
||||
+ * weight so we don't want a change to the config weight to lose this
|
||||
+ * status. What this means is :
|
||||
+ * - if previous weight was 0 and new one is >0, drop the DRAIN state.
|
||||
+ * - if the previous weight was >0, keep it.
|
||||
*/
|
||||
- if ((srv_iweight == 0) && (srv->iweight > 0)) {
|
||||
+ if (srv_iweight > 0 || srv->iweight == 0)
|
||||
srv_adm_set_drain(srv);
|
||||
- }
|
||||
}
|
||||
|
||||
srv->last_change = date.tv_sec - srv_last_time_change;
|
||||
--
|
||||
2.7.3
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
From d6649c499b8ca4fb0bf93153c2a149c78e8a76f8 Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Thu, 3 Nov 2016 18:33:25 +0100
|
||||
Subject: [PATCH 29/31] BUG/MINOR: srv-state: allow to have both CMAINT and
|
||||
FDRAIN flags
|
||||
|
||||
CMAINT indicates that the server was *initially* disabled in the
|
||||
configuration via the "disabled" keyword. FDRAIN indicates that the
|
||||
server was switched to the DRAIN state from the CLI or the agent.
|
||||
This it's perfectly valid to have both of them in the state file,
|
||||
so the parser must not reject this combination.
|
||||
|
||||
This fix must be backported to 1.6.
|
||||
(cherry picked from commit e1bde1492a30f5036ca58248e50c27a9e116d9cc)
|
||||
---
|
||||
src/server.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/src/server.c b/src/server.c
|
||||
index b9e72b7..b0c7bbe 100644
|
||||
--- a/src/server.c
|
||||
+++ b/src/server.c
|
||||
@@ -1961,6 +1961,7 @@ static void srv_update_state(struct server *srv, int version, char **params)
|
||||
srv_admin_state != SRV_ADMF_IMAINT &&
|
||||
srv_admin_state != SRV_ADMF_CMAINT &&
|
||||
srv_admin_state != (SRV_ADMF_CMAINT | SRV_ADMF_FMAINT) &&
|
||||
+ srv_admin_state != (SRV_ADMF_CMAINT | SRV_ADMF_FDRAIN) &&
|
||||
srv_admin_state != SRV_ADMF_FDRAIN &&
|
||||
srv_admin_state != SRV_ADMF_IDRAIN)) {
|
||||
chunk_appendf(msg, ", invalid srv_admin_state value '%s'", params[2]);
|
||||
--
|
||||
2.7.3
|
||||
|
|
@ -1,172 +0,0 @@
|
|||
From c449c9835e7d9e02cf0aeafc482364d5090db543 Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Thu, 3 Nov 2016 19:22:19 +0100
|
||||
Subject: [PATCH 30/31] BUG/MEDIUM: servers: properly propagate the maintenance
|
||||
states during startup
|
||||
|
||||
Right now there is an issue with the way the maintenance flags are
|
||||
propagated upon startup. They are not propagate, just copied from the
|
||||
tracked server. This implies that depending on the server's order, some
|
||||
tracking servers may not be marked down. For example this configuration
|
||||
does not work as expected :
|
||||
|
||||
server s1 1.1.1.1:8000 track s2
|
||||
server s2 1.1.1.1:8000 track s3
|
||||
server s3 1.1.1.1:8000 track s4
|
||||
server s4 wtap:8000 check inter 1s disabled
|
||||
|
||||
It results in s1/s2 being up, and s3/s4 being down, while all of them
|
||||
should be down.
|
||||
|
||||
The only clean way to process this is to run through all "root" servers
|
||||
(those not tracking any other server), and to propagate their state down
|
||||
to all their trackers. This is the same algorithm used to propagate the
|
||||
state changes. It has to be done both to compute the IDRAIN flag and the
|
||||
IMAINT flag. However, doing so requires that tracking servers are not
|
||||
marked as inherited maintenance anymore while parsing the configuration
|
||||
(and given that it is wrong, better drop it).
|
||||
|
||||
This fix also addresses another side effect of the bug above which is
|
||||
that the IDRAIN/IMAINT flags are stored in the state files, and if
|
||||
restored while the tracked server doesn't have the equivalent flag,
|
||||
the servers may end up in a situation where it's impossible to remove
|
||||
these flags. For example in the configuration above, after removing
|
||||
"disabled" on server s4, the other servers would have remained down,
|
||||
and not anymore with this fix. Similarly, the combination of IMAINT
|
||||
or IDRAIN with their respective forced modes was not accepted on
|
||||
reload, which is wrong as well.
|
||||
|
||||
This bug has been present at least since 1.5, maybe even 1.4 (it came
|
||||
with tracking support). The fix needs to be backported there, though
|
||||
the srv-state parts are irrelevant.
|
||||
|
||||
This commit relies on previous patch to silence warnings on startup.
|
||||
(cherry picked from commit 757478e900ebc1e67c1fe060b9b561d276cab3e1)
|
||||
---
|
||||
include/proto/server.h | 1 +
|
||||
src/cfgparse.c | 7 -------
|
||||
src/haproxy.c | 4 ++++
|
||||
src/server.c | 42 +++++++++++++++++++++++++++++++++++++++---
|
||||
4 files changed, 44 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/include/proto/server.h b/include/proto/server.h
|
||||
index d75cc9f..b6572ba 100644
|
||||
--- a/include/proto/server.h
|
||||
+++ b/include/proto/server.h
|
||||
@@ -44,6 +44,7 @@ struct server *server_find_by_id(struct proxy *bk, int id);
|
||||
struct server *server_find_by_name(struct proxy *bk, const char *name);
|
||||
struct server *server_find_best_match(struct proxy *bk, char *name, int id, int *diff);
|
||||
void apply_server_state(void);
|
||||
+void srv_compute_all_admin_states(struct proxy *px);
|
||||
|
||||
/* functions related to server name resolution */
|
||||
int snr_update_srv_status(struct server *s);
|
||||
diff --git a/src/cfgparse.c b/src/cfgparse.c
|
||||
index b8289a2..365b283 100644
|
||||
--- a/src/cfgparse.c
|
||||
+++ b/src/cfgparse.c
|
||||
@@ -8275,13 +8275,6 @@ out_uri_auth_compat:
|
||||
goto next_srv;
|
||||
}
|
||||
|
||||
- /* if the other server is forced disabled, we have to do the same here */
|
||||
- if (srv->admin & SRV_ADMF_MAINT) {
|
||||
- newsrv->admin |= SRV_ADMF_IMAINT;
|
||||
- newsrv->state = SRV_ST_STOPPED;
|
||||
- newsrv->check.health = 0;
|
||||
- }
|
||||
-
|
||||
newsrv->track = srv;
|
||||
newsrv->tracknext = srv->trackers;
|
||||
srv->trackers = newsrv;
|
||||
diff --git a/src/haproxy.c b/src/haproxy.c
|
||||
index 2d476f2..1699132 100644
|
||||
--- a/src/haproxy.c
|
||||
+++ b/src/haproxy.c
|
||||
@@ -566,6 +566,7 @@ void init(int argc, char **argv)
|
||||
struct wordlist *wl;
|
||||
char *progname;
|
||||
char *change_dir = NULL;
|
||||
+ struct proxy *px;
|
||||
|
||||
chunk_init(&trash, malloc(global.tune.bufsize), global.tune.bufsize);
|
||||
alloc_trash_buffers(global.tune.bufsize);
|
||||
@@ -852,6 +853,9 @@ void init(int argc, char **argv)
|
||||
/* Apply server states */
|
||||
apply_server_state();
|
||||
|
||||
+ for (px = proxy; px; px = px->next)
|
||||
+ srv_compute_all_admin_states(px);
|
||||
+
|
||||
global_listener_queue_task = task_new();
|
||||
if (!global_listener_queue_task) {
|
||||
Alert("Out of memory when initializing global task\n");
|
||||
diff --git a/src/server.c b/src/server.c
|
||||
index b0c7bbe..f2923ae 100644
|
||||
--- a/src/server.c
|
||||
+++ b/src/server.c
|
||||
@@ -705,6 +705,40 @@ void srv_clr_admin_flag(struct server *s, enum srv_admin mode)
|
||||
srv_clr_admin_flag(srv, mode);
|
||||
}
|
||||
|
||||
+/* principle: propagate maint and drain to tracking servers. This is useful
|
||||
+ * upon startup so that inherited states are correct.
|
||||
+ */
|
||||
+static void srv_propagate_admin_state(struct server *srv)
|
||||
+{
|
||||
+ struct server *srv2;
|
||||
+
|
||||
+ if (!srv->trackers)
|
||||
+ return;
|
||||
+
|
||||
+ for (srv2 = srv->trackers; srv2; srv2 = srv2->tracknext) {
|
||||
+ if (srv->admin & (SRV_ADMF_MAINT | SRV_ADMF_CMAINT))
|
||||
+ srv_set_admin_flag(srv2, SRV_ADMF_IMAINT);
|
||||
+
|
||||
+ if (srv->admin & SRV_ADMF_DRAIN)
|
||||
+ srv_set_admin_flag(srv2, SRV_ADMF_IDRAIN);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* Compute and propagate the admin states for all servers in proxy <px>.
|
||||
+ * Only servers *not* tracking another one are considered, because other
|
||||
+ * ones will be handled when the server they track is visited.
|
||||
+ */
|
||||
+void srv_compute_all_admin_states(struct proxy *px)
|
||||
+{
|
||||
+ struct server *srv;
|
||||
+
|
||||
+ for (srv = px->srv; srv; srv = srv->next) {
|
||||
+ if (srv->track)
|
||||
+ continue;
|
||||
+ srv_propagate_admin_state(srv);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/* Note: must not be declared <const> as its list will be overwritten.
|
||||
* Please take care of keeping this list alphabetically sorted, doing so helps
|
||||
* all code contributors.
|
||||
@@ -1955,15 +1989,17 @@ static void srv_update_state(struct server *srv, int version, char **params)
|
||||
p = NULL;
|
||||
errno = 0;
|
||||
srv_admin_state = strtol(params[2], &p, 10);
|
||||
+
|
||||
+ /* inherited statuses will be recomputed later */
|
||||
+ srv_admin_state &= ~SRV_ADMF_IDRAIN & ~SRV_ADMF_IMAINT;
|
||||
+
|
||||
if ((p == params[2]) || errno == EINVAL || errno == ERANGE ||
|
||||
(srv_admin_state != 0 &&
|
||||
srv_admin_state != SRV_ADMF_FMAINT &&
|
||||
- srv_admin_state != SRV_ADMF_IMAINT &&
|
||||
srv_admin_state != SRV_ADMF_CMAINT &&
|
||||
srv_admin_state != (SRV_ADMF_CMAINT | SRV_ADMF_FMAINT) &&
|
||||
srv_admin_state != (SRV_ADMF_CMAINT | SRV_ADMF_FDRAIN) &&
|
||||
- srv_admin_state != SRV_ADMF_FDRAIN &&
|
||||
- srv_admin_state != SRV_ADMF_IDRAIN)) {
|
||||
+ srv_admin_state != SRV_ADMF_FDRAIN)) {
|
||||
chunk_appendf(msg, ", invalid srv_admin_state value '%s'", params[2]);
|
||||
}
|
||||
|
||||
--
|
||||
2.7.3
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
From 9c017e541bb3cee2e2884cdc53a4cb4627be5dad Mon Sep 17 00:00:00 2001
|
||||
From: Christopher Faulet <cfaulet@haproxy.com>
|
||||
Date: Wed, 9 Nov 2016 16:15:32 +0100
|
||||
Subject: [PATCH 31/31] BUG: vars: Fix 'set-var' converter because of a typo
|
||||
|
||||
The 'set-var' converter uses function smp_conv_store (vars.c). In this function,
|
||||
we should use the first argument (index 0) to retrieve the variable name and its
|
||||
scope. But because of a typo, we get the scope of the second argument (index
|
||||
1). In this case, there is no second argument. So the scope used was always 0
|
||||
(SCOPE_SESS), always setting the variable in the session scope.
|
||||
|
||||
So, due to this bug, this rules
|
||||
|
||||
tcp-request content accept if { src,set-var(txn.foo) -m found }
|
||||
|
||||
always set the variable 'sess.foo' instead of 'txn.foo'.
|
||||
(cherry picked from commit 0099a8ca9d58cb4cff943bf6374b55b42a23fbfb)
|
||||
---
|
||||
src/vars.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/vars.c b/src/vars.c
|
||||
index a3dd85c..8645905 100644
|
||||
--- a/src/vars.c
|
||||
+++ b/src/vars.c
|
||||
@@ -379,7 +379,7 @@ static inline int sample_store_stream(const char *name, enum vars_scope scope, s
|
||||
/* Returns 0 if fails, else returns 1. */
|
||||
static int smp_conv_store(const struct arg *args, struct sample *smp, void *private)
|
||||
{
|
||||
- return sample_store_stream(args[0].data.var.name, args[1].data.var.scope, smp);
|
||||
+ return sample_store_stream(args[0].data.var.name, args[0].data.var.scope, smp);
|
||||
}
|
||||
|
||||
/* This fucntions check an argument entry and fill it with a variable
|
||||
--
|
||||
2.7.3
|
||||
|
Loading…
Reference in a new issue