]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: config: Support a range to specify processes in "cpu-map" parameter
authorChristopher Faulet <cfaulet@haproxy.com>
Wed, 22 Nov 2017 09:24:40 +0000 (10:24 +0100)
committerWilly Tarreau <w@1wt.eu>
Fri, 24 Nov 2017 14:38:49 +0000 (15:38 +0100)
Now, you can define processes concerned by a cpu-map line using a range. For
instance, the following line binds the first 32 processes on CPUs 0 to 3:

  cpu-map 1-32 0-3

doc/configuration.txt
src/cfgparse.c

index 4940b33e9104f4bab2803f01417ec48aebc5d300..8305515d905fcbf69b6b64b47810ce074bedc539 100644 (file)
@@ -657,20 +657,21 @@ chroot <jail dir>
   with superuser privileges. It is important to ensure that <jail_dir> is both
   empty and unwritable to anyone.
 
-cpu-map <"all"|"odd"|"even"|process_num> <cpu-set>...
+cpu-map <"all"|"odd"|"even"|process_num[-process_num]> <cpu-set>...
   On Linux 2.6 and above, it is possible to bind a process to a specific CPU
   set. This means that the process will never run on other CPUs. The "cpu-map"
   directive specifies CPU sets for process sets. The first argument is the
   process number to bind. This process must have a number between 1 and 32 or
   64, depending on the machine's word size, and any process IDs above nbproc
-  are ignored. It is possible to specify all processes at once using "all",
-  only odd numbers using "odd" or even numbers using "even", just like with the
-  "bind-process" directive. The second and forthcoming arguments are CPU sets.
-  Each CPU set is either a unique number between 0 and 31 or 63 or a range with
-  two such numbers delimited by a dash ('-'). Multiple CPU numbers or ranges
-  may be specified, and the processes will be allowed to bind to all of them.
-  Obviously, multiple "cpu-map" directives may be specified. Each "cpu-map"
-  directive will replace the previous ones when they overlap.
+  are ignored. It is possible to specify a range with two such number delimited
+  by a dash ('-'). It also is possible to specify all processes at once using
+  "all", only odd numbers using "odd" or even numbers using "even", just like
+  with the "bind-process" directive. The second and forthcoming arguments are
+  CPU sets.  Each CPU set is either a unique number between 0 and 31 or 63 or a
+  range with two such numbers delimited by a dash ('-'). Multiple CPU numbers
+  or ranges may be specified, and the processes will be allowed to bind to all
+  of them.  Obviously, multiple "cpu-map" directives may be specified. Each
+  "cpu-map" directive will replace the previous ones when they overlap.
 
 crt-base <dir>
   Assigns a default directory to fetch SSL certificates from when a relative
index bf8139ca0e087afa35e432a2a0a04484bb81c255..794148c94460a7e8c902315f1e46d9d8287f0845 100644 (file)
@@ -589,8 +589,9 @@ static int warnif_cond_conflicts(const struct acl_cond *cond, unsigned int where
 }
 
 /* Parse a string representing a process number or a set of processes. It must
- * be "all", "odd", "even" or a number between 1 and <LONGBITS>. It returns a
- * mask where bits are set for corresponding processes or 0 if an error occured.
+ * be "all", "odd", "even", a number between 1 and <LONGBITS> or a range with
+ * two such numbers delimited by a dash ('-'). It returns a mask where bits are
+ * set for corresponding processes or 0 if an error occured.
  *
  * Note: this function can also be used to parse a thread number or a set of
  * threads.
@@ -606,10 +607,29 @@ static unsigned long parse_process_number(const char *arg)
        else if (strcmp(arg, "even") == 0)
                proc = (~0UL/3UL) << 1; /* 0xAAA...AAA */
        else {
-               proc = atol(arg);
-               if (proc >= 1 && proc <= LONGBITS)
-                       proc = 1UL << (proc - 1);
+               char *dash;
+               unsigned int low, high;
+
+               if (!isdigit((int)*arg))
+                       goto end;
+
+               low = high = str2uic(arg);
+               if ((dash = strchr(arg, '-')) != NULL)
+                       high = str2uic(dash + 1);
+               if (high < low) {
+                       unsigned int swap = low;
+                       low  = high;
+                       high = swap;
+               }
+
+               if (low < 1 || low >= LONGBITS || high >= LONGBITS)
+                       goto end;
+
+               for (;low <= high; low++)
+                       proc |= 1UL << (low-1);
        }
+
+  end:
        return proc;
 }
 
@@ -1676,15 +1696,24 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
                unsigned long proc, cpus;
                int i;
 
-               proc = parse_process_number(args[1]);
-               if (!proc || !*args[2]) {
-                       Alert("parsing [%s:%d]: %s expects a process number "
-                             " ('all', 'odd', 'even', or a number from 1 to %d), "
+               if (!*args[1] || !*args[2]) {
+                       Alert("parsing [%s:%d] : %s expects a process number "
+                             " ('all', 'odd', 'even', a number from 1 to %d or a range), "
                              " followed by a list of CPU ranges with numbers from 0 to %d.\n",
                              file, linenum, args[0], LONGBITS, LONGBITS - 1);
                        err_code |= ERR_ALERT | ERR_FATAL;
                        goto out;
                }
+
+               proc = parse_process_number(args[1]);
+               if (!proc) {
+                       Alert("parsing [%s:%d] : %s : '%s' is not a valid PROC number "
+                             " ('all', 'odd', 'even', a number from 1 to %d or a range).\n",
+                             file, linenum, args[0], args[1], LONGBITS);
+                       err_code |= ERR_ALERT | ERR_FATAL;
+                       goto out;
+               }
+
                if (parse_cpu_set((const char **)args+2, &cpus, &errmsg)) {
                        Alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
                        err_code |= ERR_ALERT | ERR_FATAL;