diff --git a/net/haproxy/Makefile b/net/haproxy/Makefile index 859331f3c6..cccbe74e19 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 0000000000..bcd0e45e56 --- /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 +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 0000000000..e5292dac4a --- /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 +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 0000000000..f15c981ae3 --- /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 +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 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 0000000000..0ee82173ef --- /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 +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 0000000000..570f7ce3d7 --- /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 +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 0000000000..b635a650c4 --- /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 +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 + + 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 0000000000..0dfa8826f4 --- /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 +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 / [, ...] [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@' -> use file descriptor 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 0000000000..d9c198577e --- /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 +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 0000000000..57e37c1c5f --- /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 +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 + + +-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 +