- [PATCH 15/20] BUG/MEDIUM: remove debugging code from systemd-wrapper - [PATCH 16/20] BUG/MEDIUM: http: adjust close mode when switching to - [PATCH 17/20] BUG/MINOR: config: don't propagate process binding on - [PATCH 18/20] BUG/MEDIUM: check: rule-less tcp-check must detect - [PATCH 19/20] BUG/MINOR: tcp-check: report the correct failed step in - [PATCH 20/20] BUG/MINOR: config: don't propagate process binding for Signed-off-by: Thomas Heil <heil@terminal-consulting.de>lilik-openwrt-22.03
@ -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/20] 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 *)); | |||
-- | |||
2.0.4 | |||
@ -0,0 +1,188 @@ | |||
From 2e47a3ab11188239abadb6bba7bd901d764aa4fb Mon Sep 17 00:00:00 2001 | |||
From: Willy Tarreau <w@1wt.eu> | |||
Date: Tue, 30 Sep 2014 18:44:22 +0200 | |||
Subject: [PATCH 16/20] BUG/MEDIUM: http: adjust close mode when switching to | |||
backend | |||
Commit 179085c ("MEDIUM: http: move Connection header processing earlier") | |||
introduced a regression : the backend's HTTP mode is not considered anymore | |||
when setting the session's HTTP mode, because wait_for_request() is only | |||
called once, when the frontend receives the request (or when the frontend | |||
is in TCP mode, when the backend receives the request). | |||
The net effect is that in some situations when the frontend and the backend | |||
do not work in the same mode (eg: keep-alive vs close), the backend's mode | |||
is ignored. | |||
This patch moves all that processing to a dedicated function, which is | |||
called from the original place, as well as from session_set_backend() | |||
when switching from an HTTP frontend to an HTTP backend in different | |||
modes. | |||
This fix must be backported to 1.5. | |||
(cherry picked from commit 4e21ff9244aefa56bcf0793a9e07edba2c3c1960) | |||
--- | |||
include/proto/proto_http.h | 1 + | |||
src/proto_http.c | 107 +++++++++++++++++++++++---------------------- | |||
src/proxy.c | 8 ++++ | |||
3 files changed, 64 insertions(+), 52 deletions(-) | |||
diff --git a/include/proto/proto_http.h b/include/proto/proto_http.h | |||
index e898ca8..8014310 100644 | |||
--- a/include/proto/proto_http.h | |||
+++ b/include/proto/proto_http.h | |||
@@ -112,6 +112,7 @@ unsigned int http_get_hdr(const struct http_msg *msg, const char *hname, int hle | |||
void http_init_txn(struct session *s); | |||
void http_end_txn(struct session *s); | |||
void http_reset_txn(struct session *s); | |||
+void http_adjust_conn_mode(struct session *s, struct http_txn *txn, struct http_msg *msg); | |||
struct http_req_rule *parse_http_req_cond(const char **args, const char *file, int linenum, struct proxy *proxy); | |||
struct http_res_rule *parse_http_res_cond(const char **args, const char *file, int linenum, struct proxy *proxy); | |||
diff --git a/src/proto_http.c b/src/proto_http.c | |||
index 7e35c8b..20e7088 100644 | |||
--- a/src/proto_http.c | |||
+++ b/src/proto_http.c | |||
@@ -2393,6 +2393,59 @@ fail: | |||
return 0; | |||
} | |||
+void http_adjust_conn_mode(struct session *s, struct http_txn *txn, struct http_msg *msg) | |||
+{ | |||
+ int tmp = TX_CON_WANT_KAL; | |||
+ | |||
+ if (!((s->fe->options2|s->be->options2) & PR_O2_FAKE_KA)) { | |||
+ if ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_TUN || | |||
+ (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_TUN) | |||
+ tmp = TX_CON_WANT_TUN; | |||
+ | |||
+ if ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL || | |||
+ (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL) | |||
+ tmp = TX_CON_WANT_TUN; | |||
+ } | |||
+ | |||
+ if ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_SCL || | |||
+ (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_SCL) { | |||
+ /* option httpclose + server_close => forceclose */ | |||
+ if ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL || | |||
+ (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL) | |||
+ tmp = TX_CON_WANT_CLO; | |||
+ else | |||
+ tmp = TX_CON_WANT_SCL; | |||
+ } | |||
+ | |||
+ if ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_FCL || | |||
+ (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_FCL) | |||
+ tmp = TX_CON_WANT_CLO; | |||
+ | |||
+ if ((txn->flags & TX_CON_WANT_MSK) < tmp) | |||
+ txn->flags = (txn->flags & ~TX_CON_WANT_MSK) | tmp; | |||
+ | |||
+ if (!(txn->flags & TX_HDR_CONN_PRS) && | |||
+ (txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_TUN) { | |||
+ /* parse the Connection header and possibly clean it */ | |||
+ int to_del = 0; | |||
+ if ((msg->flags & HTTP_MSGF_VER_11) || | |||
+ ((txn->flags & TX_CON_WANT_MSK) >= TX_CON_WANT_SCL && | |||
+ !((s->fe->options2|s->be->options2) & PR_O2_FAKE_KA))) | |||
+ to_del |= 2; /* remove "keep-alive" */ | |||
+ if (!(msg->flags & HTTP_MSGF_VER_11)) | |||
+ to_del |= 1; /* remove "close" */ | |||
+ http_parse_connection_header(txn, msg, to_del); | |||
+ } | |||
+ | |||
+ /* check if client or config asks for explicit close in KAL/SCL */ | |||
+ if (((txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_KAL || | |||
+ (txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_SCL) && | |||
+ ((txn->flags & TX_HDR_CONN_CLO) || /* "connection: close" */ | |||
+ (!(msg->flags & HTTP_MSGF_VER_11) && !(txn->flags & TX_HDR_CONN_KAL)) || /* no "connection: k-a" in 1.0 */ | |||
+ !(msg->flags & HTTP_MSGF_XFER_LEN) || /* no length known => close */ | |||
+ s->fe->state == PR_STSTOPPED)) /* frontend is stopping */ | |||
+ txn->flags = (txn->flags & ~TX_CON_WANT_MSK) | TX_CON_WANT_CLO; | |||
+} | |||
/* This stream analyser waits for a complete HTTP request. It returns 1 if the | |||
* processing can continue on next analysers, or zero if it either needs more | |||
@@ -2929,58 +2982,8 @@ int http_wait_for_request(struct session *s, struct channel *req, int an_bit) | |||
* time. | |||
*/ | |||
if (!(txn->flags & TX_HDR_CONN_PRS) || | |||
- ((s->fe->options & PR_O_HTTP_MODE) != (s->be->options & PR_O_HTTP_MODE))) { | |||
- int tmp = TX_CON_WANT_KAL; | |||
- | |||
- if (!((s->fe->options2|s->be->options2) & PR_O2_FAKE_KA)) { | |||
- if ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_TUN || | |||
- (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_TUN) | |||
- tmp = TX_CON_WANT_TUN; | |||
- | |||
- if ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL || | |||
- (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL) | |||
- tmp = TX_CON_WANT_TUN; | |||
- } | |||
- | |||
- if ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_SCL || | |||
- (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_SCL) { | |||
- /* option httpclose + server_close => forceclose */ | |||
- if ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL || | |||
- (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL) | |||
- tmp = TX_CON_WANT_CLO; | |||
- else | |||
- tmp = TX_CON_WANT_SCL; | |||
- } | |||
- | |||
- if ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_FCL || | |||
- (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_FCL) | |||
- tmp = TX_CON_WANT_CLO; | |||
- | |||
- if ((txn->flags & TX_CON_WANT_MSK) < tmp) | |||
- txn->flags = (txn->flags & ~TX_CON_WANT_MSK) | tmp; | |||
- | |||
- if (!(txn->flags & TX_HDR_CONN_PRS) && | |||
- (txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_TUN) { | |||
- /* parse the Connection header and possibly clean it */ | |||
- int to_del = 0; | |||
- if ((msg->flags & HTTP_MSGF_VER_11) || | |||
- ((txn->flags & TX_CON_WANT_MSK) >= TX_CON_WANT_SCL && | |||
- !((s->fe->options2|s->be->options2) & PR_O2_FAKE_KA))) | |||
- to_del |= 2; /* remove "keep-alive" */ | |||
- if (!(msg->flags & HTTP_MSGF_VER_11)) | |||
- to_del |= 1; /* remove "close" */ | |||
- http_parse_connection_header(txn, msg, to_del); | |||
- } | |||
- | |||
- /* check if client or config asks for explicit close in KAL/SCL */ | |||
- if (((txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_KAL || | |||
- (txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_SCL) && | |||
- ((txn->flags & TX_HDR_CONN_CLO) || /* "connection: close" */ | |||
- (!(msg->flags & HTTP_MSGF_VER_11) && !(txn->flags & TX_HDR_CONN_KAL)) || /* no "connection: k-a" in 1.0 */ | |||
- !(msg->flags & HTTP_MSGF_XFER_LEN) || /* no length known => close */ | |||
- s->fe->state == PR_STSTOPPED)) /* frontend is stopping */ | |||
- txn->flags = (txn->flags & ~TX_CON_WANT_MSK) | TX_CON_WANT_CLO; | |||
- } | |||
+ ((s->fe->options & PR_O_HTTP_MODE) != (s->be->options & PR_O_HTTP_MODE))) | |||
+ http_adjust_conn_mode(s, txn, msg); | |||
/* end of job, return OK */ | |||
req->analysers &= ~an_bit; | |||
diff --git a/src/proxy.c b/src/proxy.c | |||
index 02103ee..405c4c4 100644 | |||
--- a/src/proxy.c | |||
+++ b/src/proxy.c | |||
@@ -955,6 +955,14 @@ int session_set_backend(struct session *s, struct proxy *be) | |||
http_init_txn(s); | |||
} | |||
+ /* If we chain to an HTTP backend running a different HTTP mode, we | |||
+ * have to re-adjust the desired keep-alive/close mode to accommodate | |||
+ * both the frontend's and the backend's modes. | |||
+ */ | |||
+ if (s->fe->mode == PR_MODE_HTTP && be->mode == PR_MODE_HTTP && | |||
+ ((s->fe->options & PR_O_HTTP_MODE) != (be->options & PR_O_HTTP_MODE))) | |||
+ http_adjust_conn_mode(s, &s->txn, &s->txn.req); | |||
+ | |||
/* If an LB algorithm needs to access some pre-parsed body contents, | |||
* we must not start to forward anything until the connection is | |||
* confirmed otherwise we'll lose the pointer to these data and | |||
-- | |||
2.0.4 | |||
@ -0,0 +1,46 @@ | |||
From b3228c83e320ad168f5b3e6884e771530a68a449 Mon Sep 17 00:00:00 2001 | |||
From: Willy Tarreau <w@1wt.eu> | |||
Date: Wed, 1 Oct 2014 20:50:17 +0200 | |||
Subject: [PATCH 17/20] BUG/MINOR: config: don't propagate process binding on | |||
fatal errors. | |||
propagate_processes() must not be called with unresolved proxies, but | |||
nothing prevents it from being called in check_config_validity(). The | |||
resulting effect is that an unresolved proxy can cause a recursion | |||
loop if called in such a situation, ending with a segfault after the | |||
fatal error report. There's no side effect beyond this. | |||
This patch refrains from calling the function when any error was met. | |||
This bug also affects 1.5, it should be backported. | |||
(cherry picked from commit acbe8ab38a638a076f8cf9fe2635db0e729d6a1f) | |||
--- | |||
src/cfgparse.c | 12 ++++++++---- | |||
1 file changed, 8 insertions(+), 4 deletions(-) | |||
diff --git a/src/cfgparse.c b/src/cfgparse.c | |||
index f723a3a..6e962c8 100644 | |||
--- a/src/cfgparse.c | |||
+++ b/src/cfgparse.c | |||
@@ -7112,10 +7112,14 @@ out_uri_auth_compat: | |||
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); | |||
+ /* propagate bindings from frontends to backends. Don't do it if there | |||
+ * are any fatal errors as we must not call it with unresolved proxies. | |||
+ */ | |||
+ if (!cfgerr) { | |||
+ 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. */ | |||
-- | |||
2.0.4 | |||
@ -0,0 +1,102 @@ | |||
From e61737a721c3b91c79484e51fc1789293b269f9f Mon Sep 17 00:00:00 2001 | |||
From: Willy Tarreau <w@1wt.eu> | |||
Date: Thu, 2 Oct 2014 14:30:14 +0200 | |||
Subject: [PATCH 18/20] BUG/MEDIUM: check: rule-less tcp-check must detect | |||
connect failures | |||
When "option tcp-check" is specified without any tcp-check rules, the | |||
documentation says that it's the same as the default check method. But | |||
the code path is a bit different, and we used to consider that since | |||
the end of rules was reached, the check is always successful regardless | |||
of the connection status. | |||
This patch reorganizes the error detection, and considers the special | |||
case where there's no tcp-check rule as a real L4 check. It also avoids | |||
dereferencing the rule list head as a rule by itself. | |||
While fixing this bug, another one related to the output messages' | |||
accuracy was noticed, it will be fixed in a separate commit and is | |||
much less important. | |||
This bug is also present in 1.5, so this fix must be backported. | |||
(cherry picked from commit ef953953e7f33c6a72c432fce8d47c2d84c69512) | |||
--- | |||
src/checks.c | 40 +++++++++++++++++++++++++--------------- | |||
1 file changed, 25 insertions(+), 15 deletions(-) | |||
diff --git a/src/checks.c b/src/checks.c | |||
index f3b2b54..9c1a866 100644 | |||
--- a/src/checks.c | |||
+++ b/src/checks.c | |||
@@ -1837,20 +1837,34 @@ static int tcpcheck_get_step_id(struct server *s) | |||
static void tcpcheck_main(struct connection *conn) | |||
{ | |||
char *contentptr; | |||
- struct list *head = NULL; | |||
struct tcpcheck_rule *cur = NULL; | |||
int done = 0, ret = 0; | |||
- | |||
struct check *check = conn->owner; | |||
struct server *s = check->server; | |||
struct task *t = check->task; | |||
+ struct list *head = &s->proxy->tcpcheck_rules; | |||
- /* | |||
- * don't do anything until the connection is established but if we're running | |||
- * first step which must be a connect | |||
+ /* here, we know that the check is complete or that it failed */ | |||
+ if (check->result != CHK_RES_UNKNOWN) | |||
+ goto out_end_tcpcheck; | |||
+ | |||
+ /* We have 4 possibilities here : | |||
+ * 1. we've not yet attempted step 1, and step 1 is a connect, so no | |||
+ * connection attempt was made yet ; | |||
+ * 2. we've not yet attempted step 1, and step 1 is a not connect or | |||
+ * does not exist (no rule), so a connection attempt was made | |||
+ * before coming here. | |||
+ * 3. we're coming back after having started with step 1, so we may | |||
+ * be waiting for a connection attempt to complete. | |||
+ * 4. the connection + handshake are complete | |||
+ * | |||
+ * #2 and #3 are quite similar, we want both the connection and the | |||
+ * handshake to complete before going any further. Thus we must always | |||
+ * wait for a connection to complete unless we're before and existing | |||
+ * step 1. | |||
*/ | |||
- if (check->current_step && (!(conn->flags & CO_FL_CONNECTED))) { | |||
- /* update expire time, should be done by process_chk */ | |||
+ if ((!(conn->flags & CO_FL_CONNECTED) || (conn->flags & CO_FL_HANDSHAKE)) && | |||
+ (check->current_step || LIST_ISEMPTY(head))) { | |||
/* we allow up to min(inter, timeout.connect) for a connection | |||
* to establish but only when timeout.check is set | |||
* as it may be to short for a full check otherwise | |||
@@ -1867,12 +1881,11 @@ static void tcpcheck_main(struct connection *conn) | |||
return; | |||
} | |||
- /* here, we know that the connection is established */ | |||
- if (check->result != CHK_RES_UNKNOWN) | |||
+ /* special case: option tcp-check with no rule, a connect is enough */ | |||
+ if (LIST_ISEMPTY(head)) { | |||
+ set_server_check_status(check, HCHK_STATUS_L4OK, NULL); | |||
goto out_end_tcpcheck; | |||
- | |||
- /* head is be the first element of the double chained list */ | |||
- head = &s->proxy->tcpcheck_rules; | |||
+ } | |||
/* no step means first step | |||
* initialisation */ | |||
@@ -1891,9 +1904,6 @@ static void tcpcheck_main(struct connection *conn) | |||
cur = check->current_step; | |||
} | |||
- if (conn->flags & CO_FL_HANDSHAKE) | |||
- return; | |||
- | |||
/* It's only the rules which will enable send/recv */ | |||
__conn_data_stop_both(conn); | |||
-- | |||
2.0.4 | |||
@ -0,0 +1,111 @@ | |||
From 90055f28a7a0c86cfb37ccb23a548a1da7229551 Mon Sep 17 00:00:00 2001 | |||
From: Willy Tarreau <w@1wt.eu> | |||
Date: Thu, 2 Oct 2014 14:51:02 +0200 | |||
Subject: [PATCH 19/20] BUG/MINOR: tcp-check: report the correct failed step in | |||
the status | |||
The step number was reported by checking only last_started_step, which | |||
was not set in case of error during the initial connection phase, and | |||
caused "step 1" to be returned with an invalid check type (typically | |||
SEND). So now we first verify that a test was started before returning | |||
this. | |||
In addition to this, the indication of the test type was taken from | |||
current_step instead of last_started_step, so the error description | |||
was matching the next action instead of the one reported in the step | |||
ID. Thus we could get the confusing "step 1 (send)" report below : | |||
tcp-check connect | |||
tcp-check send foo | |||
In order to ease debugging, when the port number is known for a connect, | |||
it is indicated in the error report. | |||
Note that this only affects asynchronous error messages, synchronous ones | |||
are correct. | |||
This fix must be backported to 1.5. | |||
(cherry picked from commit 213c6785614d0228d7e96e982e5189e1d0777059) | |||
--- | |||
src/checks.c | 43 ++++++++++++++++++++++++++++--------------- | |||
1 file changed, 28 insertions(+), 15 deletions(-) | |||
diff --git a/src/checks.c b/src/checks.c | |||
index 9c1a866..5318f35 100644 | |||
--- a/src/checks.c | |||
+++ b/src/checks.c | |||
@@ -580,6 +580,7 @@ static void chk_report_conn_err(struct connection *conn, int errno_bck, int expi | |||
struct check *check = conn->owner; | |||
const char *err_msg; | |||
struct chunk *chk; | |||
+ int step; | |||
if (check->result != CHK_RES_UNKNOWN) | |||
return; | |||
@@ -599,19 +600,27 @@ static void chk_report_conn_err(struct connection *conn, int errno_bck, int expi | |||
chk = get_trash_chunk(); | |||
if (check->type == PR_O2_TCPCHK_CHK) { | |||
- chunk_printf(chk, " at step %d of tcp-check", tcpcheck_get_step_id(check->server)); | |||
- /* we were looking for a string */ | |||
- if (check->current_step && check->current_step->action == TCPCHK_ACT_CONNECT) { | |||
- chunk_appendf(chk, " (connect)"); | |||
- } | |||
- else if (check->current_step && check->current_step->action == TCPCHK_ACT_EXPECT) { | |||
- if (check->current_step->string) | |||
- chunk_appendf(chk, " (string '%s')", check->current_step->string); | |||
- else if (check->current_step->expect_regex) | |||
- chunk_appendf(chk, " (expect regex)"); | |||
- } | |||
- else if (check->current_step && check->current_step->action == TCPCHK_ACT_SEND) { | |||
- chunk_appendf(chk, " (send)"); | |||
+ step = tcpcheck_get_step_id(check->server); | |||
+ if (!step) | |||
+ chunk_printf(chk, " at initial connection step of tcp-check"); | |||
+ else { | |||
+ chunk_printf(chk, " at step %d of tcp-check", step); | |||
+ /* we were looking for a string */ | |||
+ if (check->last_started_step && check->last_started_step->action == TCPCHK_ACT_CONNECT) { | |||
+ if (check->last_started_step->port) | |||
+ chunk_appendf(chk, " (connect port %d)" ,check->last_started_step->port); | |||
+ else | |||
+ chunk_appendf(chk, " (connect)"); | |||
+ } | |||
+ else if (check->last_started_step && check->last_started_step->action == TCPCHK_ACT_EXPECT) { | |||
+ if (check->last_started_step->string) | |||
+ chunk_appendf(chk, " (string '%s')", check->last_started_step->string); | |||
+ else if (check->last_started_step->expect_regex) | |||
+ chunk_appendf(chk, " (expect regex)"); | |||
+ } | |||
+ else if (check->last_started_step && check->last_started_step->action == TCPCHK_ACT_SEND) { | |||
+ chunk_appendf(chk, " (send)"); | |||
+ } | |||
} | |||
} | |||
@@ -1818,6 +1827,10 @@ static int tcpcheck_get_step_id(struct server *s) | |||
struct tcpcheck_rule *cur = NULL, *next = NULL; | |||
int i = 0; | |||
+ /* not even started anything yet => step 0 = initial connect */ | |||
+ if (!s->check.current_step) | |||
+ return 0; | |||
+ | |||
cur = s->check.last_started_step; | |||
/* no step => first step */ | |||
@@ -1887,9 +1900,9 @@ static void tcpcheck_main(struct connection *conn) | |||
goto out_end_tcpcheck; | |||
} | |||
- /* no step means first step | |||
- * initialisation */ | |||
+ /* no step means first step initialisation */ | |||
if (check->current_step == NULL) { | |||
+ check->last_started_step = NULL; | |||
check->bo->p = check->bo->data; | |||
check->bo->o = 0; | |||
check->bi->p = check->bi->data; | |||
-- | |||
2.0.4 | |||
@ -0,0 +1,34 @@ | |||
From c8d57dec6173430bd5602bb76efff302c51e7803 Mon Sep 17 00:00:00 2001 | |||
From: =?UTF-8?q?Cyril=20Bont=C3=A9?= <cyril.bonte@free.fr> | |||
Date: Thu, 2 Oct 2014 19:56:25 +0200 | |||
Subject: [PATCH 20/20] BUG/MINOR: config: don't propagate process binding for | |||
dynamic use_backend | |||
A segfault was reported with the introduction of the propagate_processes() | |||
function. It was caused when a use_backend rule was declared with a dynamic | |||
name, using a log-format string. The backend is not resolved during the | |||
configuration, which lead to the segfault. | |||
The patch prevents the process binding propagation for such dynamic rules, it | |||
should also be backported to 1.5. | |||
(cherry picked from commit 51639696e0a112ea3612e905a5722ad912b3869f) | |||
--- | |||
src/cfgparse.c | 2 ++ | |||
1 file changed, 2 insertions(+) | |||
diff --git a/src/cfgparse.c b/src/cfgparse.c | |||
index 6e962c8..ec6d923 100644 | |||
--- a/src/cfgparse.c | |||
+++ b/src/cfgparse.c | |||
@@ -6015,6 +6015,8 @@ void propagate_processes(struct proxy *from, struct proxy *to) | |||
/* use_backend */ | |||
list_for_each_entry(rule, &from->switching_rules, list) { | |||
+ if (rule->dynamic) | |||
+ continue; | |||
to = rule->be.backend; | |||
propagate_processes(from, to); | |||
} | |||
-- | |||
2.0.4 | |||