]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: peers/config: properly set the thread mask
authorWilly Tarreau <w@1wt.eu>
Tue, 5 Jul 2022 14:00:56 +0000 (16:00 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 5 Jul 2022 17:10:26 +0000 (19:10 +0200)
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.

src/cfgparse.c

index a98ebd58d57a78e76bb235528c8cf90b34323ce9..0c12ec6e22732607a81e9e95608af39cf0dd3513 100644 (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++;