From: Willy Tarreau Date: Tue, 5 Jul 2022 14:00:56 +0000 (+0200) Subject: BUG/MEDIUM: peers/config: properly set the thread mask X-Git-Tag: v2.7-dev2~97 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d2494e0489e831cf939ef7624ae0c37fd177e868;p=thirdparty%2Fhaproxy.git 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. --- diff --git a/src/cfgparse.c b/src/cfgparse.c index a98ebd58d5..0c12ec6e22 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -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++;