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>
This commit is contained in:
Thomas Heil 2014-07-10 13:51:27 +02:00
parent c5b89e2ea2
commit 0661fbcf90
10 changed files with 907 additions and 1 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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