aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Heil <heil@terminal-consulting.de>2014-07-10 13:51:27 +0200
committerThomas Heil <heil@terminal-consulting.de>2014-07-10 13:51:27 +0200
commit0661fbcf90658044d268d7e96423dc2d689f3ba0 (patch)
tree9bf722584b1d6fbdec2f86b637558c239c985368
parentc5b89e2ea20c40afbb605bf04cd0cbafdbfa9247 (diff)
haproxy: fixes from upstream
this patch series mainly fixes a lot of reported issues in conjuction with abstract socktet handling, improved the docs about the stats - [PATCH 13/21] BUILD: http: fix isdigit & isspace warnings on Solaris - [PATCH 14/21] BUG/MINOR: listener: set the listener's fd to -1 after - [PATCH 15/21] BUG/MEDIUM: unix: failed abstract socket binding is - [PATCH 16/21] MEDIUM: listener: implement a per-protocol pause() - [PATCH 17/21] MEDIUM: listener: support rebinding during resume() - [PATCH 18/21] BUG/MEDIUM: unix: completely unbind abstract sockets - [PATCH 19/21] DOC: explicitly mention the limits of abstract - [PATCH 20/21] DOC: expand the docs for the provided stats. - [PATCH 21/21] BUG/MEDIUM: backend: Update hash to use unsigned int Signed-off-by: Thomas Heil <heil@terminal-consulting.de>
-rw-r--r--net/haproxy/Makefile2
-rw-r--r--net/haproxy/patches/0013-BUILD-http-fix-isdigit-isspace-warnings-on-Solaris.patch102
-rw-r--r--net/haproxy/patches/0014-BUG-MINOR-listener-set-the-listener-s-fd-to-1-after-.patch32
-rw-r--r--net/haproxy/patches/0015-BUG-MEDIUM-unix-failed-abstract-socket-binding-is-re.patch153
-rw-r--r--net/haproxy/patches/0016-MEDIUM-listener-implement-a-per-protocol-pause-funct.patch124
-rw-r--r--net/haproxy/patches/0017-MEDIUM-listener-support-rebinding-during-resume.patch48
-rw-r--r--net/haproxy/patches/0018-BUG-MEDIUM-unix-completely-unbind-abstract-sockets-d.patch71
-rw-r--r--net/haproxy/patches/0019-DOC-explicitly-mention-the-limits-of-abstract-namesp.patch40
-rw-r--r--net/haproxy/patches/0020-DOC-expand-the-docs-for-the-provided-stats.patch198
-rw-r--r--net/haproxy/patches/0021-BUG-MEDIUM-backend-Update-hash-to-use-unsigned-int-t.patch138
10 files changed, 907 insertions, 1 deletions
diff --git a/net/haproxy/Makefile b/net/haproxy/Makefile
index 859331f3c..cccbe74e1 100644
--- a/net/haproxy/Makefile
+++ b/net/haproxy/Makefile
@@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=haproxy
PKG_VERSION:=1.5.1
-PKG_RELEASE:=12
+PKG_RELEASE:=21
PKG_SOURCE:=haproxy-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=http://haproxy.1wt.eu/download/1.5/src/
PKG_MD5SUM:=49640cf3ddd793a05fbd3394481a1ed4
diff --git a/net/haproxy/patches/0013-BUILD-http-fix-isdigit-isspace-warnings-on-Solaris.patch b/net/haproxy/patches/0013-BUILD-http-fix-isdigit-isspace-warnings-on-Solaris.patch
new file mode 100644
index 000000000..bcd0e45e5
--- /dev/null
+++ b/net/haproxy/patches/0013-BUILD-http-fix-isdigit-isspace-warnings-on-Solaris.patch
@@ -0,0 +1,102 @@
+From 463ae6f09e485faf3d1cdc4daceefe4bcd50b50e Mon Sep 17 00:00:00 2001
+From: Willy Tarreau <w@1wt.eu>
+Date: Tue, 8 Jul 2014 00:59:48 +0200
+Subject: [PATCH 13/21] BUILD: http: fix isdigit & isspace warnings on Solaris
+
+As usual, when touching any is* function, Solaris complains about the
+type of the element being checked. Better backport this to 1.5 since
+nobody knows what the emitted code looks like since macros are used
+instead of functions.
+(cherry picked from commit 506c69a50e8d434b6b0c2c89b0402f220830644d)
+---
+ src/proto_http.c | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/src/proto_http.c b/src/proto_http.c
+index 01fe62d..4a862b0 100644
+--- a/src/proto_http.c
++++ b/src/proto_http.c
+@@ -2143,22 +2143,22 @@ int parse_qvalue(const char *qvalue, const char **end)
+ {
+ int q = 1000;
+
+- if (!isdigit(*qvalue))
++ if (!isdigit((unsigned char)*qvalue))
+ goto out;
+ q = (*qvalue++ - '0') * 1000;
+
+ if (*qvalue++ != '.')
+ goto out;
+
+- if (!isdigit(*qvalue))
++ if (!isdigit((unsigned char)*qvalue))
+ goto out;
+ q += (*qvalue++ - '0') * 100;
+
+- if (!isdigit(*qvalue))
++ if (!isdigit((unsigned char)*qvalue))
+ goto out;
+ q += (*qvalue++ - '0') * 10;
+
+- if (!isdigit(*qvalue))
++ if (!isdigit((unsigned char)*qvalue))
+ goto out;
+ q += (*qvalue++ - '0') * 1;
+ out:
+@@ -11226,7 +11226,7 @@ static int sample_conv_q_prefered(const struct arg *args, struct sample *smp)
+ while (1) {
+
+ /* Jump spaces, quit if the end is detected. */
+- while (al < end && isspace(*al))
++ while (al < end && isspace((unsigned char)*al))
+ al++;
+ if (al >= end)
+ break;
+@@ -11235,7 +11235,7 @@ static int sample_conv_q_prefered(const struct arg *args, struct sample *smp)
+ token = al;
+
+ /* Look for separator: isspace(), ',' or ';'. Next value if 0 length word. */
+- while (al < end && *al != ';' && *al != ',' && !isspace(*al))
++ while (al < end && *al != ';' && *al != ',' && !isspace((unsigned char)*al))
+ al++;
+ if (al == token)
+ goto expect_comma;
+@@ -11264,7 +11264,7 @@ static int sample_conv_q_prefered(const struct arg *args, struct sample *smp)
+ look_for_q:
+
+ /* Jump spaces, quit if the end is detected. */
+- while (al < end && isspace(*al))
++ while (al < end && isspace((unsigned char)*al))
+ al++;
+ if (al >= end)
+ goto process_value;
+@@ -11283,7 +11283,7 @@ look_for_q:
+ al++;
+
+ /* Jump spaces, process value if the end is detected. */
+- while (al < end && isspace(*al))
++ while (al < end && isspace((unsigned char)*al))
+ al++;
+ if (al >= end)
+ goto process_value;
+@@ -11294,7 +11294,7 @@ look_for_q:
+ al++;
+
+ /* Jump spaces, process value if the end is detected. */
+- while (al < end && isspace(*al))
++ while (al < end && isspace((unsigned char)*al))
+ al++;
+ if (al >= end)
+ goto process_value;
+@@ -11305,7 +11305,7 @@ look_for_q:
+ al++;
+
+ /* Jump spaces, process value if the end is detected. */
+- while (al < end && isspace(*al))
++ while (al < end && isspace((unsigned char)*al))
+ al++;
+ if (al >= end)
+ goto process_value;
+--
+1.8.5.5
+
diff --git a/net/haproxy/patches/0014-BUG-MINOR-listener-set-the-listener-s-fd-to-1-after-.patch b/net/haproxy/patches/0014-BUG-MINOR-listener-set-the-listener-s-fd-to-1-after-.patch
new file mode 100644
index 000000000..e5292dac4
--- /dev/null
+++ b/net/haproxy/patches/0014-BUG-MINOR-listener-set-the-listener-s-fd-to-1-after-.patch
@@ -0,0 +1,32 @@
+From fb8bf6324bfe9f36d0be5110fcc13facba4389a8 Mon Sep 17 00:00:00 2001
+From: Willy Tarreau <w@1wt.eu>
+Date: Mon, 7 Jul 2014 18:24:48 +0200
+Subject: [PATCH 14/21] BUG/MINOR: listener: set the listener's fd to -1 after
+ deletion
+
+This is currently harmless, but when stopping a listener, its fd is
+closed but not set to -1, so it is not possible to re-open it again.
+Currently this has no impact but can have after the abstract sockets
+are modified to perform a complete close on soft-reload.
+
+The fix can be backported to 1.5 and may even apply to 1.4 (protocols.c).
+(cherry picked from commit 39447b6a5799a160eae452db920fd0735a78638b)
+---
+ src/listener.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/src/listener.c b/src/listener.c
+index ec3a39b..a82ce81 100644
+--- a/src/listener.c
++++ b/src/listener.c
+@@ -236,6 +236,7 @@ int unbind_listener(struct listener *listener)
+
+ if (listener->state >= LI_PAUSED) {
+ fd_delete(listener->fd);
++ listener->fd = -1;
+ listener->state = LI_ASSIGNED;
+ }
+ return ERR_NONE;
+--
+1.8.5.5
+
diff --git a/net/haproxy/patches/0015-BUG-MEDIUM-unix-failed-abstract-socket-binding-is-re.patch b/net/haproxy/patches/0015-BUG-MEDIUM-unix-failed-abstract-socket-binding-is-re.patch
new file mode 100644
index 000000000..f15c981ae
--- /dev/null
+++ b/net/haproxy/patches/0015-BUG-MEDIUM-unix-failed-abstract-socket-binding-is-re.patch
@@ -0,0 +1,153 @@
+From 58dd0f33fa908e83199d28775bad8ee2f24151a9 Mon Sep 17 00:00:00 2001
+From: Willy Tarreau <w@1wt.eu>
+Date: Mon, 7 Jul 2014 18:36:45 +0200
+Subject: [PATCH 15/21] BUG/MEDIUM: unix: failed abstract socket binding is
+ retryable
+
+Jan Seda noticed that abstract sockets are incompatible with soft reload,
+because the new process cannot bind and immediately fails. This patch marks
+the binding as retryable and not fatal so that the new process can try to
+bind again after sending a signal to the old process.
+
+Note that this fix is not enough to completely solve the problem, but it
+is necessary. This patch should be backported to 1.5.
+(cherry picked from commit 3c5efa2b3268f31cffc2c18887010d4bc906a066)
+---
+ src/proto_uxst.c | 30 ++++++++++++++++++++++++++----
+ 1 file changed, 26 insertions(+), 4 deletions(-)
+
+diff --git a/src/proto_uxst.c b/src/proto_uxst.c
+index c9a52ff..409c659 100644
+--- a/src/proto_uxst.c
++++ b/src/proto_uxst.c
+@@ -166,9 +166,11 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
+ const char *path;
+ int ext, ready;
+ socklen_t ready_len;
+-
++ int err;
+ int ret;
+
++ err = ERR_NONE;
++
+ /* ensure we never return garbage */
+ if (errlen)
+ *errmsg = 0;
+@@ -191,29 +193,34 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
+ if (path[0]) {
+ ret = snprintf(tempname, MAXPATHLEN, "%s.%d.tmp", path, pid);
+ if (ret < 0 || ret >= MAXPATHLEN) {
++ err |= ERR_FATAL | ERR_ALERT;
+ msg = "name too long for UNIX socket";
+ goto err_return;
+ }
+
+ ret = snprintf(backname, MAXPATHLEN, "%s.%d.bak", path, pid);
+ if (ret < 0 || ret >= MAXPATHLEN) {
++ err |= ERR_FATAL | ERR_ALERT;
+ msg = "name too long for UNIX socket";
+ goto err_return;
+ }
+
+ /* 2. clean existing orphaned entries */
+ if (unlink(tempname) < 0 && errno != ENOENT) {
++ err |= ERR_FATAL | ERR_ALERT;
+ msg = "error when trying to unlink previous UNIX socket";
+ goto err_return;
+ }
+
+ if (unlink(backname) < 0 && errno != ENOENT) {
++ err |= ERR_FATAL | ERR_ALERT;
+ msg = "error when trying to unlink previous UNIX socket";
+ goto err_return;
+ }
+
+ /* 3. backup existing socket */
+ if (link(path, backname) < 0 && errno != ENOENT) {
++ err |= ERR_FATAL | ERR_ALERT;
+ msg = "error when trying to preserve previous UNIX socket";
+ goto err_return;
+ }
+@@ -231,24 +238,35 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
+
+ fd = socket(PF_UNIX, SOCK_STREAM, 0);
+ if (fd < 0) {
++ err |= ERR_FATAL | ERR_ALERT;
+ msg = "cannot create UNIX socket";
+ goto err_unlink_back;
+ }
+
+ fd_ready:
+ if (fd >= global.maxsock) {
++ err |= ERR_FATAL | ERR_ALERT;
+ msg = "socket(): not enough free sockets, raise -n argument";
+ goto err_unlink_temp;
+ }
+
+ if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
++ err |= ERR_FATAL | ERR_ALERT;
+ msg = "cannot make UNIX socket non-blocking";
+ goto err_unlink_temp;
+ }
+
+ if (!ext && bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ /* note that bind() creates the socket <tempname> on the file system */
+- msg = "cannot bind UNIX socket";
++ if (errno == EADDRINUSE) {
++ /* the old process might still own it, let's retry */
++ err |= ERR_RETRYABLE | ERR_ALERT;
++ msg = "cannot listen to socket";
++ }
++ else {
++ err |= ERR_FATAL | ERR_ALERT;
++ msg = "cannot bind UNIX socket";
++ }
+ goto err_unlink_temp;
+ }
+
+@@ -261,6 +279,7 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
+ (((listener->bind_conf->ux.uid != -1 || listener->bind_conf->ux.gid != -1) &&
+ (chown(tempname, listener->bind_conf->ux.uid, listener->bind_conf->ux.gid) == -1)) ||
+ (listener->bind_conf->ux.mode != 0 && chmod(tempname, listener->bind_conf->ux.mode) == -1))) {
++ err |= ERR_FATAL | ERR_ALERT;
+ msg = "cannot change UNIX socket ownership";
+ goto err_unlink_temp;
+ }
+@@ -272,6 +291,7 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
+
+ if (!(ext && ready) && /* only listen if not already done by external process */
+ listen(fd, listener->backlog ? listener->backlog : listener->maxconn) < 0) {
++ err |= ERR_FATAL | ERR_ALERT;
+ msg = "cannot listen to UNIX socket";
+ goto err_unlink_temp;
+ }
+@@ -281,6 +301,7 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
+ * backname. Abstract sockets are not renamed.
+ */
+ if (!ext && path[0] && rename(tempname, path) < 0) {
++ err |= ERR_FATAL | ERR_ALERT;
+ msg = "cannot switch final and temporary UNIX sockets";
+ goto err_rename;
+ }
+@@ -303,7 +324,8 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
+ fd_insert(fd);
+ fdtab[fd].iocb = listener->proto->accept;
+ fdtab[fd].owner = listener; /* reference the listener instead of a task */
+- return ERR_NONE;
++ return err;
++
+ err_rename:
+ ret = rename(backname, path);
+ if (ret < 0 && errno == ENOENT)
+@@ -322,7 +344,7 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
+ else
+ snprintf(errmsg, errlen, "%s [fd %d]", msg, fd);
+ }
+- return ERR_FATAL | ERR_ALERT;
++ return err;
+ }
+
+ /* This function closes the UNIX sockets for the specified listener.
+--
+1.8.5.5
+
diff --git a/net/haproxy/patches/0016-MEDIUM-listener-implement-a-per-protocol-pause-funct.patch b/net/haproxy/patches/0016-MEDIUM-listener-implement-a-per-protocol-pause-funct.patch
new file mode 100644
index 000000000..0ee82173e
--- /dev/null
+++ b/net/haproxy/patches/0016-MEDIUM-listener-implement-a-per-protocol-pause-funct.patch
@@ -0,0 +1,124 @@
+From d903bb345dcf6ed058ccf84f476f066b3dc08d47 Mon Sep 17 00:00:00 2001
+From: Willy Tarreau <w@1wt.eu>
+Date: Mon, 7 Jul 2014 20:22:12 +0200
+Subject: [PATCH 16/21] MEDIUM: listener: implement a per-protocol pause()
+ function
+
+In order to fix the abstact socket pause mechanism during soft restarts,
+we'll need to proceed differently depending on the socket protocol. The
+pause_listener() function already supports some protocol-specific handling
+for the TCP case.
+
+This commit makes this cleaner by adding a new ->pause() function to the
+protocol struct, which, if defined, may be used to pause a listener of a
+given protocol.
+
+For now, only TCP has been adapted, with the specific code moved from
+pause_listener() to tcp_pause_listener().
+(cherry picked from commit 092d865c53de80afc847c5ff0a079b414041ce2a)
+---
+ include/proto/proto_tcp.h | 1 +
+ include/types/protocol.h | 1 +
+ src/listener.c | 17 +++++++++--------
+ src/proto_tcp.c | 18 ++++++++++++++++++
+ 4 files changed, 29 insertions(+), 8 deletions(-)
+
+diff --git a/include/proto/proto_tcp.h b/include/proto/proto_tcp.h
+index 4adf4d2..ac8b711 100644
+--- a/include/proto/proto_tcp.h
++++ b/include/proto/proto_tcp.h
+@@ -30,6 +30,7 @@
+ int tcp_bind_socket(int fd, int flags, struct sockaddr_storage *local, struct sockaddr_storage *remote);
+ void tcpv4_add_listener(struct listener *listener);
+ void tcpv6_add_listener(struct listener *listener);
++int tcp_pause_listener(struct listener *l);
+ int tcp_connect_server(struct connection *conn, int data, int delack);
+ int tcp_connect_probe(struct connection *conn);
+ int tcp_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir);
+diff --git a/include/types/protocol.h b/include/types/protocol.h
+index e03692a..74b20e8 100644
+--- a/include/types/protocol.h
++++ b/include/types/protocol.h
+@@ -60,6 +60,7 @@ struct protocol {
+ int (*get_src)(int fd, struct sockaddr *, socklen_t, int dir); /* syscall used to retrieve src addr */
+ int (*get_dst)(int fd, struct sockaddr *, socklen_t, int dir); /* syscall used to retrieve dst addr */
+ int (*drain)(int fd); /* indicates whether we can safely close the fd */
++ int (*pause)(struct listener *l); /* temporarily pause this listener for a soft restart */
+
+ struct list listeners; /* list of listeners using this protocol */
+ int nb_listeners; /* number of listeners */
+diff --git a/src/listener.c b/src/listener.c
+index a82ce81..67f8ca7 100644
+--- a/src/listener.c
++++ b/src/listener.c
+@@ -95,15 +95,16 @@ int pause_listener(struct listener *l)
+ if (l->state <= LI_PAUSED)
+ return 1;
+
+- if (l->proto->sock_prot == IPPROTO_TCP) {
+- if (shutdown(l->fd, SHUT_WR) != 0)
+- return 0; /* Solaris dies here */
+-
+- if (listen(l->fd, l->backlog ? l->backlog : l->maxconn) != 0)
+- return 0; /* OpenBSD dies here */
++ if (l->proto->pause) {
++ /* Returns < 0 in case of failure, 0 if the listener
++ * was totally stopped, or > 0 if correctly paused.
++ */
++ int ret = l->proto->pause(l);
+
+- if (shutdown(l->fd, SHUT_RD) != 0)
+- return 0; /* should always be OK */
++ if (ret < 0)
++ return 0;
++ else if (ret == 0)
++ return 1;
+ }
+
+ if (l->state == LI_LIMITED)
+diff --git a/src/proto_tcp.c b/src/proto_tcp.c
+index e9dbc9c..9778856 100644
+--- a/src/proto_tcp.c
++++ b/src/proto_tcp.c
+@@ -80,6 +80,7 @@ static struct protocol proto_tcpv4 = {
+ .get_src = tcp_get_src,
+ .get_dst = tcp_get_dst,
+ .drain = tcp_drain,
++ .pause = tcp_pause_listener,
+ .listeners = LIST_HEAD_INIT(proto_tcpv4.listeners),
+ .nb_listeners = 0,
+ };
+@@ -102,6 +103,7 @@ static struct protocol proto_tcpv6 = {
+ .get_src = tcp_get_src,
+ .get_dst = tcp_get_dst,
+ .drain = tcp_drain,
++ .pause = tcp_pause_listener,
+ .listeners = LIST_HEAD_INIT(proto_tcpv6.listeners),
+ .nb_listeners = 0,
+ };
+@@ -947,6 +949,22 @@ void tcpv6_add_listener(struct listener *listener)
+ proto_tcpv6.nb_listeners++;
+ }
+
++/* Pause a listener. Returns < 0 in case of failure, 0 if the listener
++ * was totally stopped, or > 0 if correctly paused.
++ */
++int tcp_pause_listener(struct listener *l)
++{
++ if (shutdown(l->fd, SHUT_WR) != 0)
++ return -1; /* Solaris dies here */
++
++ if (listen(l->fd, l->backlog ? l->backlog : l->maxconn) != 0)
++ return -1; /* OpenBSD dies here */
++
++ if (shutdown(l->fd, SHUT_RD) != 0)
++ return -1; /* should always be OK */
++ return 1;
++}
++
+ /* This function performs the TCP request analysis on the current request. It
+ * returns 1 if the processing can continue on next analysers, or zero if it
+ * needs more data, encounters an error, or wants to immediately abort the
+--
+1.8.5.5
+
diff --git a/net/haproxy/patches/0017-MEDIUM-listener-support-rebinding-during-resume.patch b/net/haproxy/patches/0017-MEDIUM-listener-support-rebinding-during-resume.patch
new file mode 100644
index 000000000..570f7ce3d
--- /dev/null
+++ b/net/haproxy/patches/0017-MEDIUM-listener-support-rebinding-during-resume.patch
@@ -0,0 +1,48 @@
+From ff12090bf067a1ddd56bed14cf27371cdf2e77cb Mon Sep 17 00:00:00 2001
+From: Willy Tarreau <w@1wt.eu>
+Date: Mon, 7 Jul 2014 21:06:24 +0200
+Subject: [PATCH 17/21] MEDIUM: listener: support rebinding during resume()
+
+When a listener resumes operations, supporting a full rebind makes it
+possible to perform a full stop as a pause(). This will be used for
+pausing abstract namespace unix sockets.
+(cherry picked from commit 1c4b814087189b4b0225a473b7cb0a844bc30839)
+---
+ src/listener.c | 18 +++++++++++++++++-
+ 1 file changed, 17 insertions(+), 1 deletion(-)
+
+diff --git a/src/listener.c b/src/listener.c
+index 67f8ca7..11df69f 100644
+--- a/src/listener.c
++++ b/src/listener.c
+@@ -120,10 +120,26 @@ int pause_listener(struct listener *l)
+ * may replace enable_listener(). The resulting state will either be LI_READY
+ * or LI_FULL. 0 is returned in case of failure to resume (eg: dead socket).
+ * Listeners bound to a different process are not woken up unless we're in
+- * foreground mode.
++ * foreground mode. If the listener was only in the assigned state, it's totally
++ * rebound. This can happen if a pause() has completely stopped it. If the
++ * resume fails, 0 is returned and an error might be displayed.
+ */
+ int resume_listener(struct listener *l)
+ {
++ if (l->state == LI_ASSIGNED) {
++ char msg[100];
++ int err;
++
++ err = l->proto->bind(l, msg, sizeof(msg));
++ if (err & ERR_ALERT)
++ Alert("Resuming listener: %s\n", msg);
++ else if (err & ERR_WARN)
++ Warning("Resuming listener: %s\n", msg);
++
++ if (err & (ERR_FATAL | ERR_ABORT))
++ return 0;
++ }
++
+ if (l->state < LI_PAUSED)
+ return 0;
+
+--
+1.8.5.5
+
diff --git a/net/haproxy/patches/0018-BUG-MEDIUM-unix-completely-unbind-abstract-sockets-d.patch b/net/haproxy/patches/0018-BUG-MEDIUM-unix-completely-unbind-abstract-sockets-d.patch
new file mode 100644
index 000000000..b635a650c
--- /dev/null
+++ b/net/haproxy/patches/0018-BUG-MEDIUM-unix-completely-unbind-abstract-sockets-d.patch
@@ -0,0 +1,71 @@
+From 631a70f8baff6d26a2a6692ccd368de8d3948bf9 Mon Sep 17 00:00:00 2001
+From: Willy Tarreau <w@1wt.eu>
+Date: Mon, 7 Jul 2014 21:07:51 +0200
+Subject: [PATCH 18/21] BUG/MEDIUM: unix: completely unbind abstract sockets
+ during a pause()
+
+Abstract namespace sockets ignore the shutdown() call and do not make
+it possible to temporarily stop listening. The issue it causes is that
+during a soft reload, the new process cannot bind, complaining that the
+address is already in use.
+
+This change registers a new pause() function for unix sockets and
+completely unbinds the abstract ones since it's possible to rebind
+them later. It requires the two previous patches as well as preceeding
+fixes.
+
+This fix should be backported into 1.5 since the issue apperas there.
+(cherry picked from commit fd0e008d9d4db2f860b739bd28f6cd31d9aaf2b5)
+---
+ include/proto/proto_uxst.h | 1 +
+ src/proto_uxst.c | 15 +++++++++++++++
+ 2 files changed, 16 insertions(+)
+
+diff --git a/include/proto/proto_uxst.h b/include/proto/proto_uxst.h
+index 9422ea7..8e796ec 100644
+--- a/include/proto/proto_uxst.h
++++ b/include/proto/proto_uxst.h
+@@ -27,6 +27,7 @@
+ #include <types/task.h>
+
+ void uxst_add_listener(struct listener *listener);
++int uxst_pause_listener(struct listener *l);
+ int uxst_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir);
+ int uxst_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir);
+
+diff --git a/src/proto_uxst.c b/src/proto_uxst.c
+index 409c659..adc1b46 100644
+--- a/src/proto_uxst.c
++++ b/src/proto_uxst.c
+@@ -68,6 +68,7 @@ static struct protocol proto_unix = {
+ .disable_all = disable_all_listeners,
+ .get_src = uxst_get_src,
+ .get_dst = uxst_get_dst,
++ .pause = uxst_pause_listener,
+ .listeners = LIST_HEAD_INIT(proto_unix.listeners),
+ .nb_listeners = 0,
+ };
+@@ -373,6 +374,20 @@ void uxst_add_listener(struct listener *listener)
+ proto_unix.nb_listeners++;
+ }
+
++/* Pause a listener. Returns < 0 in case of failure, 0 if the listener
++ * was totally stopped, or > 0 if correctly paused. Nothing is done for
++ * plain unix sockets since currently it's the new process which handles
++ * the renaming. Abstract sockets are completely unbound.
++ */
++int uxst_pause_listener(struct listener *l)
++{
++ if (((struct sockaddr_un *)&l->addr)->sun_path[0])
++ return 1;
++
++ unbind_listener(l);
++ return 0;
++}
++
+
+ /*
+ * This function initiates a UNIX connection establishment to the target assigned
+--
+1.8.5.5
+
diff --git a/net/haproxy/patches/0019-DOC-explicitly-mention-the-limits-of-abstract-namesp.patch b/net/haproxy/patches/0019-DOC-explicitly-mention-the-limits-of-abstract-namesp.patch
new file mode 100644
index 000000000..0dfa8826f
--- /dev/null
+++ b/net/haproxy/patches/0019-DOC-explicitly-mention-the-limits-of-abstract-namesp.patch
@@ -0,0 +1,40 @@
+From b4fca5dbf0cfe887b88d6213b014e2f73e02a5e6 Mon Sep 17 00:00:00 2001
+From: Willy Tarreau <w@1wt.eu>
+Date: Tue, 8 Jul 2014 00:37:50 +0200
+Subject: [PATCH 19/21] DOC: explicitly mention the limits of abstract
+ namespace sockets
+
+Listening to an abstract namespace socket is quite convenient but
+comes with some drawbacks that must be clearly understood when the
+socket is being listened to by multiple processes. The trouble is
+that the socket cannot be rebound if a new process attempts a soft
+restart and fails, so only one of the initially bound processes
+will still be bound to it, the other ones will fail to rebind. For
+most situations it's not an issue but it needs to be indicated.
+(cherry picked from commit 70f72e0c90691c72cb72306b718f785902270015)
+---
+ doc/configuration.txt | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/doc/configuration.txt b/doc/configuration.txt
+index fcc6454..73195ba 100644
+--- a/doc/configuration.txt
++++ b/doc/configuration.txt
+@@ -1791,7 +1791,13 @@ bind /<path> [, ...] [param*]
+ - 'ipv4@' -> address is always IPv4
+ - 'ipv6@' -> address is always IPv6
+ - 'unix@' -> address is a path to a local unix socket
+- - 'abns@' -> address is in abstract namespace (Linux only)
++ - 'abns@' -> address is in abstract namespace (Linux only).
++ Note: since abstract sockets are not "rebindable", they
++ do not cope well with multi-process mode during
++ soft-restart, so it is better to avoid them if
++ nbproc is greater than 1. The effect is that if the
++ new process fails to start, only one of the old ones
++ will be able to rebind to the socket.
+ - 'fd@<n>' -> use file descriptor <n> inherited from the
+ parent. The fd must be bound and may or may not already
+ be listening.
+--
+1.8.5.5
+
diff --git a/net/haproxy/patches/0020-DOC-expand-the-docs-for-the-provided-stats.patch b/net/haproxy/patches/0020-DOC-expand-the-docs-for-the-provided-stats.patch
new file mode 100644
index 000000000..d9c198577
--- /dev/null
+++ b/net/haproxy/patches/0020-DOC-expand-the-docs-for-the-provided-stats.patch
@@ -0,0 +1,198 @@
+From 75c98ad211c9e1b7304033b9d3eb4fe552d725d2 Mon Sep 17 00:00:00 2001
+From: James Westby <james.westby@canonical.com>
+Date: Tue, 8 Jul 2014 10:14:57 -0400
+Subject: [PATCH 20/21] DOC: expand the docs for the provided stats.
+
+Indicate for each statistic which types may have a value for
+that statistic.
+
+Explain some of the provided statistics a little more deeply.
+(cherry picked from commit ebe62d645b45aa2210ef848fa16805a0aba7d75a)
+---
+ doc/configuration.txt | 163 +++++++++++++++++++++++++++++++-------------------
+ 1 file changed, 100 insertions(+), 63 deletions(-)
+
+diff --git a/doc/configuration.txt b/doc/configuration.txt
+index 73195ba..8407500 100644
+--- a/doc/configuration.txt
++++ b/doc/configuration.txt
+@@ -13075,44 +13075,76 @@ text is doubled ('""'), which is the format that most tools recognize. Please
+ do not insert any column before these ones in order not to break tools which
+ use hard-coded column positions.
+
+- 0. pxname: proxy name
+- 1. svname: service name (FRONTEND for frontend, BACKEND for backend, any name
+- for server)
+- 2. qcur: current queued requests
+- 3. qmax: max queued requests
+- 4. scur: current sessions
+- 5. smax: max sessions
+- 6. slim: sessions limit
+- 7. stot: total sessions
+- 8. bin: bytes in
+- 9. bout: bytes out
+- 10. dreq: denied requests
+- 11. dresp: denied responses
+- 12. ereq: request errors
+- 13. econ: connection errors
+- 14. eresp: response errors (among which srv_abrt)
+- 15. wretr: retries (warning)
+- 16. wredis: redispatches (warning)
+- 17. status: status (UP/DOWN/NOLB/MAINT/MAINT(via)...)
+- 18. weight: server weight (server), total weight (backend)
+- 19. act: server is active (server), number of active servers (backend)
+- 20. bck: server is backup (server), number of backup servers (backend)
+- 21. chkfail: number of failed checks
+- 22. chkdown: number of UP->DOWN transitions
+- 23. lastchg: last status change (in seconds)
+- 24. downtime: total downtime (in seconds)
+- 25. qlimit: queue limit
+- 26. pid: process id (0 for first instance, 1 for second, ...)
+- 27. iid: unique proxy id
+- 28. sid: service id (unique inside a proxy)
+- 29. throttle: warm up status
+- 30. lbtot: total number of times a server was selected
+- 31. tracked: id of proxy/server if tracking is enabled
+- 32. type (0=frontend, 1=backend, 2=server, 3=socket)
+- 33. rate: number of sessions per second over last elapsed second
+- 34. rate_lim: limit on new sessions per second
+- 35. rate_max: max number of new sessions per second
+- 36. check_status: status of last health check, one of:
++In brackets after each field name are the types which may have a value for
++that field. The types are L (Listeners), F (Frontends), B (Backends), and
++S (Servers).
++
++ 0. pxname [LFBS]: proxy name
++ 1. svname [LFBS]: service name (FRONTEND for frontend, BACKEND for backend,
++ any name for server/listener)
++ 2. qcur [..BS]: current queued requests. For the backend this reports the
++ number queued without a server assigned.
++ 3. qmax [..BS]: max value of qcur
++ 4. scur [LFBS]: current sessions
++ 5. smax [LFBS]: max sessions
++ 6. slim [LFBS]: configured session limit
++ 7. stot [LFBS]: cumulative number of connections
++ 8. bin [LFBS]: bytes in
++ 9. bout [LFBS]: bytes out
++ 10. dreq [LFB.]: requests denied because of security concerns.
++ - For tcp this is because of a matched tcp-request content rule.
++ - For http this is because of a matched http-request or tarpit rule.
++ 11. dresp [LFBS]: responses denied because of security concerns.
++ - For http this is because of a matched http-request rule, or
++ "option checkcache".
++ 12. ereq [LF..]: request errors. Some of the possible causes are:
++ - early termination from the client, before the request has been sent.
++ - read error from the client
++ - client timeout
++ - client closed connection
++ - various bad requests from the client.
++ - request was tarpitted.
++ 13. econ [..BS]: number of requests that encountered an error trying to
++ connect to a backend server. The backend stat is the sum of the stat
++ for all servers of that backend, plus any connection errors not
++ associated with a particular server (such as the backend having no
++ active servers).
++ 14. eresp [..BS]: response errors. srv_abrt will be counted here also.
++ Some other errors are:
++ - write error on the client socket (won't be counted for the server stat)
++ - failure applying filters to the response.
++ 15. wretr [..BS]: number of times a connection to a server was retried.
++ 16. wredis [..BS]: number of times a request was redispatched to another
++ server. The server value counts the number of times that server was
++ switched away from.
++ 17. status [LFBS]: status (UP/DOWN/NOLB/MAINT/MAINT(via)...)
++ 18. weight [..BS]: server weight (server), total weight (backend)
++ 19. act [..BS]: server is active (server), number of active servers (backend)
++ 20. bck [..BS]: server is backup (server), number of backup servers (backend)
++ 21. chkfail [...S]: number of failed checks. (Only counts checks failed when
++ the server is up.)
++ 22. chkdown [..BS]: number of UP->DOWN transitions. The backend counter counts
++ transitions to the whole backend being down, rather than the sum of the
++ counters for each server.
++ 23. lastchg [..BS]: number of seconds since the last UP<->DOWN transition
++ 24. downtime [..BS]: total downtime (in seconds). The value for the backend
++ is the downtime for the whole backend, not the sum of the server downtime.
++ 25. qlimit [...S]: configured maxqueue for the server, or nothing in the
++ value is 0 (default, meaning no limit)
++ 26. pid [LFBS]: process id (0 for first instance, 1 for second, ...)
++ 27. iid [LFBS]: unique proxy id
++ 28. sid [L..S]: server id (unique inside a proxy)
++ 29. throttle [...S]: current throttle percentage for the server, when
++ slowstart is active, or no value if not in slowstart.
++ 30. lbtot [..BS]: total number of times a server was selected, either for new
++ sessions, or when re-dispatching. The server counter is the number
++ of times that server was selected.
++ 31. tracked [...S]: id of proxy/server if tracking is enabled.
++ 32. type [LFBS]: (0=frontend, 1=backend, 2=server, 3=socket/listener)
++ 33. rate [.FBS]: number of sessions per second over last elapsed second
++ 34. rate_lim [.F..]: configured limit on new sessions per second
++ 35. rate_max [.FBS]: max number of new sessions per second
++ 36. check_status [...S]: status of last health check, one of:
+ UNK -> unknown
+ INI -> initializing
+ SOCKERR -> socket error
+@@ -13129,31 +13161,36 @@ use hard-coded column positions.
+ L7TOUT -> layer 7 (HTTP/SMTP) timeout
+ L7RSP -> layer 7 invalid response - protocol error
+ L7STS -> layer 7 response error, for example HTTP 5xx
+- 37. check_code: layer5-7 code, if available
+- 38. check_duration: time in ms took to finish last health check
+- 39. hrsp_1xx: http responses with 1xx code
+- 40. hrsp_2xx: http responses with 2xx code
+- 41. hrsp_3xx: http responses with 3xx code
+- 42. hrsp_4xx: http responses with 4xx code
+- 43. hrsp_5xx: http responses with 5xx code
+- 44. hrsp_other: http responses with other codes (protocol error)
+- 45. hanafail: failed health checks details
+- 46. req_rate: HTTP requests per second over last elapsed second
+- 47. req_rate_max: max number of HTTP requests per second observed
+- 48. req_tot: total number of HTTP requests received
+- 49. cli_abrt: number of data transfers aborted by the client
+- 50. srv_abrt: number of data transfers aborted by the server (inc. in eresp)
+- 51. comp_in: number of HTTP response bytes fed to the compressor
+- 52. comp_out: number of HTTP response bytes emitted by the compressor
+- 53. comp_byp: number of bytes that bypassed the HTTP compressor (CPU/BW limit)
+- 54. comp_rsp: number of HTTP responses that were compressed
+- 55. lastsess: number of seconds since last session assigned to server/backend
+- 56. last_chk: last health check contents or textual error
+- 57. last_agt: last agent check contents or textual error
+- 58. qtime: the average queue time in ms over the 1024 last requests
+- 59. ctime: the average connect time in ms over the 1024 last requests
+- 60. rtime: the average response time in ms over the 1024 last requests (0 for TCP)
+- 61. ttime: the average total session time in ms over the 1024 last requests
++ 37. check_code [...S]: layer5-7 code, if available
++ 38. check_duration [...S]: time in ms took to finish last health check
++ 39. hrsp_1xx [.FBS]: http responses with 1xx code
++ 40. hrsp_2xx [.FBS]: http responses with 2xx code
++ 41. hrsp_3xx [.FBS]: http responses with 3xx code
++ 42. hrsp_4xx [.FBS]: http responses with 4xx code
++ 43. hrsp_5xx [.FBS]: http responses with 5xx code
++ 44. hrsp_other [.FBS]: http responses with other codes (protocol error)
++ 45. hanafail [...S]: failed health checks details
++ 46. req_rate [.F..]: HTTP requests per second over last elapsed second
++ 47. req_rate_max [.F..]: max number of HTTP requests per second observed
++ 48. req_tot [.F..]: total number of HTTP requests received
++ 49. cli_abrt [..BS]: number of data transfers aborted by the client
++ 50. srv_abrt [..BS]: number of data transfers aborted by the server
++ (inc. in eresp)
++ 51. comp_in [.FB.]: number of HTTP response bytes fed to the compressor
++ 52. comp_out [.FB.]: number of HTTP response bytes emitted by the compressor
++ 53. comp_byp [.FB.]: number of bytes that bypassed the HTTP compressor
++ (CPU/BW limit)
++ 54. comp_rsp [.FB.]: number of HTTP responses that were compressed
++ 55. lastsess [..BS]: number of seconds since last session assigned to
++ server/backend
++ 56. last_chk [...S]: last health check contents or textual error
++ 57. last_agt [...S]: last agent check contents or textual error
++ 58. qtime [..BS]: the average queue time in ms over the 1024 last requests
++ 59. ctime [..BS]: the average connect time in ms over the 1024 last requests
++ 60. rtime [..BS]: the average response time in ms over the 1024 last requests
++ (0 for TCP)
++ 61. ttime [..BS]: the average total session time in ms over the 1024 last
++ requests
+
+
+ 9.2. Unix Socket commands
+--
+1.8.5.5
+
diff --git a/net/haproxy/patches/0021-BUG-MEDIUM-backend-Update-hash-to-use-unsigned-int-t.patch b/net/haproxy/patches/0021-BUG-MEDIUM-backend-Update-hash-to-use-unsigned-int-t.patch
new file mode 100644
index 000000000..57e37c1c5
--- /dev/null
+++ b/net/haproxy/patches/0021-BUG-MEDIUM-backend-Update-hash-to-use-unsigned-int-t.patch
@@ -0,0 +1,138 @@
+From 82456753cae9200aa1f4031f64c22c08e130f072 Mon Sep 17 00:00:00 2001
+From: Dan Dubovik <ddubovik@godaddy.com>
+Date: Tue, 8 Jul 2014 08:51:03 -0700
+Subject: [PATCH 21/21] BUG/MEDIUM: backend: Update hash to use unsigned int
+ throughout
+
+When we were generating a hash, it was done using an unsigned long. When the hash was used
+to select a backend, it was sent as an unsigned int. This made it difficult to predict which
+backend would be selected.
+
+This patch updates get_hash, and the hash methods to use an unsigned int, to remain consistent
+throughout the codebase.
+
+This fix should be backported to 1.5 and probably in part to 1.4.
+(cherry picked from commit bd57a9f977f60fcf7818f462953da3740e3bd010)
+---
+ include/common/hash.h | 6 +++---
+ src/backend.c | 14 +++++++-------
+ src/hash.c | 10 +++++-----
+ 3 files changed, 15 insertions(+), 15 deletions(-)
+
+diff --git a/include/common/hash.h b/include/common/hash.h
+index 379bf89..7039ba5 100644
+--- a/include/common/hash.h
++++ b/include/common/hash.h
+@@ -22,8 +22,8 @@
+ #ifndef _COMMON_HASH_H_
+ #define _COMMON_HASH_H_
+
+-unsigned long hash_djb2(const char *key, int len);
+-unsigned long hash_wt6(const char *key, int len);
+-unsigned long hash_sdbm(const char *key, int len);
++unsigned int hash_djb2(const char *key, int len);
++unsigned int hash_wt6(const char *key, int len);
++unsigned int hash_sdbm(const char *key, int len);
+
+ #endif /* _COMMON_HASH_H_ */
+diff --git a/src/backend.c b/src/backend.c
+index 5ddb88c..a96b767 100644
+--- a/src/backend.c
++++ b/src/backend.c
+@@ -63,9 +63,9 @@ int be_lastsession(const struct proxy *be)
+ }
+
+ /* helper function to invoke the correct hash method */
+-static unsigned long gen_hash(const struct proxy* px, const char* key, unsigned long len)
++static unsigned int gen_hash(const struct proxy* px, const char* key, unsigned long len)
+ {
+- unsigned long hash;
++ unsigned int hash;
+
+ switch (px->lbprm.algo & BE_LB_HASH_FUNC) {
+ case BE_LB_HFCN_DJB2:
+@@ -183,7 +183,7 @@ struct server *get_server_sh(struct proxy *px, const char *addr, int len)
+ */
+ struct server *get_server_uh(struct proxy *px, char *uri, int uri_len)
+ {
+- unsigned long hash = 0;
++ unsigned int hash = 0;
+ int c;
+ int slashes = 0;
+ const char *start, *end;
+@@ -232,7 +232,7 @@ struct server *get_server_uh(struct proxy *px, char *uri, int uri_len)
+ */
+ struct server *get_server_ph(struct proxy *px, const char *uri, int uri_len)
+ {
+- unsigned long hash = 0;
++ unsigned int hash = 0;
+ const char *start, *end;
+ const char *p;
+ const char *params;
+@@ -294,7 +294,7 @@ struct server *get_server_ph(struct proxy *px, const char *uri, int uri_len)
+ */
+ struct server *get_server_ph_post(struct session *s)
+ {
+- unsigned long hash = 0;
++ unsigned int hash = 0;
+ struct http_txn *txn = &s->txn;
+ struct channel *req = s->req;
+ struct http_msg *msg = &txn->req;
+@@ -372,7 +372,7 @@ struct server *get_server_ph_post(struct session *s)
+ */
+ struct server *get_server_hh(struct session *s)
+ {
+- unsigned long hash = 0;
++ unsigned int hash = 0;
+ struct http_txn *txn = &s->txn;
+ struct proxy *px = s->be;
+ unsigned int plen = px->hh_len;
+@@ -444,7 +444,7 @@ struct server *get_server_hh(struct session *s)
+ /* RDP Cookie HASH. */
+ struct server *get_server_rch(struct session *s)
+ {
+- unsigned long hash = 0;
++ unsigned int hash = 0;
+ struct proxy *px = s->be;
+ unsigned long len;
+ int ret;
+diff --git a/src/hash.c b/src/hash.c
+index 034685e..aa236cb 100644
+--- a/src/hash.c
++++ b/src/hash.c
+@@ -17,7 +17,7 @@
+ #include <common/hash.h>
+
+
+-unsigned long hash_wt6(const char *key, int len)
++unsigned int hash_wt6(const char *key, int len)
+ {
+ unsigned h0 = 0xa53c965aUL;
+ unsigned h1 = 0x5ca6953aUL;
+@@ -44,9 +44,9 @@ unsigned long hash_wt6(const char *key, int len)
+ return h0 ^ h1;
+ }
+
+-unsigned long hash_djb2(const char *key, int len)
++unsigned int hash_djb2(const char *key, int len)
+ {
+- unsigned long hash = 5381;
++ unsigned int hash = 5381;
+
+ /* the hash unrolled eight times */
+ for (; len >= 8; len -= 8) {
+@@ -72,9 +72,9 @@ unsigned long hash_djb2(const char *key, int len)
+ return hash;
+ }
+
+-unsigned long hash_sdbm(const char *key, int len)
++unsigned int hash_sdbm(const char *key, int len)
+ {
+- unsigned long hash = 0;
++ unsigned int hash = 0;
+ int c;
+
+ while (len--) {
+--
+1.8.5.5
+