From: Christopher Faulet Date: Wed, 22 Nov 2017 09:24:40 +0000 (+0100) Subject: MINOR: config: Support a range to specify processes in "cpu-map" parameter X-Git-Tag: v1.8.0~38 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1dcb9cb81c55366022e45de627bbdfc0154b2509;p=thirdparty%2Fhaproxy.git MINOR: config: Support a range to specify processes in "cpu-map" parameter 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 --- diff --git a/doc/configuration.txt b/doc/configuration.txt index 4940b33e91..8305515d90 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -657,20 +657,21 @@ chroot with superuser privileges. It is important to ensure that is both empty and unwritable to anyone. -cpu-map <"all"|"odd"|"even"|process_num> ... +cpu-map <"all"|"odd"|"even"|process_num[-process_num]> ... 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 Assigns a default directory to fetch SSL certificates from when a relative diff --git a/src/cfgparse.c b/src/cfgparse.c index bf8139ca0e..794148c944 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -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 . 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 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;