forked from pool/haproxy
Accepting request 252328 from network:ha-clustering:Factory
1 OBS-URL: https://build.opensuse.org/request/show/252328 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/haproxy?expand=0&rev=13
This commit is contained in:
parent
24c81ab094
commit
aeb20f101c
@ -0,0 +1,35 @@
|
||||
From e99d44d4bc3423b721c7f654fd1778b9822a94e3 Mon Sep 17 00:00:00 2001
|
||||
From: Olivier <webmaster@ajeux.com>
|
||||
Date: Fri, 5 Sep 2014 18:49:10 +0200
|
||||
Subject: [PATCH 01/15] DOC: clearly state that the "show sess" output format
|
||||
is not fixed
|
||||
|
||||
It requires to look at the code (src/dumpstats.c) since the format may
|
||||
change at any moment.
|
||||
(cherry picked from commit ce31e6e3baebe75a2e6f6b5c66553db8d76dff0c)
|
||||
---
|
||||
doc/configuration.txt | 8 +++++---
|
||||
1 file changed, 5 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/doc/configuration.txt b/doc/configuration.txt
|
||||
index 19df5ae..1ecf15a 100644
|
||||
--- a/doc/configuration.txt
|
||||
+++ b/doc/configuration.txt
|
||||
@@ -13734,9 +13734,11 @@ show sess <id>
|
||||
of "show sess" (it corresponds to the session pointer). Those information are
|
||||
useless to most users but may be used by haproxy developers to troubleshoot a
|
||||
complex bug. The output format is intentionally not documented so that it can
|
||||
- freely evolve depending on demands. The special id "all" dumps the states of
|
||||
- all sessions, which can be avoided as much as possible as it is highly CPU
|
||||
- intensive and can take a lot of time.
|
||||
+ freely evolve depending on demands. You may find a description of all fields
|
||||
+ returned in src/dumpstats.c
|
||||
+
|
||||
+ The special id "all" dumps the states of all sessions, which must be avoided
|
||||
+ as much as possible as it is highly CPU intensive and can take a lot of time.
|
||||
|
||||
show stat [<iid> <type> <sid>]
|
||||
Dump statistics in the CSV format. By passing <id>, <type> and <sid>, it is
|
||||
--
|
||||
1.8.4.5
|
||||
|
@ -0,0 +1,28 @@
|
||||
From 815d7d5c348575181874429b93b0ebdb0cf873c2 Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Doucet <webmaster@ajeux.com>
|
||||
Date: Mon, 8 Sep 2014 11:23:00 +0200
|
||||
Subject: [PATCH 02/15] MINOR: stats: fix minor typo fix in
|
||||
stats_dump_errors_to_buffer()
|
||||
|
||||
Remove the space before the colon to match the format used in the frontend.
|
||||
(cherry picked from commit 08afdcb47bc39c071787f8fc2066776e1c5e8607)
|
||||
---
|
||||
src/dumpstats.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/dumpstats.c b/src/dumpstats.c
|
||||
index 5365042..09bc7f6 100644
|
||||
--- a/src/dumpstats.c
|
||||
+++ b/src/dumpstats.c
|
||||
@@ -6045,7 +6045,7 @@ static int stats_dump_errors_to_buffer(struct stream_interface *si)
|
||||
break;
|
||||
case 1:
|
||||
chunk_appendf(&trash,
|
||||
- " backend %s (#%d) : invalid response\n"
|
||||
+ " backend %s (#%d): invalid response\n"
|
||||
" frontend %s (#%d)",
|
||||
appctx->ctx.errors.px->id, appctx->ctx.errors.px->uuid,
|
||||
es->oe->id, es->oe->uuid);
|
||||
--
|
||||
1.8.4.5
|
||||
|
105
0003-MEDIUM-Improve-signal-handling-in-systemd-wrapper.patch
Normal file
105
0003-MEDIUM-Improve-signal-handling-in-systemd-wrapper.patch
Normal file
@ -0,0 +1,105 @@
|
||||
From 62c8565cd5bbda6ac0dd818fa26922eeaef1605c Mon Sep 17 00:00:00 2001
|
||||
From: Conrad Hoffmann <conrad@soundcloud.com>
|
||||
Date: Mon, 28 Jul 2014 23:52:20 +0200
|
||||
Subject: [PATCH 03/15] MEDIUM: Improve signal handling in systemd wrapper.
|
||||
|
||||
Move all code out of the signal handlers, since this is potentially
|
||||
dangerous. To make sure the signal handlers behave as expected, use
|
||||
sigaction() instead of signal(). That also obsoletes messing with
|
||||
the signal mask after restart.
|
||||
|
||||
Signed-off-by: Conrad Hoffmann <conrad@soundcloud.com>
|
||||
(cherry picked from commit 5b5ea9c93384da49eea0f67ebed0966d4167b17a)
|
||||
---
|
||||
src/haproxy-systemd-wrapper.c | 37 ++++++++++++++++++++++++-------------
|
||||
1 file changed, 24 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/src/haproxy-systemd-wrapper.c b/src/haproxy-systemd-wrapper.c
|
||||
index 529b213..90a94ce 100644
|
||||
--- a/src/haproxy-systemd-wrapper.c
|
||||
+++ b/src/haproxy-systemd-wrapper.c
|
||||
@@ -22,6 +22,8 @@
|
||||
#define SD_DEBUG "<7>"
|
||||
#define SD_NOTICE "<5>"
|
||||
|
||||
+static volatile sig_atomic_t caught_signal;
|
||||
+
|
||||
static char *pid_file = "/run/haproxy.pid";
|
||||
static int wrapper_argc;
|
||||
static char **wrapper_argv;
|
||||
@@ -103,7 +105,12 @@ static int read_pids(char ***pid_strv)
|
||||
return read;
|
||||
}
|
||||
|
||||
-static void sigusr2_handler(int signum __attribute__((unused)))
|
||||
+static void signal_handler(int signum)
|
||||
+{
|
||||
+ caught_signal = signum;
|
||||
+}
|
||||
+
|
||||
+static void do_restart(void)
|
||||
{
|
||||
setenv(REEXEC_FLAG, "1", 1);
|
||||
fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: re-executing\n");
|
||||
@@ -111,7 +118,7 @@ static void sigusr2_handler(int signum __attribute__((unused)))
|
||||
execv(wrapper_argv[0], wrapper_argv);
|
||||
}
|
||||
|
||||
-static void sigint_handler(int signum __attribute__((unused)))
|
||||
+static void do_shutdown(void)
|
||||
{
|
||||
int i, pid;
|
||||
char **pid_strv = NULL;
|
||||
@@ -147,25 +154,21 @@ int main(int argc, char **argv)
|
||||
--argc; ++argv;
|
||||
init(argc, argv);
|
||||
|
||||
- signal(SIGINT, &sigint_handler);
|
||||
- signal(SIGUSR2, &sigusr2_handler);
|
||||
+ struct sigaction sa;
|
||||
+ memset(&sa, 0, sizeof(struct sigaction));
|
||||
+ sa.sa_handler = &signal_handler;
|
||||
+ sigaction(SIGUSR2, &sa, NULL);
|
||||
+ sigaction(SIGINT, &sa, NULL);
|
||||
|
||||
if (getenv(REEXEC_FLAG) != NULL) {
|
||||
/* We are being re-executed: restart HAProxy gracefully */
|
||||
int i;
|
||||
char **pid_strv = NULL;
|
||||
int nb_pid = read_pids(&pid_strv);
|
||||
- sigset_t sigs;
|
||||
|
||||
unsetenv(REEXEC_FLAG);
|
||||
spawn_haproxy(pid_strv, nb_pid);
|
||||
|
||||
- /* Unblock SIGUSR2 which was blocked by the signal handler
|
||||
- * before re-exec */
|
||||
- sigprocmask(SIG_BLOCK, NULL, &sigs);
|
||||
- sigdelset(&sigs, SIGUSR2);
|
||||
- sigprocmask(SIG_SETMASK, &sigs, NULL);
|
||||
-
|
||||
for (i = 0; i < nb_pid; ++i)
|
||||
free(pid_strv[i]);
|
||||
free(pid_strv);
|
||||
@@ -176,8 +179,16 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
status = -1;
|
||||
- while (-1 != wait(&status) || errno == EINTR)
|
||||
- ;
|
||||
+ while (-1 != wait(&status) || errno == EINTR) {
|
||||
+ if (caught_signal == SIGUSR2) {
|
||||
+ caught_signal = 0;
|
||||
+ do_restart();
|
||||
+ }
|
||||
+ else if (caught_signal == SIGINT) {
|
||||
+ caught_signal = 0;
|
||||
+ do_shutdown();
|
||||
+ }
|
||||
+ }
|
||||
|
||||
fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: exit, haproxy RC=%d\n",
|
||||
status);
|
||||
--
|
||||
1.8.4.5
|
||||
|
@ -0,0 +1,48 @@
|
||||
From 6bb7bf7949dd019403b65f400c4b3d0d8589327b Mon Sep 17 00:00:00 2001
|
||||
From: Matt Robenolt <matt@ydekproductions.com>
|
||||
Date: Thu, 11 Sep 2014 05:19:30 +0000
|
||||
Subject: [PATCH 04/15] MINOR: Also accept SIGHUP/SIGTERM in systemd-wrapper
|
||||
|
||||
My proposal is to let haproxy-systemd-wrapper also accept normal
|
||||
SIGHUP/SIGTERM signals to play nicely with other process managers
|
||||
besides just systemd. In my use case, this will be for using with
|
||||
runit which has to ability to change the signal used for a
|
||||
"reload" or "stop" command. It also might be worth renaming this
|
||||
bin to just haproxy-wrapper or something of that sort to separate
|
||||
itself away from systemd. But that's a different discussion. :)
|
||||
(cherry picked from commit c54bdd2a118161b4dc36963b4201edfa7341dadb)
|
||||
---
|
||||
src/haproxy-systemd-wrapper.c | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/haproxy-systemd-wrapper.c b/src/haproxy-systemd-wrapper.c
|
||||
index 90a94ce..cc8baa8 100644
|
||||
--- a/src/haproxy-systemd-wrapper.c
|
||||
+++ b/src/haproxy-systemd-wrapper.c
|
||||
@@ -158,7 +158,9 @@ int main(int argc, char **argv)
|
||||
memset(&sa, 0, sizeof(struct sigaction));
|
||||
sa.sa_handler = &signal_handler;
|
||||
sigaction(SIGUSR2, &sa, NULL);
|
||||
+ sigaction(SIGHUP, &sa, NULL);
|
||||
sigaction(SIGINT, &sa, NULL);
|
||||
+ sigaction(SIGTERM, &sa, NULL);
|
||||
|
||||
if (getenv(REEXEC_FLAG) != NULL) {
|
||||
/* We are being re-executed: restart HAProxy gracefully */
|
||||
@@ -180,11 +182,11 @@ int main(int argc, char **argv)
|
||||
|
||||
status = -1;
|
||||
while (-1 != wait(&status) || errno == EINTR) {
|
||||
- if (caught_signal == SIGUSR2) {
|
||||
+ if (caught_signal == SIGUSR2 || caught_signal == SIGHUP) {
|
||||
caught_signal = 0;
|
||||
do_restart();
|
||||
}
|
||||
- else if (caught_signal == SIGINT) {
|
||||
+ else if (caught_signal == SIGINT || caught_signal == SIGTERM) {
|
||||
caught_signal = 0;
|
||||
do_shutdown();
|
||||
}
|
||||
--
|
||||
1.8.4.5
|
||||
|
@ -0,0 +1,52 @@
|
||||
From 531485c08ffb15b939a28ecf47090e4c93341d1b Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Tue, 16 Sep 2014 15:48:15 +0200
|
||||
Subject: [PATCH 05/15] DOC: indicate in the doc that track-sc* can wait if
|
||||
data are missing
|
||||
|
||||
Since commit 1b71eb5 ("BUG/MEDIUM: counters: fix track-sc* to wait on
|
||||
unstable contents"), we don't need the "if HTTP" anymore. But the doc
|
||||
was not updated to reflect this.
|
||||
|
||||
Since this change was backported to 1.5, this doc update should be
|
||||
backported as well.
|
||||
(cherry picked from commit 4d54c7ca0286588de5060acce9aff8aa9645bb98)
|
||||
---
|
||||
doc/configuration.txt | 10 +++++-----
|
||||
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/doc/configuration.txt b/doc/configuration.txt
|
||||
index 1ecf15a..3c75c92 100644
|
||||
--- a/doc/configuration.txt
|
||||
+++ b/doc/configuration.txt
|
||||
@@ -7470,9 +7470,9 @@ tcp-request content <action> [{if | unless} <condition>]
|
||||
contents will always be immediately present when the rule is evaluated first.
|
||||
|
||||
Tracking layer7 information is also possible provided that the information
|
||||
- are present when the rule is processed. The current solution for making the
|
||||
- rule engine wait for such information is to set an inspect delay and to
|
||||
- condition its execution with an ACL relying on such information.
|
||||
+ are present when the rule is processed. The rule processing engine is able to
|
||||
+ wait until the inspect delay expires when the data to be tracked is not yet
|
||||
+ available.
|
||||
|
||||
Example:
|
||||
# Accept HTTP requests containing a Host header saying "example.com"
|
||||
@@ -7497,12 +7497,12 @@ tcp-request content <action> [{if | unless} <condition>]
|
||||
Example:
|
||||
# Track the last IP from X-Forwarded-For
|
||||
tcp-request inspect-delay 10s
|
||||
- tcp-request content track-sc0 hdr(x-forwarded-for,-1) if HTTP
|
||||
+ tcp-request content track-sc0 hdr(x-forwarded-for,-1)
|
||||
|
||||
Example:
|
||||
# track request counts per "base" (concatenation of Host+URL)
|
||||
tcp-request inspect-delay 10s
|
||||
- tcp-request content track-sc0 base table req-rate if HTTP
|
||||
+ tcp-request content track-sc0 base table req-rate
|
||||
|
||||
Example: track per-frontend and per-backend counters, block abusers at the
|
||||
frontend when the backend detects abuse.
|
||||
--
|
||||
1.8.4.5
|
||||
|
@ -0,0 +1,80 @@
|
||||
From 0cb4b899d370b9d04b3457a1d75dbd658c1a1646 Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Tue, 16 Sep 2014 10:40:38 +0200
|
||||
Subject: [PATCH 06/15] MEDIUM: http: enable header manipulation for 101
|
||||
responses
|
||||
|
||||
Ryan Brock reported that server stickiness did not work for WebSocket
|
||||
because the cookies and headers are not modified on 1xx responses. He
|
||||
found that his browser correctly presents the cookies learned on 101
|
||||
responses, which was not specifically defined in the WebSocket spec,
|
||||
nor in the cookie spec. 101 is a very special case. Being part of 1xx,
|
||||
it's an interim response. But within 1xx, it's special because it's
|
||||
the last HTTP/1 response that transits on the wire, which is different
|
||||
from 100 or 102 which may appear multiple times. So in that sense, we
|
||||
can consider it as a final response regarding HTTP/1, and it makes
|
||||
sense to allow header processing there. Note that we still ensure not
|
||||
to mangle the Connection header, which is critical for HTTP upgrade to
|
||||
continue to work smoothly with agents that are a bit picky about what
|
||||
tokens are found there.
|
||||
|
||||
The rspadd rules are now processed for 101 responses as well, but the
|
||||
cache-control checks are not performed (since no body is delivered).
|
||||
|
||||
Ryan confirmed that this patch works for him.
|
||||
|
||||
It would make sense to backport it to 1.5 given that it improves end
|
||||
user experience on WebSocket servers.
|
||||
(cherry picked from commit ce730de86719d0b5079dd8b0843559e4ff0a1ecc)
|
||||
---
|
||||
src/proto_http.c | 12 +++++++-----
|
||||
1 file changed, 7 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/src/proto_http.c b/src/proto_http.c
|
||||
index 4d27b2c..7e35c8b 100644
|
||||
--- a/src/proto_http.c
|
||||
+++ b/src/proto_http.c
|
||||
@@ -6249,7 +6249,7 @@ int http_process_res_common(struct session *s, struct channel *rep, int an_bit,
|
||||
|
||||
/* add response headers from the rule sets in the same order */
|
||||
list_for_each_entry(wl, &rule_set->rsp_add, list) {
|
||||
- if (txn->status < 200)
|
||||
+ if (txn->status < 200 && txn->status != 101)
|
||||
break;
|
||||
if (wl->cond) {
|
||||
int ret = acl_exec_cond(wl->cond, px, s, txn, SMP_OPT_DIR_RES|SMP_OPT_FINAL);
|
||||
@@ -6270,7 +6270,7 @@ int http_process_res_common(struct session *s, struct channel *rep, int an_bit,
|
||||
}
|
||||
|
||||
/* OK that's all we can do for 1xx responses */
|
||||
- if (unlikely(txn->status < 200))
|
||||
+ if (unlikely(txn->status < 200 && txn->status != 101))
|
||||
goto skip_header_mangling;
|
||||
|
||||
/*
|
||||
@@ -6283,7 +6283,7 @@ int http_process_res_common(struct session *s, struct channel *rep, int an_bit,
|
||||
/*
|
||||
* Check for cache-control or pragma headers if required.
|
||||
*/
|
||||
- if ((s->be->options & PR_O_CHK_CACHE) || (s->be->ck_opts & PR_CK_NOC))
|
||||
+ if (((s->be->options & PR_O_CHK_CACHE) || (s->be->ck_opts & PR_CK_NOC)) && txn->status != 101)
|
||||
check_response_for_cacheability(s, rep);
|
||||
|
||||
/*
|
||||
@@ -6399,9 +6399,11 @@ int http_process_res_common(struct session *s, struct channel *rep, int an_bit,
|
||||
* Adjust "Connection: close" or "Connection: keep-alive" if needed.
|
||||
* If an "Upgrade" token is found, the header is left untouched in order
|
||||
* not to have to deal with some client bugs : some of them fail an upgrade
|
||||
- * if anything but "Upgrade" is present in the Connection header.
|
||||
+ * if anything but "Upgrade" is present in the Connection header. We don't
|
||||
+ * want to touch any 101 response either since it's switching to another
|
||||
+ * protocol.
|
||||
*/
|
||||
- if (!(txn->flags & TX_HDR_CONN_UPG) &&
|
||||
+ if ((txn->status != 101) && !(txn->flags & TX_HDR_CONN_UPG) &&
|
||||
(((txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_TUN) ||
|
||||
((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL ||
|
||||
(s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL))) {
|
||||
--
|
||||
1.8.4.5
|
||||
|
@ -0,0 +1,60 @@
|
||||
From b53934eec71ab34eb3762a89cec326360a5b0bc5 Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Tue, 16 Sep 2014 11:31:31 +0200
|
||||
Subject: [PATCH 07/15] BUG/MEDIUM: config: propagate frontend to backend
|
||||
process binding again.
|
||||
|
||||
This basically reverts 3507d5d ("MEDIUM: proxy: only adjust the backend's
|
||||
bind-process when already set"). It was needed during the transition to
|
||||
the new process binding method but is causing trouble now because frontend
|
||||
to backend binding is not properly propagated.
|
||||
|
||||
This fix should be backported to 1.5.
|
||||
(cherry picked from commit 8a3478ed31a16904f45178c153f4649faf6de675)
|
||||
---
|
||||
src/cfgparse.c | 15 ++++++---------
|
||||
1 file changed, 6 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/src/cfgparse.c b/src/cfgparse.c
|
||||
index 943eba0..5288600 100644
|
||||
--- a/src/cfgparse.c
|
||||
+++ b/src/cfgparse.c
|
||||
@@ -6165,9 +6165,8 @@ int check_config_validity()
|
||||
/* we force the backend to be present on at least all of
|
||||
* the frontend's processes.
|
||||
*/
|
||||
- if (target->bind_proc)
|
||||
- target->bind_proc = curproxy->bind_proc ?
|
||||
- (target->bind_proc | curproxy->bind_proc) : 0;
|
||||
+ target->bind_proc = curproxy->bind_proc ?
|
||||
+ (target->bind_proc | curproxy->bind_proc) : 0;
|
||||
|
||||
/* Emit a warning if this proxy also has some servers */
|
||||
if (curproxy->srv) {
|
||||
@@ -6203,9 +6202,8 @@ int check_config_validity()
|
||||
/* we force the backend to be present on at least all of
|
||||
* the frontend's processes.
|
||||
*/
|
||||
- if (target->bind_proc)
|
||||
- target->bind_proc = curproxy->bind_proc ?
|
||||
- (target->bind_proc | curproxy->bind_proc) : 0;
|
||||
+ target->bind_proc = curproxy->bind_proc ?
|
||||
+ (target->bind_proc | curproxy->bind_proc) : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6257,9 +6255,8 @@ int check_config_validity()
|
||||
/* we force the backend to be present on at least all of
|
||||
* the frontend's processes.
|
||||
*/
|
||||
- if (target->bind_proc)
|
||||
- target->bind_proc = curproxy->bind_proc ?
|
||||
- (target->bind_proc | curproxy->bind_proc) : 0;
|
||||
+ target->bind_proc = curproxy->bind_proc ?
|
||||
+ (target->bind_proc | curproxy->bind_proc) : 0;
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
1.8.4.5
|
||||
|
142
0008-MEDIUM-config-properly-propagate-process-binding-bet.patch
Normal file
142
0008-MEDIUM-config-properly-propagate-process-binding-bet.patch
Normal file
@ -0,0 +1,142 @@
|
||||
From 5436afc9488531a5e2adff3a1a766af375e0922c Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Tue, 16 Sep 2014 12:17:36 +0200
|
||||
Subject: [PATCH 08/15] MEDIUM: config: properly propagate process binding
|
||||
between proxies
|
||||
|
||||
We now recursively propagate the bind-process values between frontends
|
||||
and backends instead of doing it during name resolving. This ensures
|
||||
that we're able to properly propagate all the bind-process directives
|
||||
even across "listen" instances, which are not perfectly covered at the
|
||||
moment, depending on the declaration order.
|
||||
(cherry picked from commit 64ab6077b768ee02b04a36b30ee195639a2fabc1)
|
||||
---
|
||||
src/cfgparse.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++------------
|
||||
1 file changed, 65 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/src/cfgparse.c b/src/cfgparse.c
|
||||
index 5288600..b9853ef 100644
|
||||
--- a/src/cfgparse.c
|
||||
+++ b/src/cfgparse.c
|
||||
@@ -5932,6 +5932,64 @@ int readcfgfile(const char *file)
|
||||
return err_code;
|
||||
}
|
||||
|
||||
+/* This function propagates processes from frontend <from> to backend <to> so
|
||||
+ * that it is always guaranteed that a backend pointed to by a frontend is
|
||||
+ * bound to all of its processes. After that, if the target is a "listen"
|
||||
+ * instance, the function recursively descends the target's own targets along
|
||||
+ * default_backend, use_backend rules, and reqsetbe rules. Since the bits are
|
||||
+ * checked first to ensure that <to> is already bound to all processes of
|
||||
+ * <from>, there is no risk of looping and we ensure to follow the shortest
|
||||
+ * path to the destination.
|
||||
+ *
|
||||
+ * It is possible to set <to> to NULL for the first call so that the function
|
||||
+ * takes care of visiting the initial frontend in <from>.
|
||||
+ *
|
||||
+ * It is important to note that the function relies on the fact that all names
|
||||
+ * have already been resolved.
|
||||
+ */
|
||||
+void propagate_processes(struct proxy *from, struct proxy *to)
|
||||
+{
|
||||
+ struct switching_rule *rule;
|
||||
+ struct hdr_exp *exp;
|
||||
+
|
||||
+ if (to) {
|
||||
+ /* check whether we need to go down */
|
||||
+ if (from->bind_proc &&
|
||||
+ (from->bind_proc & to->bind_proc) == from->bind_proc)
|
||||
+ return;
|
||||
+
|
||||
+ if (!from->bind_proc && !to->bind_proc)
|
||||
+ return;
|
||||
+
|
||||
+ to->bind_proc = from->bind_proc ?
|
||||
+ (to->bind_proc | from->bind_proc) : 0;
|
||||
+
|
||||
+ /* now propagate down */
|
||||
+ from = to;
|
||||
+ }
|
||||
+
|
||||
+ if (!from->cap & PR_CAP_FE)
|
||||
+ return;
|
||||
+
|
||||
+ /* default_backend */
|
||||
+ if (from->defbe.be)
|
||||
+ propagate_processes(from, from->defbe.be);
|
||||
+
|
||||
+ /* use_backend */
|
||||
+ list_for_each_entry(rule, &from->switching_rules, list) {
|
||||
+ to = rule->be.backend;
|
||||
+ propagate_processes(from, to);
|
||||
+ }
|
||||
+
|
||||
+ /* reqsetbe */
|
||||
+ for (exp = from->req_exp; exp != NULL; exp = exp->next) {
|
||||
+ if (exp->action != ACT_SETBE)
|
||||
+ continue;
|
||||
+ to = (struct proxy *)exp->replace;
|
||||
+ propagate_processes(from, to);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Returns the error code, 0 if OK, or any combination of :
|
||||
* - ERR_ABORT: must abort ASAP
|
||||
@@ -6162,11 +6220,6 @@ int check_config_validity()
|
||||
} else {
|
||||
free(curproxy->defbe.name);
|
||||
curproxy->defbe.be = target;
|
||||
- /* we force the backend to be present on at least all of
|
||||
- * the frontend's processes.
|
||||
- */
|
||||
- target->bind_proc = curproxy->bind_proc ?
|
||||
- (target->bind_proc | curproxy->bind_proc) : 0;
|
||||
|
||||
/* Emit a warning if this proxy also has some servers */
|
||||
if (curproxy->srv) {
|
||||
@@ -6199,11 +6252,6 @@ int check_config_validity()
|
||||
} else {
|
||||
free((void *)exp->replace);
|
||||
exp->replace = (const char *)target;
|
||||
- /* we force the backend to be present on at least all of
|
||||
- * the frontend's processes.
|
||||
- */
|
||||
- target->bind_proc = curproxy->bind_proc ?
|
||||
- (target->bind_proc | curproxy->bind_proc) : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6252,15 +6300,10 @@ int check_config_validity()
|
||||
} else {
|
||||
free((void *)rule->be.name);
|
||||
rule->be.backend = target;
|
||||
- /* we force the backend to be present on at least all of
|
||||
- * the frontend's processes.
|
||||
- */
|
||||
- target->bind_proc = curproxy->bind_proc ?
|
||||
- (target->bind_proc | curproxy->bind_proc) : 0;
|
||||
}
|
||||
}
|
||||
|
||||
- /* find the target proxy for 'use_backend' rules */
|
||||
+ /* find the target server for 'use_server' rules */
|
||||
list_for_each_entry(srule, &curproxy->server_rules, list) {
|
||||
struct server *target = findserver(curproxy, srule->srv.name);
|
||||
|
||||
@@ -7131,6 +7174,12 @@ out_uri_auth_compat:
|
||||
}
|
||||
}
|
||||
|
||||
+ /* At this point, target names have already been resolved */
|
||||
+ for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
|
||||
+ if (curproxy->cap & PR_CAP_FE)
|
||||
+ propagate_processes(curproxy, NULL);
|
||||
+ }
|
||||
+
|
||||
/* automatically compute fullconn if not set. We must not do it in the
|
||||
* loop above because cross-references are not yet fully resolved.
|
||||
*/
|
||||
--
|
||||
1.8.4.5
|
||||
|
@ -0,0 +1,93 @@
|
||||
From e56c4f1f76c6731a5a0f4b128540071cffeb1951 Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Tue, 16 Sep 2014 13:21:03 +0200
|
||||
Subject: [PATCH 09/15] MEDIUM: config: make the frontends automatically bind
|
||||
to the listeners' processes
|
||||
|
||||
When a frontend does not have any bind-process directive, make it
|
||||
automatically bind to the union of all of its listeners' processes
|
||||
instead of binding to all processes. That will make it possible to
|
||||
have the expected behaviour without having to explicitly specify a
|
||||
bind-process directive.
|
||||
|
||||
Note that if the listeners are not bound to a specific process, the
|
||||
default is still to bind to all processes.
|
||||
|
||||
This change could be backported to 1.5 as it simplifies process
|
||||
management, and was planned to be done during the 1.5 development phase.
|
||||
(cherry picked from commit b369a045d545b41ef2b250bf747caf83c97e0ca8)
|
||||
---
|
||||
doc/configuration.txt | 4 ++++
|
||||
src/cfgparse.c | 36 ++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 40 insertions(+)
|
||||
|
||||
diff --git a/doc/configuration.txt b/doc/configuration.txt
|
||||
index 3c75c92..1e32057 100644
|
||||
--- a/doc/configuration.txt
|
||||
+++ b/doc/configuration.txt
|
||||
@@ -1905,6 +1905,10 @@ bind-process [ all | odd | even | <number 1-64>[-<number 1-64>] ] ...
|
||||
Each "bind" line may further be limited to a subset of the proxy's processes,
|
||||
please consult the "process" bind keyword in section 5.1.
|
||||
|
||||
+ When a frontend has no explicit "bind-process" line, it tries to bind to all
|
||||
+ the processes referenced by its "bind" lines. That means that frontends can
|
||||
+ easily adapt to their listeners' processes.
|
||||
+
|
||||
If some backends are referenced by frontends bound to other processes, the
|
||||
backend automatically inherits the frontend's processes.
|
||||
|
||||
diff --git a/src/cfgparse.c b/src/cfgparse.c
|
||||
index b9853ef..d53f69e 100644
|
||||
--- a/src/cfgparse.c
|
||||
+++ b/src/cfgparse.c
|
||||
@@ -7175,11 +7175,47 @@ out_uri_auth_compat:
|
||||
}
|
||||
|
||||
/* At this point, target names have already been resolved */
|
||||
+
|
||||
+ /* Make each frontend inherit bind-process from its listeners when not specified. */
|
||||
+ for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
|
||||
+ if (curproxy->bind_proc)
|
||||
+ continue;
|
||||
+
|
||||
+ list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
|
||||
+ unsigned long mask;
|
||||
+
|
||||
+ mask = bind_conf->bind_proc ? bind_conf->bind_proc : ~0UL;
|
||||
+ curproxy->bind_proc |= mask;
|
||||
+ }
|
||||
+
|
||||
+ if (!curproxy->bind_proc)
|
||||
+ curproxy->bind_proc = ~0UL;
|
||||
+ }
|
||||
+
|
||||
+ if (global.stats_fe) {
|
||||
+ list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
|
||||
+ unsigned long mask;
|
||||
+
|
||||
+ mask = bind_conf->bind_proc ? bind_conf->bind_proc : ~0UL;
|
||||
+ global.stats_fe->bind_proc |= mask;
|
||||
+ }
|
||||
+ if (!global.stats_fe->bind_proc)
|
||||
+ global.stats_fe->bind_proc = ~0UL;
|
||||
+ }
|
||||
+
|
||||
+ /* propagate bindings from frontends to backends */
|
||||
for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
|
||||
if (curproxy->cap & PR_CAP_FE)
|
||||
propagate_processes(curproxy, NULL);
|
||||
}
|
||||
|
||||
+ /* Bind each unbound backend to all processes when not specified. */
|
||||
+ for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
|
||||
+ if (curproxy->bind_proc)
|
||||
+ continue;
|
||||
+ curproxy->bind_proc = ~0UL;
|
||||
+ }
|
||||
+
|
||||
/* automatically compute fullconn if not set. We must not do it in the
|
||||
* loop above because cross-references are not yet fully resolved.
|
||||
*/
|
||||
--
|
||||
1.8.4.5
|
||||
|
209
0010-MEDIUM-config-compute-the-exact-bind-process-before-.patch
Normal file
209
0010-MEDIUM-config-compute-the-exact-bind-process-before-.patch
Normal file
@ -0,0 +1,209 @@
|
||||
From 91b00c2194b728ccd61133cca83f03de3650b674 Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Tue, 16 Sep 2014 13:41:21 +0200
|
||||
Subject: [PATCH 10/15] MEDIUM: config: compute the exact bind-process before
|
||||
listener's maxaccept
|
||||
|
||||
This is a continuation of previous patch, the listener's maxaccept is divided
|
||||
by the number of processes, so it's best if we can swap the two blocks so that
|
||||
the number of processes is already known when computing the maxaccept value.
|
||||
(cherry picked from commit 419ead8eca9237f9cc2ec32630d96fde333282ee)
|
||||
---
|
||||
src/cfgparse.c | 156 ++++++++++++++++++++++++++++++---------------------------
|
||||
1 file changed, 81 insertions(+), 75 deletions(-)
|
||||
|
||||
diff --git a/src/cfgparse.c b/src/cfgparse.c
|
||||
index d53f69e..f3907bf 100644
|
||||
--- a/src/cfgparse.c
|
||||
+++ b/src/cfgparse.c
|
||||
@@ -6042,12 +6042,11 @@ int check_config_validity()
|
||||
proxy = next;
|
||||
}
|
||||
|
||||
- while (curproxy != NULL) {
|
||||
+ for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
|
||||
struct switching_rule *rule;
|
||||
struct server_rule *srule;
|
||||
struct sticking_rule *mrule;
|
||||
struct tcp_rule *trule;
|
||||
- struct listener *listener;
|
||||
unsigned int next_id;
|
||||
int nbproc;
|
||||
|
||||
@@ -6115,14 +6114,6 @@ int check_config_validity()
|
||||
}
|
||||
}
|
||||
|
||||
- /* here, if bind_proc is null, it means no limit, otherwise it's explicit.
|
||||
- * We now check how many processes the proxy will effectively run on.
|
||||
- */
|
||||
-
|
||||
- nbproc = global.nbproc;
|
||||
- if (curproxy->bind_proc)
|
||||
- nbproc = popcount(curproxy->bind_proc & nbits(global.nbproc));
|
||||
-
|
||||
if (global.nbproc > 1 && curproxy->table.peers.name) {
|
||||
Alert("Proxy '%s': peers can't be used in multi-process mode (nbproc > 1).\n",
|
||||
curproxy->id);
|
||||
@@ -7005,6 +6996,86 @@ out_uri_auth_compat:
|
||||
if (curproxy->options2 & PR_O2_RDPC_PRST)
|
||||
curproxy->be_req_ana |= AN_REQ_PRST_RDP_COOKIE;
|
||||
}
|
||||
+ }
|
||||
+
|
||||
+ /***********************************************************/
|
||||
+ /* At this point, target names have already been resolved. */
|
||||
+ /***********************************************************/
|
||||
+
|
||||
+ /* Check multi-process mode compatibility */
|
||||
+
|
||||
+ if (global.nbproc > 1 && global.stats_fe) {
|
||||
+ list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
|
||||
+ unsigned long mask;
|
||||
+
|
||||
+ mask = nbits(global.nbproc);
|
||||
+ if (global.stats_fe->bind_proc)
|
||||
+ mask &= global.stats_fe->bind_proc;
|
||||
+
|
||||
+ if (bind_conf->bind_proc)
|
||||
+ mask &= bind_conf->bind_proc;
|
||||
+
|
||||
+ /* stop here if more than one process is used */
|
||||
+ if (popcount(mask) > 1)
|
||||
+ break;
|
||||
+ }
|
||||
+ if (&bind_conf->by_fe != &global.stats_fe->conf.bind) {
|
||||
+ Warning("stats socket will not work as expected in multi-process mode (nbproc > 1), you should force process binding globally using 'stats bind-process' or per socket using the 'process' attribute.\n");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Make each frontend inherit bind-process from its listeners when not specified. */
|
||||
+ for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
|
||||
+ if (curproxy->bind_proc)
|
||||
+ continue;
|
||||
+
|
||||
+ list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
|
||||
+ unsigned long mask;
|
||||
+
|
||||
+ mask = bind_conf->bind_proc ? bind_conf->bind_proc : ~0UL;
|
||||
+ curproxy->bind_proc |= mask;
|
||||
+ }
|
||||
+
|
||||
+ if (!curproxy->bind_proc)
|
||||
+ curproxy->bind_proc = ~0UL;
|
||||
+ }
|
||||
+
|
||||
+ if (global.stats_fe) {
|
||||
+ list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
|
||||
+ unsigned long mask;
|
||||
+
|
||||
+ mask = bind_conf->bind_proc ? bind_conf->bind_proc : ~0UL;
|
||||
+ global.stats_fe->bind_proc |= mask;
|
||||
+ }
|
||||
+ if (!global.stats_fe->bind_proc)
|
||||
+ global.stats_fe->bind_proc = ~0UL;
|
||||
+ }
|
||||
+
|
||||
+ /* propagate bindings from frontends to backends */
|
||||
+ for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
|
||||
+ if (curproxy->cap & PR_CAP_FE)
|
||||
+ propagate_processes(curproxy, NULL);
|
||||
+ }
|
||||
+
|
||||
+ /* Bind each unbound backend to all processes when not specified. */
|
||||
+ for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
|
||||
+ if (curproxy->bind_proc)
|
||||
+ continue;
|
||||
+ curproxy->bind_proc = ~0UL;
|
||||
+ }
|
||||
+
|
||||
+ /*******************************************************/
|
||||
+ /* At this step, all proxies have a non-null bind_proc */
|
||||
+ /*******************************************************/
|
||||
+
|
||||
+ /* perform the final checks before creating tasks */
|
||||
+
|
||||
+ for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
|
||||
+ struct listener *listener;
|
||||
+ unsigned int next_id;
|
||||
+ int nbproc;
|
||||
+
|
||||
+ nbproc = popcount(curproxy->bind_proc & nbits(global.nbproc));
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
/* Configure SSL for each bind line.
|
||||
@@ -7149,71 +7220,6 @@ out_uri_auth_compat:
|
||||
curproxy->id);
|
||||
cfgerr++;
|
||||
}
|
||||
-
|
||||
- curproxy = curproxy->next;
|
||||
- }
|
||||
-
|
||||
- /* Check multi-process mode compatibility */
|
||||
- if (global.nbproc > 1 && global.stats_fe) {
|
||||
- list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
|
||||
- unsigned long mask;
|
||||
-
|
||||
- mask = nbits(global.nbproc);
|
||||
- if (global.stats_fe->bind_proc)
|
||||
- mask &= global.stats_fe->bind_proc;
|
||||
-
|
||||
- if (bind_conf->bind_proc)
|
||||
- mask &= bind_conf->bind_proc;
|
||||
-
|
||||
- /* stop here if more than one process is used */
|
||||
- if (popcount(mask) > 1)
|
||||
- break;
|
||||
- }
|
||||
- if (&bind_conf->by_fe != &global.stats_fe->conf.bind) {
|
||||
- Warning("stats socket will not work as expected in multi-process mode (nbproc > 1), you should force process binding globally using 'stats bind-process' or per socket using the 'process' attribute.\n");
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- /* At this point, target names have already been resolved */
|
||||
-
|
||||
- /* Make each frontend inherit bind-process from its listeners when not specified. */
|
||||
- for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
|
||||
- if (curproxy->bind_proc)
|
||||
- continue;
|
||||
-
|
||||
- list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
|
||||
- unsigned long mask;
|
||||
-
|
||||
- mask = bind_conf->bind_proc ? bind_conf->bind_proc : ~0UL;
|
||||
- curproxy->bind_proc |= mask;
|
||||
- }
|
||||
-
|
||||
- if (!curproxy->bind_proc)
|
||||
- curproxy->bind_proc = ~0UL;
|
||||
- }
|
||||
-
|
||||
- if (global.stats_fe) {
|
||||
- list_for_each_entry(bind_conf, &global.stats_fe->conf.bind, by_fe) {
|
||||
- unsigned long mask;
|
||||
-
|
||||
- mask = bind_conf->bind_proc ? bind_conf->bind_proc : ~0UL;
|
||||
- global.stats_fe->bind_proc |= mask;
|
||||
- }
|
||||
- if (!global.stats_fe->bind_proc)
|
||||
- global.stats_fe->bind_proc = ~0UL;
|
||||
- }
|
||||
-
|
||||
- /* propagate bindings from frontends to backends */
|
||||
- for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
|
||||
- if (curproxy->cap & PR_CAP_FE)
|
||||
- propagate_processes(curproxy, NULL);
|
||||
- }
|
||||
-
|
||||
- /* Bind each unbound backend to all processes when not specified. */
|
||||
- for (curproxy = proxy; curproxy; curproxy = curproxy->next) {
|
||||
- if (curproxy->bind_proc)
|
||||
- continue;
|
||||
- curproxy->bind_proc = ~0UL;
|
||||
}
|
||||
|
||||
/* automatically compute fullconn if not set. We must not do it in the
|
||||
--
|
||||
1.8.4.5
|
||||
|
@ -0,0 +1,45 @@
|
||||
From 036a83e9c300a42386cd378022420e52a43b314f Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Tue, 16 Sep 2014 15:11:04 +0200
|
||||
Subject: [PATCH 11/15] MEDIUM: config: only warn if stats are attached to
|
||||
multi-process bind directives
|
||||
|
||||
Some users want to have a stats frontend with one line per process, but while
|
||||
100% valid and safe, the config parser emits a warning. Relax this check to
|
||||
ensure that the warning is only emitted if at least one of the listeners is
|
||||
bound to multiple processes, or if the directive is placed in a backend called
|
||||
from multiple processes (since in this case we don't know if it's safe).
|
||||
(cherry picked from commit eb791e03b5c5abfddb24a439fa6434788db026b7)
|
||||
---
|
||||
src/cfgparse.c | 15 +++++++++++++--
|
||||
1 file changed, 13 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/cfgparse.c b/src/cfgparse.c
|
||||
index f3907bf..5668393 100644
|
||||
--- a/src/cfgparse.c
|
||||
+++ b/src/cfgparse.c
|
||||
@@ -7189,8 +7189,19 @@ out_uri_auth_compat:
|
||||
|
||||
if (nbproc > 1) {
|
||||
if (curproxy->uri_auth) {
|
||||
- Warning("Proxy '%s': in multi-process mode, stats will be limited to process assigned to the current request.\n",
|
||||
- curproxy->id);
|
||||
+ int count, maxproc = 0;
|
||||
+
|
||||
+ list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
|
||||
+ count = popcount(bind_conf->bind_proc);
|
||||
+ if (count > maxproc)
|
||||
+ maxproc = count;
|
||||
+ }
|
||||
+ /* backends have 0, frontends have 1 or more */
|
||||
+ if (maxproc != 1)
|
||||
+ Warning("Proxy '%s': in multi-process mode, stats will be"
|
||||
+ " limited to process assigned to the current request.\n",
|
||||
+ curproxy->id);
|
||||
+
|
||||
if (!LIST_ISEMPTY(&curproxy->uri_auth->admin_rules)) {
|
||||
Warning("Proxy '%s': stats admin will not work correctly in multi-process mode.\n",
|
||||
curproxy->id);
|
||||
--
|
||||
1.8.4.5
|
||||
|
110
0012-MEDIUM-config-report-it-when-tcp-request-rules-are-m.patch
Normal file
110
0012-MEDIUM-config-report-it-when-tcp-request-rules-are-m.patch
Normal file
@ -0,0 +1,110 @@
|
||||
From 8b3c808c37dd5672f87e7b61085295e1316a6694 Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Tue, 16 Sep 2014 15:39:51 +0200
|
||||
Subject: [PATCH 12/15] MEDIUM: config: report it when tcp-request rules are
|
||||
misplaced
|
||||
|
||||
A config where a tcp-request rule appears after an http-request rule
|
||||
might seem valid but it is not. So let's report a warning about this
|
||||
since this case is hard to detect by the naked eye.
|
||||
(cherry picked from commit 3986b9c14037f446f5f5bec6207a39e1bd753fae)
|
||||
---
|
||||
include/common/cfgparse.h | 2 ++
|
||||
src/cfgparse.c | 38 ++++++++++++++++++++++++++++++++++++++
|
||||
src/proto_tcp.c | 4 ++++
|
||||
3 files changed, 44 insertions(+)
|
||||
|
||||
diff --git a/include/common/cfgparse.h b/include/common/cfgparse.h
|
||||
index 80310ae..86a0035 100644
|
||||
--- a/include/common/cfgparse.h
|
||||
+++ b/include/common/cfgparse.h
|
||||
@@ -73,6 +73,8 @@ int check_config_validity();
|
||||
int str2listener(char *str, struct proxy *curproxy, struct bind_conf *bind_conf, const char *file, int line, char **err);
|
||||
int cfg_register_section(char *section_name,
|
||||
int (*section_parser)(const char *, int, char **, int));
|
||||
+int warnif_misplaced_tcp_conn(struct proxy *proxy, const char *file, int line, const char *arg);
|
||||
+int warnif_misplaced_tcp_cont(struct proxy *proxy, const char *file, int line, const char *arg);
|
||||
|
||||
/*
|
||||
* Sends a warning if proxy <proxy> does not have at least one of the
|
||||
diff --git a/src/cfgparse.c b/src/cfgparse.c
|
||||
index 5668393..9ff44e9 100644
|
||||
--- a/src/cfgparse.c
|
||||
+++ b/src/cfgparse.c
|
||||
@@ -317,6 +317,19 @@ int str2listener(char *str, struct proxy *curproxy, struct bind_conf *bind_conf,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/* Report a warning if a rule is placed after a 'tcp-request content' rule.
|
||||
+ * Return 1 if the warning has been emitted, otherwise 0.
|
||||
+ */
|
||||
+int warnif_rule_after_tcp_cont(struct proxy *proxy, const char *file, int line, const char *arg)
|
||||
+{
|
||||
+ if (!LIST_ISEMPTY(&proxy->tcp_req.inspect_rules)) {
|
||||
+ Warning("parsing [%s:%d] : a '%s' rule placed after a 'tcp-request content' rule will still be processed before.\n",
|
||||
+ file, line, arg);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/* Report a warning if a rule is placed after a 'block' rule.
|
||||
* Return 1 if the warning has been emitted, otherwise 0.
|
||||
*/
|
||||
@@ -408,6 +421,31 @@ int warnif_rule_after_use_server(struct proxy *proxy, const char *file, int line
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/* report a warning if a "tcp request connection" rule is dangerously placed */
|
||||
+int warnif_misplaced_tcp_conn(struct proxy *proxy, const char *file, int line, const char *arg)
|
||||
+{
|
||||
+ return warnif_rule_after_tcp_cont(proxy, file, line, arg) ||
|
||||
+ warnif_rule_after_block(proxy, file, line, arg) ||
|
||||
+ warnif_rule_after_http_req(proxy, file, line, arg) ||
|
||||
+ warnif_rule_after_reqxxx(proxy, file, line, arg) ||
|
||||
+ warnif_rule_after_reqadd(proxy, file, line, arg) ||
|
||||
+ warnif_rule_after_redirect(proxy, file, line, arg) ||
|
||||
+ warnif_rule_after_use_backend(proxy, file, line, arg) ||
|
||||
+ warnif_rule_after_use_server(proxy, file, line, arg);
|
||||
+}
|
||||
+
|
||||
+/* report a warning if a "tcp request content" rule is dangerously placed */
|
||||
+int warnif_misplaced_tcp_cont(struct proxy *proxy, const char *file, int line, const char *arg)
|
||||
+{
|
||||
+ return warnif_rule_after_block(proxy, file, line, arg) ||
|
||||
+ warnif_rule_after_http_req(proxy, file, line, arg) ||
|
||||
+ warnif_rule_after_reqxxx(proxy, file, line, arg) ||
|
||||
+ warnif_rule_after_reqadd(proxy, file, line, arg) ||
|
||||
+ warnif_rule_after_redirect(proxy, file, line, arg) ||
|
||||
+ warnif_rule_after_use_backend(proxy, file, line, arg) ||
|
||||
+ warnif_rule_after_use_server(proxy, file, line, arg);
|
||||
+}
|
||||
+
|
||||
/* report a warning if a block rule is dangerously placed */
|
||||
int warnif_misplaced_block(struct proxy *proxy, const char *file, int line, const char *arg)
|
||||
{
|
||||
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
|
||||
index 72dc92b..940c3f1 100644
|
||||
--- a/src/proto_tcp.c
|
||||
+++ b/src/proto_tcp.c
|
||||
@@ -1711,6 +1711,8 @@ static int tcp_parse_tcp_req(char **args, int section_type, struct proxy *curpx,
|
||||
warn++;
|
||||
}
|
||||
|
||||
+ /* the following function directly emits the warning */
|
||||
+ warnif_misplaced_tcp_cont(curpx, file, line, args[0]);
|
||||
LIST_ADDQ(&curpx->tcp_req.inspect_rules, &rule->list);
|
||||
}
|
||||
else if (strcmp(args[1], "connection") == 0) {
|
||||
@@ -1754,6 +1756,8 @@ static int tcp_parse_tcp_req(char **args, int section_type, struct proxy *curpx,
|
||||
warn++;
|
||||
}
|
||||
|
||||
+ /* the following function directly emits the warning */
|
||||
+ warnif_misplaced_tcp_conn(curpx, file, line, args[0]);
|
||||
LIST_ADDQ(&curpx->tcp_req.l4_rules, &rule->list);
|
||||
}
|
||||
else {
|
||||
--
|
||||
1.8.4.5
|
||||
|
@ -0,0 +1,52 @@
|
||||
From 7fc7ebd5785629074297ee324b22e0aee9ad00f9 Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Tue, 16 Sep 2014 16:21:19 +0200
|
||||
Subject: [PATCH 13/15] MINOR: config: detect the case where a tcp-request
|
||||
content rule has no inspect-delay
|
||||
|
||||
If a frontend has any tcp-request content rule relying on request contents
|
||||
without any inspect delay, we now emit a warning as this will randomly match.
|
||||
|
||||
This can be backported to 1.5 as it reduces the support effort.
|
||||
(cherry picked from commit e42bd96d0acc38ea7c546c8de8115ffd1dd6c3f3)
|
||||
---
|
||||
src/cfgparse.c | 23 +++++++++++++++++++++++
|
||||
1 file changed, 23 insertions(+)
|
||||
|
||||
diff --git a/src/cfgparse.c b/src/cfgparse.c
|
||||
index 9ff44e9..f723a3a 100644
|
||||
--- a/src/cfgparse.c
|
||||
+++ b/src/cfgparse.c
|
||||
@@ -6998,6 +6998,29 @@ out_uri_auth_compat:
|
||||
newsrv = newsrv->next;
|
||||
}
|
||||
|
||||
+ /* check if we have a frontend with "tcp-request content" looking at L7
|
||||
+ * with no inspect-delay
|
||||
+ */
|
||||
+ if ((curproxy->cap & PR_CAP_FE) && !curproxy->tcp_req.inspect_delay) {
|
||||
+ list_for_each_entry(trule, &curproxy->tcp_req.inspect_rules, list) {
|
||||
+ if (trule->action == TCP_ACT_CAPTURE &&
|
||||
+ !(trule->act_prm.cap.expr->fetch->val & SMP_VAL_FE_SES_ACC))
|
||||
+ break;
|
||||
+ if ((trule->action >= TCP_ACT_TRK_SC0 && trule->action <= TCP_ACT_TRK_SCMAX) &&
|
||||
+ !(trule->act_prm.trk_ctr.expr->fetch->val & SMP_VAL_FE_SES_ACC))
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (&trule->list != &curproxy->tcp_req.inspect_rules) {
|
||||
+ Warning("config : %s '%s' : some 'tcp-request content' rules explicitly depending on request"
|
||||
+ " contents were found in a frontend without any 'tcp-request inspect-delay' setting."
|
||||
+ " This means that these rules will randomly find their contents. This can be fixed by"
|
||||
+ " setting the tcp-request inspect-delay.\n",
|
||||
+ proxy_type_str(curproxy), curproxy->id);
|
||||
+ err_code |= ERR_WARN;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (curproxy->cap & PR_CAP_FE) {
|
||||
if (!curproxy->accept)
|
||||
curproxy->accept = frontend_accept;
|
||||
--
|
||||
1.8.4.5
|
||||
|
@ -0,0 +1,90 @@
|
||||
From afbfc27c0f2cac29e18f87b36335ea821c633b9d Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Fri, 19 Sep 2014 15:42:30 +0200
|
||||
Subject: [PATCH 14/15] MEDIUM: systemd-wrapper: support multiple executable
|
||||
versions and names
|
||||
|
||||
Having to use a hard-coded "haproxy" executable name next to the systemd
|
||||
wrapper is not always convenient, as it's sometimes desirable to run with
|
||||
multiple versions in parallel.
|
||||
|
||||
Thus this patch performs a minor change to the wrapper : if the name ends
|
||||
with "-systemd-wrapper", then it trims that part off and what remains
|
||||
becomes the target haproxy executable. That makes it easy to have for
|
||||
example :
|
||||
|
||||
haproxy-1.5.4-systemd-wrapper haproxy-1.5.4
|
||||
haproxy-1.5.3-systemd-wrapper haproxy-1.5.3
|
||||
|
||||
and so on, in a same directory.
|
||||
|
||||
This patch also fixes a rare bug caused by readlink() not adding the
|
||||
trailing zero and leaving possible existing contents, including possibly
|
||||
a randomly placed "/" which would make it unable to locate the correct
|
||||
binary. This case is not totally unlikely as I got a \177 a few times
|
||||
at the end of the executable names, so I could have got a '/' as well.
|
||||
|
||||
Back-porting to 1.5 is desirable.
|
||||
(cherry picked from commit ceaf2aec1ec1612da461c61798e944693144bee9)
|
||||
---
|
||||
src/haproxy-systemd-wrapper.c | 27 ++++++++++++++++++++++-----
|
||||
1 file changed, 22 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/src/haproxy-systemd-wrapper.c b/src/haproxy-systemd-wrapper.c
|
||||
index cc8baa8..446f28f 100644
|
||||
--- a/src/haproxy-systemd-wrapper.c
|
||||
+++ b/src/haproxy-systemd-wrapper.c
|
||||
@@ -28,20 +28,36 @@ static char *pid_file = "/run/haproxy.pid";
|
||||
static int wrapper_argc;
|
||||
static char **wrapper_argv;
|
||||
|
||||
+/* returns the path to the haproxy binary into <buffer>, whose size indicated
|
||||
+ * in <buffer_size> must be at least 1 byte long.
|
||||
+ */
|
||||
static void locate_haproxy(char *buffer, size_t buffer_size)
|
||||
{
|
||||
char *end = NULL;
|
||||
+ int len;
|
||||
|
||||
- if (readlink("/proc/self/exe", buffer, buffer_size) > 0)
|
||||
- end = strrchr(buffer, '/');
|
||||
+ len = readlink("/proc/self/exe", buffer, buffer_size - 1);
|
||||
+ if (len == -1)
|
||||
+ goto fail;
|
||||
|
||||
- if (end == NULL) {
|
||||
- strncpy(buffer, "/usr/sbin/haproxy", buffer_size);
|
||||
+ buffer[len] = 0;
|
||||
+ end = strrchr(buffer, '/');
|
||||
+ if (end == NULL)
|
||||
+ goto fail;
|
||||
+
|
||||
+ if (strcmp(end + strlen(end) - 16, "-systemd-wrapper") == 0) {
|
||||
+ end[strlen(end) - 16] = '\0';
|
||||
return;
|
||||
}
|
||||
+
|
||||
end[1] = '\0';
|
||||
strncpy(end + 1, "haproxy", buffer + buffer_size - (end + 1));
|
||||
buffer[buffer_size - 1] = '\0';
|
||||
+ return;
|
||||
+ fail:
|
||||
+ strncpy(buffer, "/usr/sbin/haproxy", buffer_size);
|
||||
+ buffer[buffer_size - 1] = '\0';
|
||||
+ return;
|
||||
}
|
||||
|
||||
static void spawn_haproxy(char **pid_strv, int nb_pid)
|
||||
@@ -54,7 +70,8 @@ static void spawn_haproxy(char **pid_strv, int nb_pid)
|
||||
main_argc = wrapper_argc - 1;
|
||||
main_argv = wrapper_argv + 1;
|
||||
|
||||
- pid = fork();
|
||||
+ //pid = fork();
|
||||
+ pid=0;
|
||||
if (!pid) {
|
||||
/* 3 for "haproxy -Ds -sf" */
|
||||
char **argv = calloc(4 + main_argc + nb_pid + 1, sizeof(char *));
|
||||
--
|
||||
1.8.4.5
|
||||
|
@ -0,0 +1,36 @@
|
||||
From 575e299cc07f5f2b314d91dfac8671834cbdd2a7 Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Wed, 24 Sep 2014 12:59:25 +0200
|
||||
Subject: [PATCH 15/15] BUG/MEDIUM: remove debugging code from systemd-wrapper
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Kristoffer Grönlund reported that after my recent update to the
|
||||
systemd-wrapper, I accidentely left the debugging code which
|
||||
consists in disabling the fork :-(
|
||||
|
||||
The fix needs to be backported to 1.5 as well since I pushed it
|
||||
there as well.
|
||||
(cherry picked from commit a55bbc64d8272e4066a67b6d190ffebaff2b300a)
|
||||
---
|
||||
src/haproxy-systemd-wrapper.c | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/haproxy-systemd-wrapper.c b/src/haproxy-systemd-wrapper.c
|
||||
index 446f28f..8602881 100644
|
||||
--- a/src/haproxy-systemd-wrapper.c
|
||||
+++ b/src/haproxy-systemd-wrapper.c
|
||||
@@ -70,8 +70,7 @@ static void spawn_haproxy(char **pid_strv, int nb_pid)
|
||||
main_argc = wrapper_argc - 1;
|
||||
main_argv = wrapper_argv + 1;
|
||||
|
||||
- //pid = fork();
|
||||
- pid=0;
|
||||
+ pid = fork();
|
||||
if (!pid) {
|
||||
/* 3 for "haproxy -Ds -sf" */
|
||||
char **argv = calloc(4 + main_argc + nb_pid + 1, sizeof(char *));
|
||||
--
|
||||
1.8.4.5
|
||||
|
@ -1,7 +1,44 @@
|
||||
-------------------------------------------------------------------
|
||||
Thu Sep 25 16:10:08 UTC 2014 - kgronlund@suse.com
|
||||
|
||||
- Backported fixes (bnc#898498):
|
||||
- DOC: clearly state that the "show sess" output format is not fixed
|
||||
- MINOR: stats: fix minor typo fix in stats_dump_errors_to_buffer()
|
||||
- MEDIUM: Improve signal handling in systemd wrapper.
|
||||
- MINOR: Also accept SIGHUP/SIGTERM in systemd-wrapper
|
||||
- DOC: indicate in the doc that track-sc* can wait if data are missing
|
||||
- MEDIUM: http: enable header manipulation for 101 responses
|
||||
- BUG/MEDIUM: config: propagate frontend to backend process binding again.
|
||||
- MEDIUM: config: properly propagate process binding between proxies
|
||||
- MEDIUM: config: make the frontends automatically bind to the listeners' processes
|
||||
- MEDIUM: config: compute the exact bind-process before listener's maxaccept
|
||||
- MEDIUM: config: only warn if stats are attached to multi-process bind directives
|
||||
- MEDIUM: config: report it when tcp-request rules are misplaced
|
||||
- MINOR: config: detect the case where a tcp-request content rule has no inspect-delay
|
||||
- MEDIUM: systemd-wrapper: support multiple executable versions and names
|
||||
- BUG/MEDIUM: remove debugging code from systemd-wrapper
|
||||
|
||||
- Added patches:
|
||||
- 0001-DOC-clearly-state-that-the-show-sess-output-format-i.patch
|
||||
- 0002-MINOR-stats-fix-minor-typo-fix-in-stats_dump_errors_.patch
|
||||
- 0003-MEDIUM-Improve-signal-handling-in-systemd-wrapper.patch
|
||||
- 0004-MINOR-Also-accept-SIGHUP-SIGTERM-in-systemd-wrapper.patch
|
||||
- 0005-DOC-indicate-in-the-doc-that-track-sc-can-wait-if-da.patch
|
||||
- 0006-MEDIUM-http-enable-header-manipulation-for-101-respo.patch
|
||||
- 0007-BUG-MEDIUM-config-propagate-frontend-to-backend-proc.patch
|
||||
- 0008-MEDIUM-config-properly-propagate-process-binding-bet.patch
|
||||
- 0009-MEDIUM-config-make-the-frontends-automatically-bind-.patch
|
||||
- 0010-MEDIUM-config-compute-the-exact-bind-process-before-.patch
|
||||
- 0011-MEDIUM-config-only-warn-if-stats-are-attached-to-mul.patch
|
||||
- 0012-MEDIUM-config-report-it-when-tcp-request-rules-are-m.patch
|
||||
- 0013-MINOR-config-detect-the-case-where-a-tcp-request-con.patch
|
||||
- 0014-MEDIUM-systemd-wrapper-support-multiple-executable-v.patch
|
||||
- 0015-BUG-MEDIUM-remove-debugging-code-from-systemd-wrappe.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Sep 3 07:35:14 UTC 2014 - kgronlund@suse.com
|
||||
|
||||
- update to 1.5.4
|
||||
- update to 1.5.4 (bnc#895849 CVE-2014-6269)
|
||||
- BUG: config: error in http-response replace-header number of arguments
|
||||
- BUG/MINOR: Fix search for -p argument in systemd wrapper.
|
||||
- BUG/MEDIUM: auth: fix segfault with http-auth and a configuration with an unknown encryption algorithm
|
||||
|
45
haproxy.spec
45
haproxy.spec
@ -61,6 +61,36 @@ Patch1: haproxy-1.2.16_config_haproxy_user.patch
|
||||
Patch2: haproxy-makefile_lib.patch
|
||||
Patch3: sec-options.patch
|
||||
Patch4: haproxy-1.5_check_config_before_start.patch
|
||||
# PATCH-FIX-UPSTREAM: DOC: clearly state that the "show sess" output format is not fixed
|
||||
Patch5: 0001-DOC-clearly-state-that-the-show-sess-output-format-i.patch
|
||||
# PATCH-FIX-UPSTREAM: MINOR: stats: fix minor typo fix in stats_dump_errors_to_buffer()
|
||||
Patch6: 0002-MINOR-stats-fix-minor-typo-fix-in-stats_dump_errors_.patch
|
||||
# PATCH-FIX-UPSTREAM: MEDIUM: Improve signal handling in systemd wrapper.
|
||||
Patch7: 0003-MEDIUM-Improve-signal-handling-in-systemd-wrapper.patch
|
||||
# PATCH-FIX-UPSTREAM: MINOR: Also accept SIGHUP/SIGTERM in systemd-wrapper
|
||||
Patch8: 0004-MINOR-Also-accept-SIGHUP-SIGTERM-in-systemd-wrapper.patch
|
||||
# PATCH-FIX-UPSTREAM: DOC: indicate in the doc that track-sc* can wait if data are missing
|
||||
Patch9: 0005-DOC-indicate-in-the-doc-that-track-sc-can-wait-if-da.patch
|
||||
# PATCH-FIX-UPSTREAM: MEDIUM: http: enable header manipulation for 101 responses
|
||||
Patch10: 0006-MEDIUM-http-enable-header-manipulation-for-101-respo.patch
|
||||
# PATCH-FIX-UPSTREAM: BUG/MEDIUM: config: propagate frontend to backend process binding again.
|
||||
Patch11: 0007-BUG-MEDIUM-config-propagate-frontend-to-backend-proc.patch
|
||||
# PATCH-FIX-UPSTREAM: MEDIUM: config: properly propagate process binding between proxies
|
||||
Patch12: 0008-MEDIUM-config-properly-propagate-process-binding-bet.patch
|
||||
# PATCH-FIX-UPSTREAM: MEDIUM: config: make the frontends automatically bind to the listeners' processes
|
||||
Patch13: 0009-MEDIUM-config-make-the-frontends-automatically-bind-.patch
|
||||
# PATCH-FIX-UPSTREAM: MEDIUM: config: compute the exact bind-process before listener's maxaccept
|
||||
Patch14: 0010-MEDIUM-config-compute-the-exact-bind-process-before-.patch
|
||||
# PATCH-FIX-UPSTREAM: MEDIUM: config: only warn if stats are attached to multi-process bind directives
|
||||
Patch15: 0011-MEDIUM-config-only-warn-if-stats-are-attached-to-mul.patch
|
||||
# PATCH-FIX-UPSTREAM: MEDIUM: config: report it when tcp-request rules are misplaced
|
||||
Patch16: 0012-MEDIUM-config-report-it-when-tcp-request-rules-are-m.patch
|
||||
# PATCH-FIX-UPSTREAM: MINOR: config: detect the case where a tcp-request content rule has no inspect-delay
|
||||
Patch17: 0013-MINOR-config-detect-the-case-where-a-tcp-request-con.patch
|
||||
# PATCH-FIX-UPSTREAM: MEDIUM: systemd-wrapper: support multiple executable versions and names
|
||||
Patch18: 0014-MEDIUM-systemd-wrapper-support-multiple-executable-v.patch
|
||||
# PATCH-FIX-UPSTREAM: BUG/MEDIUM: remove debugging code from systemd-wrapper
|
||||
Patch19: 0015-BUG-MEDIUM-remove-debugging-code-from-systemd-wrappe.patch
|
||||
Source99: haproxy-rpmlintrc
|
||||
#
|
||||
Summary: The Reliable, High Performance TCP/HTTP Load Balancer
|
||||
@ -94,6 +124,21 @@ the most work done from every CPU cycle.
|
||||
%patch2
|
||||
%patch3
|
||||
%patch4 -p1
|
||||
%patch5 -p1
|
||||
%patch6 -p1
|
||||
%patch7 -p1
|
||||
%patch8 -p1
|
||||
%patch9 -p1
|
||||
%patch10 -p1
|
||||
%patch11 -p1
|
||||
%patch12 -p1
|
||||
%patch13 -p1
|
||||
%patch14 -p1
|
||||
%patch15 -p1
|
||||
%patch16 -p1
|
||||
%patch17 -p1
|
||||
%patch18 -p1
|
||||
%patch19 -p1
|
||||
|
||||
%build
|
||||
%{__make} \
|
||||
|
Loading…
Reference in New Issue
Block a user