Procházet zdrojové kódy

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>
Thomas Heil před 10 roky
rodič
revize
0661fbcf90

+ 1
- 1
net/haproxy/Makefile Zobrazit soubor

@@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk
10 10
 
11 11
 PKG_NAME:=haproxy
12 12
 PKG_VERSION:=1.5.1
13
-PKG_RELEASE:=12
13
+PKG_RELEASE:=21
14 14
 PKG_SOURCE:=haproxy-$(PKG_VERSION).tar.gz
15 15
 PKG_SOURCE_URL:=http://haproxy.1wt.eu/download/1.5/src/
16 16
 PKG_MD5SUM:=49640cf3ddd793a05fbd3394481a1ed4

+ 102
- 0
net/haproxy/patches/0013-BUILD-http-fix-isdigit-isspace-warnings-on-Solaris.patch Zobrazit soubor

@@ -0,0 +1,102 @@
1
+From 463ae6f09e485faf3d1cdc4daceefe4bcd50b50e Mon Sep 17 00:00:00 2001
2
+From: Willy Tarreau <w@1wt.eu>
3
+Date: Tue, 8 Jul 2014 00:59:48 +0200
4
+Subject: [PATCH 13/21] BUILD: http: fix isdigit & isspace warnings on Solaris
5
+
6
+As usual, when touching any is* function, Solaris complains about the
7
+type of the element being checked. Better backport this to 1.5 since
8
+nobody knows what the emitted code looks like since macros are used
9
+instead of functions.
10
+(cherry picked from commit 506c69a50e8d434b6b0c2c89b0402f220830644d)
11
+---
12
+ src/proto_http.c | 20 ++++++++++----------
13
+ 1 file changed, 10 insertions(+), 10 deletions(-)
14
+
15
+diff --git a/src/proto_http.c b/src/proto_http.c
16
+index 01fe62d..4a862b0 100644
17
+--- a/src/proto_http.c
18
++++ b/src/proto_http.c
19
+@@ -2143,22 +2143,22 @@ int parse_qvalue(const char *qvalue, const char **end)
20
+ {
21
+ 	int q = 1000;
22
+ 
23
+-	if (!isdigit(*qvalue))
24
++	if (!isdigit((unsigned char)*qvalue))
25
+ 		goto out;
26
+ 	q = (*qvalue++ - '0') * 1000;
27
+ 
28
+ 	if (*qvalue++ != '.')
29
+ 		goto out;
30
+ 
31
+-	if (!isdigit(*qvalue))
32
++	if (!isdigit((unsigned char)*qvalue))
33
+ 		goto out;
34
+ 	q += (*qvalue++ - '0') * 100;
35
+ 
36
+-	if (!isdigit(*qvalue))
37
++	if (!isdigit((unsigned char)*qvalue))
38
+ 		goto out;
39
+ 	q += (*qvalue++ - '0') * 10;
40
+ 
41
+-	if (!isdigit(*qvalue))
42
++	if (!isdigit((unsigned char)*qvalue))
43
+ 		goto out;
44
+ 	q += (*qvalue++ - '0') * 1;
45
+  out:
46
+@@ -11226,7 +11226,7 @@ static int sample_conv_q_prefered(const struct arg *args, struct sample *smp)
47
+ 	while (1) {
48
+ 
49
+ 		/* Jump spaces, quit if the end is detected. */
50
+-		while (al < end && isspace(*al))
51
++		while (al < end && isspace((unsigned char)*al))
52
+ 			al++;
53
+ 		if (al >= end)
54
+ 			break;
55
+@@ -11235,7 +11235,7 @@ static int sample_conv_q_prefered(const struct arg *args, struct sample *smp)
56
+ 		token = al;
57
+ 
58
+ 		/* Look for separator: isspace(), ',' or ';'. Next value if 0 length word. */
59
+-		while (al < end && *al != ';' && *al != ',' && !isspace(*al))
60
++		while (al < end && *al != ';' && *al != ',' && !isspace((unsigned char)*al))
61
+ 			al++;
62
+ 		if (al == token)
63
+ 			goto expect_comma;
64
+@@ -11264,7 +11264,7 @@ static int sample_conv_q_prefered(const struct arg *args, struct sample *smp)
65
+ look_for_q:
66
+ 
67
+ 		/* Jump spaces, quit if the end is detected. */
68
+-		while (al < end && isspace(*al))
69
++		while (al < end && isspace((unsigned char)*al))
70
+ 			al++;
71
+ 		if (al >= end)
72
+ 			goto process_value;
73
+@@ -11283,7 +11283,7 @@ look_for_q:
74
+ 		al++;
75
+ 
76
+ 		/* Jump spaces, process value if the end is detected. */
77
+-		while (al < end && isspace(*al))
78
++		while (al < end && isspace((unsigned char)*al))
79
+ 			al++;
80
+ 		if (al >= end)
81
+ 			goto process_value;
82
+@@ -11294,7 +11294,7 @@ look_for_q:
83
+ 		al++;
84
+ 
85
+ 		/* Jump spaces, process value if the end is detected. */
86
+-		while (al < end && isspace(*al))
87
++		while (al < end && isspace((unsigned char)*al))
88
+ 			al++;
89
+ 		if (al >= end)
90
+ 			goto process_value;
91
+@@ -11305,7 +11305,7 @@ look_for_q:
92
+ 		al++;
93
+ 
94
+ 		/* Jump spaces, process value if the end is detected. */
95
+-		while (al < end && isspace(*al))
96
++		while (al < end && isspace((unsigned char)*al))
97
+ 			al++;
98
+ 		if (al >= end)
99
+ 			goto process_value;
100
+-- 
101
+1.8.5.5
102
+

+ 32
- 0
net/haproxy/patches/0014-BUG-MINOR-listener-set-the-listener-s-fd-to-1-after-.patch Zobrazit soubor

@@ -0,0 +1,32 @@
1
+From fb8bf6324bfe9f36d0be5110fcc13facba4389a8 Mon Sep 17 00:00:00 2001
2
+From: Willy Tarreau <w@1wt.eu>
3
+Date: Mon, 7 Jul 2014 18:24:48 +0200
4
+Subject: [PATCH 14/21] BUG/MINOR: listener: set the listener's fd to -1 after
5
+ deletion
6
+
7
+This is currently harmless, but when stopping a listener, its fd is
8
+closed but not set to -1, so it is not possible to re-open it again.
9
+Currently this has no impact but can have after the abstract sockets
10
+are modified to perform a complete close on soft-reload.
11
+
12
+The fix can be backported to 1.5 and may even apply to 1.4 (protocols.c).
13
+(cherry picked from commit 39447b6a5799a160eae452db920fd0735a78638b)
14
+---
15
+ src/listener.c | 1 +
16
+ 1 file changed, 1 insertion(+)
17
+
18
+diff --git a/src/listener.c b/src/listener.c
19
+index ec3a39b..a82ce81 100644
20
+--- a/src/listener.c
21
++++ b/src/listener.c
22
+@@ -236,6 +236,7 @@ int unbind_listener(struct listener *listener)
23
+ 
24
+ 	if (listener->state >= LI_PAUSED) {
25
+ 		fd_delete(listener->fd);
26
++		listener->fd = -1;
27
+ 		listener->state = LI_ASSIGNED;
28
+ 	}
29
+ 	return ERR_NONE;
30
+-- 
31
+1.8.5.5
32
+

+ 153
- 0
net/haproxy/patches/0015-BUG-MEDIUM-unix-failed-abstract-socket-binding-is-re.patch Zobrazit soubor

@@ -0,0 +1,153 @@
1
+From 58dd0f33fa908e83199d28775bad8ee2f24151a9 Mon Sep 17 00:00:00 2001
2
+From: Willy Tarreau <w@1wt.eu>
3
+Date: Mon, 7 Jul 2014 18:36:45 +0200
4
+Subject: [PATCH 15/21] BUG/MEDIUM: unix: failed abstract socket binding is
5
+ retryable
6
+
7
+Jan Seda noticed that abstract sockets are incompatible with soft reload,
8
+because the new process cannot bind and immediately fails. This patch marks
9
+the binding as retryable and not fatal so that the new process can try to
10
+bind again after sending a signal to the old process.
11
+
12
+Note that this fix is not enough to completely solve the problem, but it
13
+is necessary. This patch should be backported to 1.5.
14
+(cherry picked from commit 3c5efa2b3268f31cffc2c18887010d4bc906a066)
15
+---
16
+ src/proto_uxst.c | 30 ++++++++++++++++++++++++++----
17
+ 1 file changed, 26 insertions(+), 4 deletions(-)
18
+
19
+diff --git a/src/proto_uxst.c b/src/proto_uxst.c
20
+index c9a52ff..409c659 100644
21
+--- a/src/proto_uxst.c
22
++++ b/src/proto_uxst.c
23
+@@ -166,9 +166,11 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
24
+ 	const char *path;
25
+ 	int ext, ready;
26
+ 	socklen_t ready_len;
27
+-
28
++	int err;
29
+ 	int ret;
30
+ 
31
++	err = ERR_NONE;
32
++
33
+ 	/* ensure we never return garbage */
34
+ 	if (errlen)
35
+ 		*errmsg = 0;
36
+@@ -191,29 +193,34 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
37
+ 	if (path[0]) {
38
+ 		ret = snprintf(tempname, MAXPATHLEN, "%s.%d.tmp", path, pid);
39
+ 		if (ret < 0 || ret >= MAXPATHLEN) {
40
++			err |= ERR_FATAL | ERR_ALERT;
41
+ 			msg = "name too long for UNIX socket";
42
+ 			goto err_return;
43
+ 		}
44
+ 
45
+ 		ret = snprintf(backname, MAXPATHLEN, "%s.%d.bak", path, pid);
46
+ 		if (ret < 0 || ret >= MAXPATHLEN) {
47
++			err |= ERR_FATAL | ERR_ALERT;
48
+ 			msg = "name too long for UNIX socket";
49
+ 			goto err_return;
50
+ 		}
51
+ 
52
+ 		/* 2. clean existing orphaned entries */
53
+ 		if (unlink(tempname) < 0 && errno != ENOENT) {
54
++			err |= ERR_FATAL | ERR_ALERT;
55
+ 			msg = "error when trying to unlink previous UNIX socket";
56
+ 			goto err_return;
57
+ 		}
58
+ 
59
+ 		if (unlink(backname) < 0 && errno != ENOENT) {
60
++			err |= ERR_FATAL | ERR_ALERT;
61
+ 			msg = "error when trying to unlink previous UNIX socket";
62
+ 			goto err_return;
63
+ 		}
64
+ 
65
+ 		/* 3. backup existing socket */
66
+ 		if (link(path, backname) < 0 && errno != ENOENT) {
67
++			err |= ERR_FATAL | ERR_ALERT;
68
+ 			msg = "error when trying to preserve previous UNIX socket";
69
+ 			goto err_return;
70
+ 		}
71
+@@ -231,24 +238,35 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
72
+ 
73
+ 	fd = socket(PF_UNIX, SOCK_STREAM, 0);
74
+ 	if (fd < 0) {
75
++		err |= ERR_FATAL | ERR_ALERT;
76
+ 		msg = "cannot create UNIX socket";
77
+ 		goto err_unlink_back;
78
+ 	}
79
+ 
80
+  fd_ready:
81
+ 	if (fd >= global.maxsock) {
82
++		err |= ERR_FATAL | ERR_ALERT;
83
+ 		msg = "socket(): not enough free sockets, raise -n argument";
84
+ 		goto err_unlink_temp;
85
+ 	}
86
+ 	
87
+ 	if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
88
++		err |= ERR_FATAL | ERR_ALERT;
89
+ 		msg = "cannot make UNIX socket non-blocking";
90
+ 		goto err_unlink_temp;
91
+ 	}
92
+ 	
93
+ 	if (!ext && bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
94
+ 		/* note that bind() creates the socket <tempname> on the file system */
95
+-		msg = "cannot bind UNIX socket";
96
++		if (errno == EADDRINUSE) {
97
++			/* the old process might still own it, let's retry */
98
++			err |= ERR_RETRYABLE | ERR_ALERT;
99
++			msg = "cannot listen to socket";
100
++		}
101
++		else {
102
++			err |= ERR_FATAL | ERR_ALERT;
103
++			msg = "cannot bind UNIX socket";
104
++		}
105
+ 		goto err_unlink_temp;
106
+ 	}
107
+ 
108
+@@ -261,6 +279,7 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
109
+ 	    (((listener->bind_conf->ux.uid != -1 || listener->bind_conf->ux.gid != -1) &&
110
+ 	      (chown(tempname, listener->bind_conf->ux.uid, listener->bind_conf->ux.gid) == -1)) ||
111
+ 	     (listener->bind_conf->ux.mode != 0 && chmod(tempname, listener->bind_conf->ux.mode) == -1))) {
112
++		err |= ERR_FATAL | ERR_ALERT;
113
+ 		msg = "cannot change UNIX socket ownership";
114
+ 		goto err_unlink_temp;
115
+ 	}
116
+@@ -272,6 +291,7 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
117
+ 
118
+ 	if (!(ext && ready) && /* only listen if not already done by external process */
119
+ 	    listen(fd, listener->backlog ? listener->backlog : listener->maxconn) < 0) {
120
++		err |= ERR_FATAL | ERR_ALERT;
121
+ 		msg = "cannot listen to UNIX socket";
122
+ 		goto err_unlink_temp;
123
+ 	}
124
+@@ -281,6 +301,7 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
125
+ 	 * backname. Abstract sockets are not renamed.
126
+ 	 */
127
+ 	if (!ext && path[0] && rename(tempname, path) < 0) {
128
++		err |= ERR_FATAL | ERR_ALERT;
129
+ 		msg = "cannot switch final and temporary UNIX sockets";
130
+ 		goto err_rename;
131
+ 	}
132
+@@ -303,7 +324,8 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
133
+ 	fd_insert(fd);
134
+ 	fdtab[fd].iocb = listener->proto->accept;
135
+ 	fdtab[fd].owner = listener; /* reference the listener instead of a task */
136
+-	return ERR_NONE;
137
++	return err;
138
++
139
+  err_rename:
140
+ 	ret = rename(backname, path);
141
+ 	if (ret < 0 && errno == ENOENT)
142
+@@ -322,7 +344,7 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
143
+ 		else
144
+ 			snprintf(errmsg, errlen, "%s [fd %d]", msg, fd);
145
+ 	}
146
+-	return ERR_FATAL | ERR_ALERT;
147
++	return err;
148
+ }
149
+ 
150
+ /* This function closes the UNIX sockets for the specified listener.
151
+-- 
152
+1.8.5.5
153
+

+ 124
- 0
net/haproxy/patches/0016-MEDIUM-listener-implement-a-per-protocol-pause-funct.patch Zobrazit soubor

@@ -0,0 +1,124 @@
1
+From d903bb345dcf6ed058ccf84f476f066b3dc08d47 Mon Sep 17 00:00:00 2001
2
+From: Willy Tarreau <w@1wt.eu>
3
+Date: Mon, 7 Jul 2014 20:22:12 +0200
4
+Subject: [PATCH 16/21] MEDIUM: listener: implement a per-protocol pause()
5
+ function
6
+
7
+In order to fix the abstact socket pause mechanism during soft restarts,
8
+we'll need to proceed differently depending on the socket protocol. The
9
+pause_listener() function already supports some protocol-specific handling
10
+for the TCP case.
11
+
12
+This commit makes this cleaner by adding a new ->pause() function to the
13
+protocol struct, which, if defined, may be used to pause a listener of a
14
+given protocol.
15
+
16
+For now, only TCP has been adapted, with the specific code moved from
17
+pause_listener() to tcp_pause_listener().
18
+(cherry picked from commit 092d865c53de80afc847c5ff0a079b414041ce2a)
19
+---
20
+ include/proto/proto_tcp.h |  1 +
21
+ include/types/protocol.h  |  1 +
22
+ src/listener.c            | 17 +++++++++--------
23
+ src/proto_tcp.c           | 18 ++++++++++++++++++
24
+ 4 files changed, 29 insertions(+), 8 deletions(-)
25
+
26
+diff --git a/include/proto/proto_tcp.h b/include/proto/proto_tcp.h
27
+index 4adf4d2..ac8b711 100644
28
+--- a/include/proto/proto_tcp.h
29
++++ b/include/proto/proto_tcp.h
30
+@@ -30,6 +30,7 @@
31
+ int tcp_bind_socket(int fd, int flags, struct sockaddr_storage *local, struct sockaddr_storage *remote);
32
+ void tcpv4_add_listener(struct listener *listener);
33
+ void tcpv6_add_listener(struct listener *listener);
34
++int tcp_pause_listener(struct listener *l);
35
+ int tcp_connect_server(struct connection *conn, int data, int delack);
36
+ int tcp_connect_probe(struct connection *conn);
37
+ int tcp_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir);
38
+diff --git a/include/types/protocol.h b/include/types/protocol.h
39
+index e03692a..74b20e8 100644
40
+--- a/include/types/protocol.h
41
++++ b/include/types/protocol.h
42
+@@ -60,6 +60,7 @@ struct protocol {
43
+ 	int (*get_src)(int fd, struct sockaddr *, socklen_t, int dir); /* syscall used to retrieve src addr */
44
+ 	int (*get_dst)(int fd, struct sockaddr *, socklen_t, int dir); /* syscall used to retrieve dst addr */
45
+ 	int (*drain)(int fd);                           /* indicates whether we can safely close the fd */
46
++	int (*pause)(struct listener *l);               /* temporarily pause this listener for a soft restart */
47
+ 
48
+ 	struct list listeners;				/* list of listeners using this protocol */
49
+ 	int nb_listeners;				/* number of listeners */
50
+diff --git a/src/listener.c b/src/listener.c
51
+index a82ce81..67f8ca7 100644
52
+--- a/src/listener.c
53
++++ b/src/listener.c
54
+@@ -95,15 +95,16 @@ int pause_listener(struct listener *l)
55
+ 	if (l->state <= LI_PAUSED)
56
+ 		return 1;
57
+ 
58
+-	if (l->proto->sock_prot == IPPROTO_TCP) {
59
+-		if (shutdown(l->fd, SHUT_WR) != 0)
60
+-			return 0; /* Solaris dies here */
61
+-
62
+-		if (listen(l->fd, l->backlog ? l->backlog : l->maxconn) != 0)
63
+-			return 0; /* OpenBSD dies here */
64
++	if (l->proto->pause) {
65
++		/* Returns < 0 in case of failure, 0 if the listener
66
++		 * was totally stopped, or > 0 if correctly paused.
67
++		 */
68
++		int ret = l->proto->pause(l);
69
+ 
70
+-		if (shutdown(l->fd, SHUT_RD) != 0)
71
+-			return 0; /* should always be OK */
72
++		if (ret < 0)
73
++			return 0;
74
++		else if (ret == 0)
75
++			return 1;
76
+ 	}
77
+ 
78
+ 	if (l->state == LI_LIMITED)
79
+diff --git a/src/proto_tcp.c b/src/proto_tcp.c
80
+index e9dbc9c..9778856 100644
81
+--- a/src/proto_tcp.c
82
++++ b/src/proto_tcp.c
83
+@@ -80,6 +80,7 @@ static struct protocol proto_tcpv4 = {
84
+ 	.get_src = tcp_get_src,
85
+ 	.get_dst = tcp_get_dst,
86
+ 	.drain = tcp_drain,
87
++	.pause = tcp_pause_listener,
88
+ 	.listeners = LIST_HEAD_INIT(proto_tcpv4.listeners),
89
+ 	.nb_listeners = 0,
90
+ };
91
+@@ -102,6 +103,7 @@ static struct protocol proto_tcpv6 = {
92
+ 	.get_src = tcp_get_src,
93
+ 	.get_dst = tcp_get_dst,
94
+ 	.drain = tcp_drain,
95
++	.pause = tcp_pause_listener,
96
+ 	.listeners = LIST_HEAD_INIT(proto_tcpv6.listeners),
97
+ 	.nb_listeners = 0,
98
+ };
99
+@@ -947,6 +949,22 @@ void tcpv6_add_listener(struct listener *listener)
100
+ 	proto_tcpv6.nb_listeners++;
101
+ }
102
+ 
103
++/* Pause a listener. Returns < 0 in case of failure, 0 if the listener
104
++ * was totally stopped, or > 0 if correctly paused.
105
++ */
106
++int tcp_pause_listener(struct listener *l)
107
++{
108
++	if (shutdown(l->fd, SHUT_WR) != 0)
109
++		return -1; /* Solaris dies here */
110
++
111
++	if (listen(l->fd, l->backlog ? l->backlog : l->maxconn) != 0)
112
++		return -1; /* OpenBSD dies here */
113
++
114
++	if (shutdown(l->fd, SHUT_RD) != 0)
115
++		return -1; /* should always be OK */
116
++	return 1;
117
++}
118
++
119
+ /* This function performs the TCP request analysis on the current request. It
120
+  * returns 1 if the processing can continue on next analysers, or zero if it
121
+  * needs more data, encounters an error, or wants to immediately abort the
122
+-- 
123
+1.8.5.5
124
+

+ 48
- 0
net/haproxy/patches/0017-MEDIUM-listener-support-rebinding-during-resume.patch Zobrazit soubor

@@ -0,0 +1,48 @@
1
+From ff12090bf067a1ddd56bed14cf27371cdf2e77cb Mon Sep 17 00:00:00 2001
2
+From: Willy Tarreau <w@1wt.eu>
3
+Date: Mon, 7 Jul 2014 21:06:24 +0200
4
+Subject: [PATCH 17/21] MEDIUM: listener: support rebinding during resume()
5
+
6
+When a listener resumes operations, supporting a full rebind makes it
7
+possible to perform a full stop as a pause(). This will be used for
8
+pausing abstract namespace unix sockets.
9
+(cherry picked from commit 1c4b814087189b4b0225a473b7cb0a844bc30839)
10
+---
11
+ src/listener.c | 18 +++++++++++++++++-
12
+ 1 file changed, 17 insertions(+), 1 deletion(-)
13
+
14
+diff --git a/src/listener.c b/src/listener.c
15
+index 67f8ca7..11df69f 100644
16
+--- a/src/listener.c
17
++++ b/src/listener.c
18
+@@ -120,10 +120,26 @@ int pause_listener(struct listener *l)
19
+  * may replace enable_listener(). The resulting state will either be LI_READY
20
+  * or LI_FULL. 0 is returned in case of failure to resume (eg: dead socket).
21
+  * Listeners bound to a different process are not woken up unless we're in
22
+- * foreground mode.
23
++ * foreground mode. If the listener was only in the assigned state, it's totally
24
++ * rebound. This can happen if a pause() has completely stopped it. If the
25
++ * resume fails, 0 is returned and an error might be displayed.
26
+  */
27
+ int resume_listener(struct listener *l)
28
+ {
29
++	if (l->state == LI_ASSIGNED) {
30
++		char msg[100];
31
++		int err;
32
++
33
++		err = l->proto->bind(l, msg, sizeof(msg));
34
++		if (err & ERR_ALERT)
35
++			Alert("Resuming listener: %s\n", msg);
36
++		else if (err & ERR_WARN)
37
++			Warning("Resuming listener: %s\n", msg);
38
++
39
++		if (err & (ERR_FATAL | ERR_ABORT))
40
++			return 0;
41
++	}
42
++
43
+ 	if (l->state < LI_PAUSED)
44
+ 		return 0;
45
+ 
46
+-- 
47
+1.8.5.5
48
+

+ 71
- 0
net/haproxy/patches/0018-BUG-MEDIUM-unix-completely-unbind-abstract-sockets-d.patch Zobrazit soubor

@@ -0,0 +1,71 @@
1
+From 631a70f8baff6d26a2a6692ccd368de8d3948bf9 Mon Sep 17 00:00:00 2001
2
+From: Willy Tarreau <w@1wt.eu>
3
+Date: Mon, 7 Jul 2014 21:07:51 +0200
4
+Subject: [PATCH 18/21] BUG/MEDIUM: unix: completely unbind abstract sockets
5
+ during a pause()
6
+
7
+Abstract namespace sockets ignore the shutdown() call and do not make
8
+it possible to temporarily stop listening. The issue it causes is that
9
+during a soft reload, the new process cannot bind, complaining that the
10
+address is already in use.
11
+
12
+This change registers a new pause() function for unix sockets and
13
+completely unbinds the abstract ones since it's possible to rebind
14
+them later. It requires the two previous patches as well as preceeding
15
+fixes.
16
+
17
+This fix should be backported into 1.5 since the issue apperas there.
18
+(cherry picked from commit fd0e008d9d4db2f860b739bd28f6cd31d9aaf2b5)
19
+---
20
+ include/proto/proto_uxst.h |  1 +
21
+ src/proto_uxst.c           | 15 +++++++++++++++
22
+ 2 files changed, 16 insertions(+)
23
+
24
+diff --git a/include/proto/proto_uxst.h b/include/proto/proto_uxst.h
25
+index 9422ea7..8e796ec 100644
26
+--- a/include/proto/proto_uxst.h
27
++++ b/include/proto/proto_uxst.h
28
+@@ -27,6 +27,7 @@
29
+ #include <types/task.h>
30
+ 
31
+ void uxst_add_listener(struct listener *listener);
32
++int uxst_pause_listener(struct listener *l);
33
+ int uxst_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir);
34
+ int uxst_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir);
35
+ 
36
+diff --git a/src/proto_uxst.c b/src/proto_uxst.c
37
+index 409c659..adc1b46 100644
38
+--- a/src/proto_uxst.c
39
++++ b/src/proto_uxst.c
40
+@@ -68,6 +68,7 @@ static struct protocol proto_unix = {
41
+ 	.disable_all = disable_all_listeners,
42
+ 	.get_src = uxst_get_src,
43
+ 	.get_dst = uxst_get_dst,
44
++	.pause = uxst_pause_listener,
45
+ 	.listeners = LIST_HEAD_INIT(proto_unix.listeners),
46
+ 	.nb_listeners = 0,
47
+ };
48
+@@ -373,6 +374,20 @@ void uxst_add_listener(struct listener *listener)
49
+ 	proto_unix.nb_listeners++;
50
+ }
51
+ 
52
++/* Pause a listener. Returns < 0 in case of failure, 0 if the listener
53
++ * was totally stopped, or > 0 if correctly paused. Nothing is done for
54
++ * plain unix sockets since currently it's the new process which handles
55
++ * the renaming. Abstract sockets are completely unbound.
56
++ */
57
++int uxst_pause_listener(struct listener *l)
58
++{
59
++	if (((struct sockaddr_un *)&l->addr)->sun_path[0])
60
++		return 1;
61
++
62
++	unbind_listener(l);
63
++	return 0;
64
++}
65
++
66
+ 
67
+ /*
68
+  * This function initiates a UNIX connection establishment to the target assigned
69
+-- 
70
+1.8.5.5
71
+

+ 40
- 0
net/haproxy/patches/0019-DOC-explicitly-mention-the-limits-of-abstract-namesp.patch Zobrazit soubor

@@ -0,0 +1,40 @@
1
+From b4fca5dbf0cfe887b88d6213b014e2f73e02a5e6 Mon Sep 17 00:00:00 2001
2
+From: Willy Tarreau <w@1wt.eu>
3
+Date: Tue, 8 Jul 2014 00:37:50 +0200
4
+Subject: [PATCH 19/21] DOC: explicitly mention the limits of abstract
5
+ namespace sockets
6
+
7
+Listening to an abstract namespace socket is quite convenient but
8
+comes with some drawbacks that must be clearly understood when the
9
+socket is being listened to by multiple processes. The trouble is
10
+that the socket cannot be rebound if a new process attempts a soft
11
+restart and fails, so only one of the initially bound processes
12
+will still be bound to it, the other ones will fail to rebind. For
13
+most situations it's not an issue but it needs to be indicated.
14
+(cherry picked from commit 70f72e0c90691c72cb72306b718f785902270015)
15
+---
16
+ doc/configuration.txt | 8 +++++++-
17
+ 1 file changed, 7 insertions(+), 1 deletion(-)
18
+
19
+diff --git a/doc/configuration.txt b/doc/configuration.txt
20
+index fcc6454..73195ba 100644
21
+--- a/doc/configuration.txt
22
++++ b/doc/configuration.txt
23
+@@ -1791,7 +1791,13 @@ bind /<path> [, ...] [param*]
24
+                     - 'ipv4@'  -> address is always IPv4
25
+                     - 'ipv6@'  -> address is always IPv6
26
+                     - 'unix@'  -> address is a path to a local unix socket
27
+-                    - 'abns@'  -> address is in abstract namespace (Linux only)
28
++                    - 'abns@'  -> address is in abstract namespace (Linux only).
29
++                      Note: since abstract sockets are not "rebindable", they
30
++                            do not cope well with multi-process mode during
31
++                            soft-restart, so it is better to avoid them if
32
++                            nbproc is greater than 1. The effect is that if the
33
++                            new process fails to start, only one of the old ones
34
++                            will be able to rebind to the socket.
35
+                     - 'fd@<n>' -> use file descriptor <n> inherited from the
36
+                       parent. The fd must be bound and may or may not already
37
+                       be listening.
38
+-- 
39
+1.8.5.5
40
+

+ 198
- 0
net/haproxy/patches/0020-DOC-expand-the-docs-for-the-provided-stats.patch Zobrazit soubor

@@ -0,0 +1,198 @@
1
+From 75c98ad211c9e1b7304033b9d3eb4fe552d725d2 Mon Sep 17 00:00:00 2001
2
+From: James Westby <james.westby@canonical.com>
3
+Date: Tue, 8 Jul 2014 10:14:57 -0400
4
+Subject: [PATCH 20/21] DOC: expand the docs for the provided stats.
5
+
6
+Indicate for each statistic which types may have a value for
7
+that statistic.
8
+
9
+Explain some of the provided statistics a little more deeply.
10
+(cherry picked from commit ebe62d645b45aa2210ef848fa16805a0aba7d75a)
11
+---
12
+ doc/configuration.txt | 163 +++++++++++++++++++++++++++++++-------------------
13
+ 1 file changed, 100 insertions(+), 63 deletions(-)
14
+
15
+diff --git a/doc/configuration.txt b/doc/configuration.txt
16
+index 73195ba..8407500 100644
17
+--- a/doc/configuration.txt
18
++++ b/doc/configuration.txt
19
+@@ -13075,44 +13075,76 @@ text is doubled ('""'), which is the format that most tools recognize. Please
20
+ do not insert any column before these ones in order not to break tools which
21
+ use hard-coded column positions.
22
+ 
23
+-  0. pxname: proxy name
24
+-  1. svname: service name (FRONTEND for frontend, BACKEND for backend, any name
25
+-    for server)
26
+-  2. qcur: current queued requests
27
+-  3. qmax: max queued requests
28
+-  4. scur: current sessions
29
+-  5. smax: max sessions
30
+-  6. slim: sessions limit
31
+-  7. stot: total sessions
32
+-  8. bin: bytes in
33
+-  9. bout: bytes out
34
+- 10. dreq: denied requests
35
+- 11. dresp: denied responses
36
+- 12. ereq: request errors
37
+- 13. econ: connection errors
38
+- 14. eresp: response errors (among which srv_abrt)
39
+- 15. wretr: retries (warning)
40
+- 16. wredis: redispatches (warning)
41
+- 17. status: status (UP/DOWN/NOLB/MAINT/MAINT(via)...)
42
+- 18. weight: server weight (server), total weight (backend)
43
+- 19. act: server is active (server), number of active servers (backend)
44
+- 20. bck: server is backup (server), number of backup servers (backend)
45
+- 21. chkfail: number of failed checks
46
+- 22. chkdown: number of UP->DOWN transitions
47
+- 23. lastchg: last status change (in seconds)
48
+- 24. downtime: total downtime (in seconds)
49
+- 25. qlimit: queue limit
50
+- 26. pid: process id (0 for first instance, 1 for second, ...)
51
+- 27. iid: unique proxy id
52
+- 28. sid: service id (unique inside a proxy)
53
+- 29. throttle: warm up status
54
+- 30. lbtot: total number of times a server was selected
55
+- 31. tracked: id of proxy/server if tracking is enabled
56
+- 32. type (0=frontend, 1=backend, 2=server, 3=socket)
57
+- 33. rate: number of sessions per second over last elapsed second
58
+- 34. rate_lim: limit on new sessions per second
59
+- 35. rate_max: max number of new sessions per second
60
+- 36. check_status: status of last health check, one of:
61
++In brackets after each field name are the types which may have a value for
62
++that field. The types are L (Listeners), F (Frontends), B (Backends), and
63
++S (Servers).
64
++
65
++  0. pxname [LFBS]: proxy name
66
++  1. svname [LFBS]: service name (FRONTEND for frontend, BACKEND for backend,
67
++     any name for server/listener)
68
++  2. qcur [..BS]: current queued requests. For the backend this reports the
69
++     number queued without a server assigned.
70
++  3. qmax [..BS]: max value of qcur
71
++  4. scur [LFBS]: current sessions
72
++  5. smax [LFBS]: max sessions
73
++  6. slim [LFBS]: configured session limit
74
++  7. stot [LFBS]: cumulative number of connections
75
++  8. bin [LFBS]: bytes in
76
++  9. bout [LFBS]: bytes out
77
++ 10. dreq [LFB.]: requests denied because of security concerns.
78
++     - For tcp this is because of a matched tcp-request content rule.
79
++     - For http this is because of a matched http-request or tarpit rule.
80
++ 11. dresp [LFBS]: responses denied because of security concerns.
81
++     - For http this is because of a matched http-request rule, or
82
++       "option checkcache".
83
++ 12. ereq [LF..]: request errors. Some of the possible causes are:
84
++     - early termination from the client, before the request has been sent.
85
++     - read error from the client
86
++     - client timeout
87
++     - client closed connection
88
++     - various bad requests from the client.
89
++     - request was tarpitted.
90
++ 13. econ [..BS]: number of requests that encountered an error trying to
91
++     connect to a backend server. The backend stat is the sum of the stat
92
++     for all servers of that backend, plus any connection errors not
93
++     associated with a particular server (such as the backend having no
94
++     active servers).
95
++ 14. eresp [..BS]: response errors. srv_abrt will be counted here also.
96
++     Some other errors are:
97
++     - write error on the client socket (won't be counted for the server stat)
98
++     - failure applying filters to the response.
99
++ 15. wretr [..BS]: number of times a connection to a server was retried.
100
++ 16. wredis [..BS]: number of times a request was redispatched to another
101
++     server. The server value counts the number of times that server was
102
++     switched away from.
103
++ 17. status [LFBS]: status (UP/DOWN/NOLB/MAINT/MAINT(via)...)
104
++ 18. weight [..BS]: server weight (server), total weight (backend)
105
++ 19. act [..BS]: server is active (server), number of active servers (backend)
106
++ 20. bck [..BS]: server is backup (server), number of backup servers (backend)
107
++ 21. chkfail [...S]: number of failed checks. (Only counts checks failed when
108
++     the server is up.)
109
++ 22. chkdown [..BS]: number of UP->DOWN transitions. The backend counter counts
110
++     transitions to the whole backend being down, rather than the sum of the
111
++     counters for each server.
112
++ 23. lastchg [..BS]: number of seconds since the last UP<->DOWN transition
113
++ 24. downtime [..BS]: total downtime (in seconds). The value for the backend
114
++     is the downtime for the whole backend, not the sum of the server downtime.
115
++ 25. qlimit [...S]: configured maxqueue for the server, or nothing in the
116
++     value is 0 (default, meaning no limit)
117
++ 26. pid [LFBS]: process id (0 for first instance, 1 for second, ...)
118
++ 27. iid [LFBS]: unique proxy id
119
++ 28. sid [L..S]: server id (unique inside a proxy)
120
++ 29. throttle [...S]: current throttle percentage for the server, when
121
++     slowstart is active, or no value if not in slowstart.
122
++ 30. lbtot [..BS]: total number of times a server was selected, either for new
123
++     sessions, or when re-dispatching. The server counter is the number
124
++     of times that server was selected.
125
++ 31. tracked [...S]: id of proxy/server if tracking is enabled.
126
++ 32. type [LFBS]: (0=frontend, 1=backend, 2=server, 3=socket/listener)
127
++ 33. rate [.FBS]: number of sessions per second over last elapsed second
128
++ 34. rate_lim [.F..]: configured limit on new sessions per second
129
++ 35. rate_max [.FBS]: max number of new sessions per second
130
++ 36. check_status [...S]: status of last health check, one of:
131
+         UNK     -> unknown
132
+         INI     -> initializing
133
+         SOCKERR -> socket error
134
+@@ -13129,31 +13161,36 @@ use hard-coded column positions.
135
+         L7TOUT  -> layer 7 (HTTP/SMTP) timeout
136
+         L7RSP   -> layer 7 invalid response - protocol error
137
+         L7STS   -> layer 7 response error, for example HTTP 5xx
138
+- 37. check_code: layer5-7 code, if available
139
+- 38. check_duration: time in ms took to finish last health check
140
+- 39. hrsp_1xx: http responses with 1xx code
141
+- 40. hrsp_2xx: http responses with 2xx code
142
+- 41. hrsp_3xx: http responses with 3xx code
143
+- 42. hrsp_4xx: http responses with 4xx code
144
+- 43. hrsp_5xx: http responses with 5xx code
145
+- 44. hrsp_other: http responses with other codes (protocol error)
146
+- 45. hanafail: failed health checks details
147
+- 46. req_rate: HTTP requests per second over last elapsed second
148
+- 47. req_rate_max: max number of HTTP requests per second observed
149
+- 48. req_tot: total number of HTTP requests received
150
+- 49. cli_abrt: number of data transfers aborted by the client
151
+- 50. srv_abrt: number of data transfers aborted by the server (inc. in eresp)
152
+- 51. comp_in: number of HTTP response bytes fed to the compressor
153
+- 52. comp_out: number of HTTP response bytes emitted by the compressor
154
+- 53. comp_byp: number of bytes that bypassed the HTTP compressor (CPU/BW limit)
155
+- 54. comp_rsp: number of HTTP responses that were compressed
156
+- 55. lastsess: number of seconds since last session assigned to server/backend
157
+- 56. last_chk: last health check contents or textual error
158
+- 57. last_agt: last agent check contents or textual error
159
+- 58. qtime: the average queue time in ms over the 1024 last requests
160
+- 59. ctime: the average connect time in ms over the 1024 last requests
161
+- 60. rtime: the average response time in ms over the 1024 last requests (0 for TCP)
162
+- 61. ttime: the average total session time in ms over the 1024 last requests
163
++ 37. check_code [...S]: layer5-7 code, if available
164
++ 38. check_duration [...S]: time in ms took to finish last health check
165
++ 39. hrsp_1xx [.FBS]: http responses with 1xx code
166
++ 40. hrsp_2xx [.FBS]: http responses with 2xx code
167
++ 41. hrsp_3xx [.FBS]: http responses with 3xx code
168
++ 42. hrsp_4xx [.FBS]: http responses with 4xx code
169
++ 43. hrsp_5xx [.FBS]: http responses with 5xx code
170
++ 44. hrsp_other [.FBS]: http responses with other codes (protocol error)
171
++ 45. hanafail [...S]: failed health checks details
172
++ 46. req_rate [.F..]: HTTP requests per second over last elapsed second
173
++ 47. req_rate_max [.F..]: max number of HTTP requests per second observed
174
++ 48. req_tot [.F..]: total number of HTTP requests received
175
++ 49. cli_abrt [..BS]: number of data transfers aborted by the client
176
++ 50. srv_abrt [..BS]: number of data transfers aborted by the server
177
++     (inc. in eresp)
178
++ 51. comp_in [.FB.]: number of HTTP response bytes fed to the compressor
179
++ 52. comp_out [.FB.]: number of HTTP response bytes emitted by the compressor
180
++ 53. comp_byp [.FB.]: number of bytes that bypassed the HTTP compressor
181
++     (CPU/BW limit)
182
++ 54. comp_rsp [.FB.]: number of HTTP responses that were compressed
183
++ 55. lastsess [..BS]: number of seconds since last session assigned to
184
++     server/backend
185
++ 56. last_chk [...S]: last health check contents or textual error
186
++ 57. last_agt [...S]: last agent check contents or textual error
187
++ 58. qtime [..BS]: the average queue time in ms over the 1024 last requests
188
++ 59. ctime [..BS]: the average connect time in ms over the 1024 last requests
189
++ 60. rtime [..BS]: the average response time in ms over the 1024 last requests
190
++     (0 for TCP)
191
++ 61. ttime [..BS]: the average total session time in ms over the 1024 last
192
++     requests
193
+ 
194
+ 
195
+ 9.2. Unix Socket commands
196
+-- 
197
+1.8.5.5
198
+

+ 138
- 0
net/haproxy/patches/0021-BUG-MEDIUM-backend-Update-hash-to-use-unsigned-int-t.patch Zobrazit soubor

@@ -0,0 +1,138 @@
1
+From 82456753cae9200aa1f4031f64c22c08e130f072 Mon Sep 17 00:00:00 2001
2
+From: Dan Dubovik <ddubovik@godaddy.com>
3
+Date: Tue, 8 Jul 2014 08:51:03 -0700
4
+Subject: [PATCH 21/21] BUG/MEDIUM: backend: Update hash to use unsigned int
5
+ throughout
6
+
7
+When we were generating a hash, it was done using an unsigned long.  When the hash was used
8
+to select a backend, it was sent as an unsigned int.  This made it difficult to predict which
9
+backend would be selected.
10
+
11
+This patch updates get_hash, and the hash methods to use an unsigned int, to remain consistent
12
+throughout the codebase.
13
+
14
+This fix should be backported to 1.5 and probably in part to 1.4.
15
+(cherry picked from commit bd57a9f977f60fcf7818f462953da3740e3bd010)
16
+---
17
+ include/common/hash.h |  6 +++---
18
+ src/backend.c         | 14 +++++++-------
19
+ src/hash.c            | 10 +++++-----
20
+ 3 files changed, 15 insertions(+), 15 deletions(-)
21
+
22
+diff --git a/include/common/hash.h b/include/common/hash.h
23
+index 379bf89..7039ba5 100644
24
+--- a/include/common/hash.h
25
++++ b/include/common/hash.h
26
+@@ -22,8 +22,8 @@
27
+ #ifndef _COMMON_HASH_H_
28
+ #define _COMMON_HASH_H_
29
+ 
30
+-unsigned long hash_djb2(const char *key, int len);
31
+-unsigned long hash_wt6(const char *key, int len);
32
+-unsigned long hash_sdbm(const char *key, int len);
33
++unsigned int hash_djb2(const char *key, int len);
34
++unsigned int hash_wt6(const char *key, int len);
35
++unsigned int hash_sdbm(const char *key, int len);
36
+ 
37
+ #endif /* _COMMON_HASH_H_ */
38
+diff --git a/src/backend.c b/src/backend.c
39
+index 5ddb88c..a96b767 100644
40
+--- a/src/backend.c
41
++++ b/src/backend.c
42
+@@ -63,9 +63,9 @@ int be_lastsession(const struct proxy *be)
43
+ }
44
+ 
45
+ /* helper function to invoke the correct hash method */
46
+-static unsigned long gen_hash(const struct proxy* px, const char* key, unsigned long len)
47
++static unsigned int gen_hash(const struct proxy* px, const char* key, unsigned long len)
48
+ {
49
+-	unsigned long hash;
50
++	unsigned int hash;
51
+ 
52
+ 	switch (px->lbprm.algo & BE_LB_HASH_FUNC) {
53
+ 	case BE_LB_HFCN_DJB2:
54
+@@ -183,7 +183,7 @@ struct server *get_server_sh(struct proxy *px, const char *addr, int len)
55
+  */
56
+ struct server *get_server_uh(struct proxy *px, char *uri, int uri_len)
57
+ {
58
+-	unsigned long hash = 0;
59
++	unsigned int hash = 0;
60
+ 	int c;
61
+ 	int slashes = 0;
62
+ 	const char *start, *end;
63
+@@ -232,7 +232,7 @@ struct server *get_server_uh(struct proxy *px, char *uri, int uri_len)
64
+  */
65
+ struct server *get_server_ph(struct proxy *px, const char *uri, int uri_len)
66
+ {
67
+-	unsigned long hash = 0;
68
++	unsigned int hash = 0;
69
+ 	const char *start, *end;
70
+ 	const char *p;
71
+ 	const char *params;
72
+@@ -294,7 +294,7 @@ struct server *get_server_ph(struct proxy *px, const char *uri, int uri_len)
73
+  */
74
+ struct server *get_server_ph_post(struct session *s)
75
+ {
76
+-	unsigned long    hash = 0;
77
++	unsigned int hash = 0;
78
+ 	struct http_txn *txn  = &s->txn;
79
+ 	struct channel   *req = s->req;
80
+ 	struct http_msg *msg  = &txn->req;
81
+@@ -372,7 +372,7 @@ struct server *get_server_ph_post(struct session *s)
82
+  */
83
+ struct server *get_server_hh(struct session *s)
84
+ {
85
+-	unsigned long    hash = 0;
86
++	unsigned int hash = 0;
87
+ 	struct http_txn *txn  = &s->txn;
88
+ 	struct proxy    *px   = s->be;
89
+ 	unsigned int     plen = px->hh_len;
90
+@@ -444,7 +444,7 @@ struct server *get_server_hh(struct session *s)
91
+ /* RDP Cookie HASH.  */
92
+ struct server *get_server_rch(struct session *s)
93
+ {
94
+-	unsigned long    hash = 0;
95
++	unsigned int hash = 0;
96
+ 	struct proxy    *px   = s->be;
97
+ 	unsigned long    len;
98
+ 	int              ret;
99
+diff --git a/src/hash.c b/src/hash.c
100
+index 034685e..aa236cb 100644
101
+--- a/src/hash.c
102
++++ b/src/hash.c
103
+@@ -17,7 +17,7 @@
104
+ #include <common/hash.h>
105
+ 
106
+ 
107
+-unsigned long hash_wt6(const char *key, int len)
108
++unsigned int hash_wt6(const char *key, int len)
109
+ {
110
+ 	unsigned h0 = 0xa53c965aUL;
111
+ 	unsigned h1 = 0x5ca6953aUL;
112
+@@ -44,9 +44,9 @@ unsigned long hash_wt6(const char *key, int len)
113
+ 	return h0 ^ h1;
114
+ }
115
+ 
116
+-unsigned long hash_djb2(const char *key, int len)
117
++unsigned int hash_djb2(const char *key, int len)
118
+ {
119
+-	unsigned long hash = 5381;
120
++	unsigned int hash = 5381;
121
+ 
122
+ 	/* the hash unrolled eight times */
123
+ 	for (; len >= 8; len -= 8) {
124
+@@ -72,9 +72,9 @@ unsigned long hash_djb2(const char *key, int len)
125
+ 	return hash;
126
+ }
127
+ 
128
+-unsigned long hash_sdbm(const char *key, int len)
129
++unsigned int hash_sdbm(const char *key, int len)
130
+ {
131
+-	unsigned long hash = 0;
132
++	unsigned int hash = 0;
133
+ 	int c;
134
+ 
135
+ 	while (len--) {
136
+-- 
137
+1.8.5.5
138
+