- haproxy 1.6 needs OPENSSL_WITH_DEPRECATED, OPENSSL_WITH_EC NPM ... - fix buildflags for lua, so its not build with the host compiler - fix duplication of defines Signed-off-by: heil <heil@terminal-consulting.de>lilik-openwrt-22.03
@ -0,0 +1,70 @@ | |||||
From 0a2117dc29147ed990732d1b2fc9779835820f3e Mon Sep 17 00:00:00 2001 | |||||
From: Willy Tarreau <w@1wt.eu> | |||||
Date: Thu, 3 Nov 2016 20:31:40 +0100 | |||||
Subject: [PATCH 27/31] BUG/MEDIUM: systemd-wrapper: return correct exit codes | |||||
Gabriele Cerami reported the the exit codes of the systemd-wrapper are | |||||
wrong. In short, it directly returns the output of the wait syscall's | |||||
status, which is a composite value made of error code an signal numbers. | |||||
In general it contains the signal number on the lower bits and the error | |||||
code on the higher bits, but exit() truncates it to the lowest 8 bits, | |||||
causing config validations to incorrectly report a success. Example : | |||||
$ ./haproxy-systemd-wrapper -c -f /dev/null | |||||
<7>haproxy-systemd-wrapper: executing /tmp/haproxy -c -f /dev/null -Ds | |||||
Configuration file has no error but will not start (no listener) => exit(2). | |||||
<5>haproxy-systemd-wrapper: exit, haproxy RC=512 | |||||
$ echo $? | |||||
0 | |||||
If the process is killed however, the signal number is directly reported | |||||
in the exit code. | |||||
Let's fix all this to ensure that the exit code matches what the shell does, | |||||
which means that codes 0..127 are for exit codes, codes 128..254 for signals, | |||||
and code 255 for unknown exit code. Now the return code is correct : | |||||
$ ./haproxy-systemd-wrapper -c -f /dev/null | |||||
<7>haproxy-systemd-wrapper: executing /tmp/haproxy -c -f /dev/null -Ds | |||||
Configuration file has no error but will not start (no listener) => exit(2). | |||||
<5>haproxy-systemd-wrapper: exit, haproxy RC=2 | |||||
$ echo $? | |||||
2 | |||||
$ ./haproxy-systemd-wrapper -f /tmp/cfg.conf | |||||
<7>haproxy-systemd-wrapper: executing /tmp/haproxy -f /dev/null -Ds | |||||
^C | |||||
<5>haproxy-systemd-wrapper: exit, haproxy RC=130 | |||||
$ echo $? | |||||
130 | |||||
This fix must be backported to 1.6 and 1.5. | |||||
(cherry picked from commit f7659cb10cb0420c7ca06fad1067207021d2a078) | |||||
--- | |||||
src/haproxy-systemd-wrapper.c | 10 ++++++++++ | |||||
1 file changed, 10 insertions(+) | |||||
diff --git a/src/haproxy-systemd-wrapper.c b/src/haproxy-systemd-wrapper.c | |||||
index b426f96..f6a9c85 100644 | |||||
--- a/src/haproxy-systemd-wrapper.c | |||||
+++ b/src/haproxy-systemd-wrapper.c | |||||
@@ -295,6 +295,16 @@ int main(int argc, char **argv) | |||||
} | |||||
} | |||||
+ /* return either exit code or signal+128 */ | |||||
+ if (WIFEXITED(status)) | |||||
+ status = WEXITSTATUS(status); | |||||
+ else if (WIFSIGNALED(status)) | |||||
+ status = 128 + WTERMSIG(status); | |||||
+ else if (WIFSTOPPED(status)) | |||||
+ status = 128 + WSTOPSIG(status); | |||||
+ else | |||||
+ status = 255; | |||||
+ | |||||
fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: exit, haproxy RC=%d\n", | |||||
status); | |||||
return status; | |||||
-- | |||||
2.7.3 | |||||
@ -0,0 +1,72 @@ | |||||
From 74ffd0cd0cecaeec3cfa848cbc03beb08999cc72 Mon Sep 17 00:00:00 2001 | |||||
From: Willy Tarreau <w@1wt.eu> | |||||
Date: Thu, 3 Nov 2016 18:19:49 +0100 | |||||
Subject: [PATCH 28/31] BUG/MEDIUM: srv-state: properly restore the DRAIN state | |||||
There were seveal reports about the DRAIN state not being properly | |||||
restored upon reload. | |||||
It happens that the condition in the code does exactly the opposite | |||||
of what the comment says, and the comment is right so the code is | |||||
wrong. | |||||
It's worth noting that the conditions are complex here due to the 2 | |||||
available methods to set the drain state (CLI/agent, and config's | |||||
weight). To paraphrase the updated comment in the code, there are | |||||
two possible reasons for FDRAIN to have been present : | |||||
- previous config weight was zero | |||||
- "set server b/s drain" was sent to the CLI | |||||
In the first case, we simply want to drop this drain state if the new | |||||
weight is not zero anymore, meaning the administrator has intentionally | |||||
turned the weight back to a positive value to enable the server again | |||||
after an operation. In the second case, the drain state was forced on | |||||
the CLI regardless of the config's weight so we don't want a change to | |||||
the config weight to lose this status. What this means is : | |||||
- if previous weight was 0 and new one is >0, drop the DRAIN state. | |||||
- if the previous weight was >0, keep it. | |||||
This fix must be backported to 1.6. | |||||
(cherry picked from commit 22cace2f4c3cbeca27c1941c647e7ae38ec8c0c0) | |||||
--- | |||||
src/server.c | 22 +++++++++++++++------- | |||||
1 file changed, 15 insertions(+), 7 deletions(-) | |||||
diff --git a/src/server.c b/src/server.c | |||||
index 79b3cb2..b9e72b7 100644 | |||||
--- a/src/server.c | |||||
+++ b/src/server.c | |||||
@@ -2093,15 +2093,23 @@ static void srv_update_state(struct server *srv, int version, char **params) | |||||
/* apply drain mode if server is currently enabled */ | |||||
if (!(srv->admin & SRV_ADMF_FMAINT) && (srv_admin_state & SRV_ADMF_FDRAIN)) { | |||||
/* The SRV_ADMF_FDRAIN flag is inherited when srv->iweight is 0 | |||||
- * (srv->iweight is the weight set up in configuration) | |||||
- * so we don't want to apply it when srv_iweight is 0 and | |||||
- * srv->iweight is greater than 0. Purpose is to give the | |||||
- * chance to the admin to re-enable this server from configuration | |||||
- * file by setting a new weight > 0. | |||||
+ * (srv->iweight is the weight set up in configuration). | |||||
+ * There are two possible reasons for FDRAIN to have been present : | |||||
+ * - previous config weight was zero | |||||
+ * - "set server b/s drain" was sent to the CLI | |||||
+ * | |||||
+ * In the first case, we simply want to drop this drain state | |||||
+ * if the new weight is not zero anymore, meaning the administrator | |||||
+ * has intentionally turned the weight back to a positive value to | |||||
+ * enable the server again after an operation. In the second case, | |||||
+ * the drain state was forced on the CLI regardless of the config's | |||||
+ * weight so we don't want a change to the config weight to lose this | |||||
+ * status. What this means is : | |||||
+ * - if previous weight was 0 and new one is >0, drop the DRAIN state. | |||||
+ * - if the previous weight was >0, keep it. | |||||
*/ | |||||
- if ((srv_iweight == 0) && (srv->iweight > 0)) { | |||||
+ if (srv_iweight > 0 || srv->iweight == 0) | |||||
srv_adm_set_drain(srv); | |||||
- } | |||||
} | |||||
srv->last_change = date.tv_sec - srv_last_time_change; | |||||
-- | |||||
2.7.3 | |||||
@ -0,0 +1,33 @@ | |||||
From d6649c499b8ca4fb0bf93153c2a149c78e8a76f8 Mon Sep 17 00:00:00 2001 | |||||
From: Willy Tarreau <w@1wt.eu> | |||||
Date: Thu, 3 Nov 2016 18:33:25 +0100 | |||||
Subject: [PATCH 29/31] BUG/MINOR: srv-state: allow to have both CMAINT and | |||||
FDRAIN flags | |||||
CMAINT indicates that the server was *initially* disabled in the | |||||
configuration via the "disabled" keyword. FDRAIN indicates that the | |||||
server was switched to the DRAIN state from the CLI or the agent. | |||||
This it's perfectly valid to have both of them in the state file, | |||||
so the parser must not reject this combination. | |||||
This fix must be backported to 1.6. | |||||
(cherry picked from commit e1bde1492a30f5036ca58248e50c27a9e116d9cc) | |||||
--- | |||||
src/server.c | 1 + | |||||
1 file changed, 1 insertion(+) | |||||
diff --git a/src/server.c b/src/server.c | |||||
index b9e72b7..b0c7bbe 100644 | |||||
--- a/src/server.c | |||||
+++ b/src/server.c | |||||
@@ -1961,6 +1961,7 @@ static void srv_update_state(struct server *srv, int version, char **params) | |||||
srv_admin_state != SRV_ADMF_IMAINT && | |||||
srv_admin_state != SRV_ADMF_CMAINT && | |||||
srv_admin_state != (SRV_ADMF_CMAINT | SRV_ADMF_FMAINT) && | |||||
+ srv_admin_state != (SRV_ADMF_CMAINT | SRV_ADMF_FDRAIN) && | |||||
srv_admin_state != SRV_ADMF_FDRAIN && | |||||
srv_admin_state != SRV_ADMF_IDRAIN)) { | |||||
chunk_appendf(msg, ", invalid srv_admin_state value '%s'", params[2]); | |||||
-- | |||||
2.7.3 | |||||
@ -0,0 +1,172 @@ | |||||
From c449c9835e7d9e02cf0aeafc482364d5090db543 Mon Sep 17 00:00:00 2001 | |||||
From: Willy Tarreau <w@1wt.eu> | |||||
Date: Thu, 3 Nov 2016 19:22:19 +0100 | |||||
Subject: [PATCH 30/31] BUG/MEDIUM: servers: properly propagate the maintenance | |||||
states during startup | |||||
Right now there is an issue with the way the maintenance flags are | |||||
propagated upon startup. They are not propagate, just copied from the | |||||
tracked server. This implies that depending on the server's order, some | |||||
tracking servers may not be marked down. For example this configuration | |||||
does not work as expected : | |||||
server s1 1.1.1.1:8000 track s2 | |||||
server s2 1.1.1.1:8000 track s3 | |||||
server s3 1.1.1.1:8000 track s4 | |||||
server s4 wtap:8000 check inter 1s disabled | |||||
It results in s1/s2 being up, and s3/s4 being down, while all of them | |||||
should be down. | |||||
The only clean way to process this is to run through all "root" servers | |||||
(those not tracking any other server), and to propagate their state down | |||||
to all their trackers. This is the same algorithm used to propagate the | |||||
state changes. It has to be done both to compute the IDRAIN flag and the | |||||
IMAINT flag. However, doing so requires that tracking servers are not | |||||
marked as inherited maintenance anymore while parsing the configuration | |||||
(and given that it is wrong, better drop it). | |||||
This fix also addresses another side effect of the bug above which is | |||||
that the IDRAIN/IMAINT flags are stored in the state files, and if | |||||
restored while the tracked server doesn't have the equivalent flag, | |||||
the servers may end up in a situation where it's impossible to remove | |||||
these flags. For example in the configuration above, after removing | |||||
"disabled" on server s4, the other servers would have remained down, | |||||
and not anymore with this fix. Similarly, the combination of IMAINT | |||||
or IDRAIN with their respective forced modes was not accepted on | |||||
reload, which is wrong as well. | |||||
This bug has been present at least since 1.5, maybe even 1.4 (it came | |||||
with tracking support). The fix needs to be backported there, though | |||||
the srv-state parts are irrelevant. | |||||
This commit relies on previous patch to silence warnings on startup. | |||||
(cherry picked from commit 757478e900ebc1e67c1fe060b9b561d276cab3e1) | |||||
--- | |||||
include/proto/server.h | 1 + | |||||
src/cfgparse.c | 7 ------- | |||||
src/haproxy.c | 4 ++++ | |||||
src/server.c | 42 +++++++++++++++++++++++++++++++++++++++--- | |||||
4 files changed, 44 insertions(+), 10 deletions(-) | |||||
diff --git a/include/proto/server.h b/include/proto/server.h | |||||
index d75cc9f..b6572ba 100644 | |||||
--- a/include/proto/server.h | |||||
+++ b/include/proto/server.h | |||||
@@ -44,6 +44,7 @@ struct server *server_find_by_id(struct proxy *bk, int id); | |||||
struct server *server_find_by_name(struct proxy *bk, const char *name); | |||||
struct server *server_find_best_match(struct proxy *bk, char *name, int id, int *diff); | |||||
void apply_server_state(void); | |||||
+void srv_compute_all_admin_states(struct proxy *px); | |||||
/* functions related to server name resolution */ | |||||
int snr_update_srv_status(struct server *s); | |||||
diff --git a/src/cfgparse.c b/src/cfgparse.c | |||||
index b8289a2..365b283 100644 | |||||
--- a/src/cfgparse.c | |||||
+++ b/src/cfgparse.c | |||||
@@ -8275,13 +8275,6 @@ out_uri_auth_compat: | |||||
goto next_srv; | |||||
} | |||||
- /* if the other server is forced disabled, we have to do the same here */ | |||||
- if (srv->admin & SRV_ADMF_MAINT) { | |||||
- newsrv->admin |= SRV_ADMF_IMAINT; | |||||
- newsrv->state = SRV_ST_STOPPED; | |||||
- newsrv->check.health = 0; | |||||
- } | |||||
- | |||||
newsrv->track = srv; | |||||
newsrv->tracknext = srv->trackers; | |||||
srv->trackers = newsrv; | |||||
diff --git a/src/haproxy.c b/src/haproxy.c | |||||
index 2d476f2..1699132 100644 | |||||
--- a/src/haproxy.c | |||||
+++ b/src/haproxy.c | |||||
@@ -566,6 +566,7 @@ void init(int argc, char **argv) | |||||
struct wordlist *wl; | |||||
char *progname; | |||||
char *change_dir = NULL; | |||||
+ struct proxy *px; | |||||
chunk_init(&trash, malloc(global.tune.bufsize), global.tune.bufsize); | |||||
alloc_trash_buffers(global.tune.bufsize); | |||||
@@ -852,6 +853,9 @@ void init(int argc, char **argv) | |||||
/* Apply server states */ | |||||
apply_server_state(); | |||||
+ for (px = proxy; px; px = px->next) | |||||
+ srv_compute_all_admin_states(px); | |||||
+ | |||||
global_listener_queue_task = task_new(); | |||||
if (!global_listener_queue_task) { | |||||
Alert("Out of memory when initializing global task\n"); | |||||
diff --git a/src/server.c b/src/server.c | |||||
index b0c7bbe..f2923ae 100644 | |||||
--- a/src/server.c | |||||
+++ b/src/server.c | |||||
@@ -705,6 +705,40 @@ void srv_clr_admin_flag(struct server *s, enum srv_admin mode) | |||||
srv_clr_admin_flag(srv, mode); | |||||
} | |||||
+/* principle: propagate maint and drain to tracking servers. This is useful | |||||
+ * upon startup so that inherited states are correct. | |||||
+ */ | |||||
+static void srv_propagate_admin_state(struct server *srv) | |||||
+{ | |||||
+ struct server *srv2; | |||||
+ | |||||
+ if (!srv->trackers) | |||||
+ return; | |||||
+ | |||||
+ for (srv2 = srv->trackers; srv2; srv2 = srv2->tracknext) { | |||||
+ if (srv->admin & (SRV_ADMF_MAINT | SRV_ADMF_CMAINT)) | |||||
+ srv_set_admin_flag(srv2, SRV_ADMF_IMAINT); | |||||
+ | |||||
+ if (srv->admin & SRV_ADMF_DRAIN) | |||||
+ srv_set_admin_flag(srv2, SRV_ADMF_IDRAIN); | |||||
+ } | |||||
+} | |||||
+ | |||||
+/* Compute and propagate the admin states for all servers in proxy <px>. | |||||
+ * Only servers *not* tracking another one are considered, because other | |||||
+ * ones will be handled when the server they track is visited. | |||||
+ */ | |||||
+void srv_compute_all_admin_states(struct proxy *px) | |||||
+{ | |||||
+ struct server *srv; | |||||
+ | |||||
+ for (srv = px->srv; srv; srv = srv->next) { | |||||
+ if (srv->track) | |||||
+ continue; | |||||
+ srv_propagate_admin_state(srv); | |||||
+ } | |||||
+} | |||||
+ | |||||
/* Note: must not be declared <const> as its list will be overwritten. | |||||
* Please take care of keeping this list alphabetically sorted, doing so helps | |||||
* all code contributors. | |||||
@@ -1955,15 +1989,17 @@ static void srv_update_state(struct server *srv, int version, char **params) | |||||
p = NULL; | |||||
errno = 0; | |||||
srv_admin_state = strtol(params[2], &p, 10); | |||||
+ | |||||
+ /* inherited statuses will be recomputed later */ | |||||
+ srv_admin_state &= ~SRV_ADMF_IDRAIN & ~SRV_ADMF_IMAINT; | |||||
+ | |||||
if ((p == params[2]) || errno == EINVAL || errno == ERANGE || | |||||
(srv_admin_state != 0 && | |||||
srv_admin_state != SRV_ADMF_FMAINT && | |||||
- srv_admin_state != SRV_ADMF_IMAINT && | |||||
srv_admin_state != SRV_ADMF_CMAINT && | |||||
srv_admin_state != (SRV_ADMF_CMAINT | SRV_ADMF_FMAINT) && | |||||
srv_admin_state != (SRV_ADMF_CMAINT | SRV_ADMF_FDRAIN) && | |||||
- srv_admin_state != SRV_ADMF_FDRAIN && | |||||
- srv_admin_state != SRV_ADMF_IDRAIN)) { | |||||
+ srv_admin_state != SRV_ADMF_FDRAIN)) { | |||||
chunk_appendf(msg, ", invalid srv_admin_state value '%s'", params[2]); | |||||
} | |||||
-- | |||||
2.7.3 | |||||
@ -0,0 +1,37 @@ | |||||
From 9c017e541bb3cee2e2884cdc53a4cb4627be5dad Mon Sep 17 00:00:00 2001 | |||||
From: Christopher Faulet <cfaulet@haproxy.com> | |||||
Date: Wed, 9 Nov 2016 16:15:32 +0100 | |||||
Subject: [PATCH 31/31] BUG: vars: Fix 'set-var' converter because of a typo | |||||
The 'set-var' converter uses function smp_conv_store (vars.c). In this function, | |||||
we should use the first argument (index 0) to retrieve the variable name and its | |||||
scope. But because of a typo, we get the scope of the second argument (index | |||||
1). In this case, there is no second argument. So the scope used was always 0 | |||||
(SCOPE_SESS), always setting the variable in the session scope. | |||||
So, due to this bug, this rules | |||||
tcp-request content accept if { src,set-var(txn.foo) -m found } | |||||
always set the variable 'sess.foo' instead of 'txn.foo'. | |||||
(cherry picked from commit 0099a8ca9d58cb4cff943bf6374b55b42a23fbfb) | |||||
--- | |||||
src/vars.c | 2 +- | |||||
1 file changed, 1 insertion(+), 1 deletion(-) | |||||
diff --git a/src/vars.c b/src/vars.c | |||||
index a3dd85c..8645905 100644 | |||||
--- a/src/vars.c | |||||
+++ b/src/vars.c | |||||
@@ -379,7 +379,7 @@ static inline int sample_store_stream(const char *name, enum vars_scope scope, s | |||||
/* Returns 0 if fails, else returns 1. */ | |||||
static int smp_conv_store(const struct arg *args, struct sample *smp, void *private) | |||||
{ | |||||
- return sample_store_stream(args[0].data.var.name, args[1].data.var.scope, smp); | |||||
+ return sample_store_stream(args[0].data.var.name, args[0].data.var.scope, smp); | |||||
} | |||||
/* This fucntions check an argument entry and fill it with a variable | |||||
-- | |||||
2.7.3 | |||||