forked from pool/haproxy
aeb20f101c
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
143 lines
4.5 KiB
Diff
143 lines
4.5 KiB
Diff
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
|
|
|