|
|
- 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/13] 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.5.5
-
|