]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: listeners: support the definition of thread groups on bind lines
authorWilly Tarreau <w@1wt.eu>
Wed, 29 Sep 2021 16:50:31 +0000 (18:50 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 8 Oct 2021 15:22:26 +0000 (17:22 +0200)
This extends the "thread" statement of bind lines to support an optional
thread group number. When unspecified (0) it's an absolute thread range,
and when specified it's one relative to the thread group. Masks are still
used so no more than 64 threads may be specified at once, and a single
group is possible. The directive is not used for now.

doc/configuration.txt
include/haproxy/receiver-t.h
src/listener.c

index 830aee9e65e6ffdcad40cf116e6237337432aebd..d4ce56657c3fabd190f73815d2670240b077d85b 100644 (file)
@@ -14123,12 +14123,24 @@ tfo
   need to build HAProxy with USE_TFO=1 if your libc doesn't define
   TCP_FASTOPEN.
 
-thread <thread-set>
+thread [<thread-group>/]<thread-set>
   This restricts the list of threads on which this listener is allowed to run.
   It does not enforce any of them but eliminates those which do not match. It
   limits the threads allowed to process incoming connections for this listener.
+
+  There are two numbering schemes. By default, thread numbers are absolute in
+  the process, comprised between 1 and the value specified in global.nbthread.
+  When thread groups are enabled, the number of a single desired thread group
+  (starting at 1) may be specified before a slash ('/') before the thread
+  range. In this case, the thread numbers in the range are relative to the
+  thread group instead, and start at 1 for each thread group. Absolute and
+  relative thread numbers may be used interchangeably but they must not be
+  mixed on a single "bind" line, as those not set will be resolved at the end
+  of the parsing.
+
   For the unlikely case where several ranges are needed, this directive may be
-  repeated. <thread-set> must use the format:
+  repeated. It is not permitted to use different thread groups even when using
+  multiple directives. The <thread-set> specification must use the format:
 
       all | odd | even | number[-[number]]
 
index d8f2422d938e8f91114524a2fb4db3fa4cf881fe..9f14af3d33300fb214fbb3dca07c67ed461ec2ee 100644 (file)
@@ -42,6 +42,7 @@
 /* All the settings that are used to configure a receiver */
 struct rx_settings {
        unsigned long bind_thread;        /* bitmask of threads allowed to use these listeners */
+       uint bind_tgroup;                 /* thread group ID: 0=global IDs, non-zero=local IDs */
        struct {                          /* UNIX socket permissions */
                uid_t uid;                /* -1 to leave unchanged */
                gid_t gid;                /* -1 to leave unchanged */
index a1e9edc1a1e78262ef562dd2e671dba28ff42406..b89aa986f33014b02cf9d1cfa6077cb38dad7bf7 100644 (file)
@@ -1593,24 +1593,38 @@ static int bind_parse_proto(char **args, int cur_arg, struct proxy *px, struct b
 /* parse the "thread" bind keyword */
 static int bind_parse_thread(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
 {
-       char *slash;
-       unsigned long thread = 0;
-
-       if ((slash = strchr(args[cur_arg + 1], '/')) != NULL)
-               *slash = 0;
+       char *sep = NULL;
+       ulong thread = 0;
+       long tgroup = 0;
+
+       tgroup = strtol(args[cur_arg + 1], &sep, 10);
+       if (*sep == '/') {
+               /* a thread group was present */
+               if (tgroup < 1 || tgroup > MAX_TGROUPS) {
+                       memprintf(err, "'%s' thread-group number must be between 1 and %d (was %ld)", args[cur_arg + 1], MAX_TGROUPS, tgroup);
+                       return ERR_ALERT | ERR_FATAL;
+               }
+               sep++;
+       }
+       else {
+               /* no thread group */
+               tgroup = 0;
+               sep = args[cur_arg + 1];
+       }
 
-       if (slash) {
-               *slash = '/';
-               memprintf(err, "'%s': thread groups not supported", args[cur_arg+1]);
+       if ((conf->settings.bind_tgroup || conf->settings.bind_thread) &&
+           conf->settings.bind_tgroup != tgroup) {
+               memprintf(err, "'%s' multiple thread-groups are not supported", args[cur_arg + 1]);
                return ERR_ALERT | ERR_FATAL;
        }
-
-       if (parse_process_number(args[cur_arg+1], &thread, MAX_THREADS, NULL, err)) {
-               memprintf(err, "'%s' : %s", args[cur_arg+1], *err);
+       
+       if (parse_process_number(sep, &thread, MAX_THREADS, NULL, err)) {
+               memprintf(err, "'%s' : %s", sep, *err);
                return ERR_ALERT | ERR_FATAL;
        }
 
        conf->settings.bind_thread |= thread;
+       conf->settings.bind_tgroup  = tgroup;
        return 0;
 }