BUG/MEDIUM: peers/config: properly set the thread mask

The peers didn't have their bind_conf thread mask nor group set, because
they're still not part of the global proxy list. Till 2.6 it seems it does
not have any visible impact, since most listener-oriented operations pass
through thread_mask() which detects null masks and turns them to
all_threads_mask. But starting with 2.7 it becomes a problem as won't
permit these null masks anymore.

This patch duplicates (yes, sorry) the loop that applies to the frontend's
bind_conf, though it is simplified (no sharding, etc).

As the code is right now, it simply seems impossible to trigger the second
(and largest) part of the check when leaving thread_resolve_group_mask()
on success, so it looks like it might be removed.

No backport is needed, unless a report in 2.6 or earlier mentions an issue
with a null thread_mask.
This commit is contained in:
Willy Tarreau 2022-07-05 16:00:56 +02:00
parent 8d158132bd
commit d2494e0489

View File

@ -4079,9 +4079,38 @@ out_uri_auth_compat:
if (!LIST_ISEMPTY(&curpeers->peers_fe->conf.bind)) {
struct list *l;
struct bind_conf *bind_conf;
struct listener *li;
unsigned long mask;
l = &curpeers->peers_fe->conf.bind;
bind_conf = LIST_ELEM(l->n, typeof(bind_conf), by_fe);
err = NULL;
if (thread_resolve_group_mask(bind_conf->bind_tgroup, bind_conf->bind_thread,
&bind_conf->bind_tgroup, &bind_conf->bind_thread, &err) < 0) {
ha_alert("Peers section '%s': %s in 'bind %s' at [%s:%d].\n",
curpeers->peers_fe->id, err, bind_conf->arg, bind_conf->file, bind_conf->line);
free(err);
cfgerr++;
} else if (!((mask = bind_conf->bind_thread) & all_threads_mask)) {
unsigned long new_mask = 0;
while (mask) {
new_mask |= mask & all_threads_mask;
mask >>= global.nbthread;
}
bind_conf->bind_thread = new_mask;
ha_warning("Peers section '%s': the thread range specified on the 'thread' directive of 'bind %s' at [%s:%d] only refers to thread numbers out of the range defined by the global 'nbthread' directive. The thread numbers were remapped to existing threads instead (mask 0x%lx).\n",
curpeers->peers_fe->id, bind_conf->arg, bind_conf->file, bind_conf->line, new_mask);
}
/* apply thread masks and groups to all receivers */
list_for_each_entry(li, &bind_conf->listeners, by_bind) {
li->rx.bind_thread = bind_conf->bind_thread;
li->rx.bind_tgroup = bind_conf->bind_tgroup;
}
if (bind_conf->xprt->prepare_bind_conf &&
bind_conf->xprt->prepare_bind_conf(bind_conf) < 0)
cfgerr++;