mirror of
https://github.com/haproxy/haproxy.git
synced 2026-04-27 00:57:03 -04:00
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.
This commit is contained in:
parent
8a3478ed31
commit
64ab6077b7
1 changed files with 65 additions and 16 deletions
|
|
@ -5984,6 +5984,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
|
||||
|
|
@ -6257,11 +6315,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) {
|
||||
|
|
@ -6294,11 +6347,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6347,15 +6395,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);
|
||||
|
||||
|
|
@ -7265,6 +7308,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.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in a new issue