summaryrefslogtreecommitdiff
path: root/src/basic/cpu-set-util.c
diff options
context:
space:
mode:
authorFilipe Brandenburger <filbranden@google.com>2015-09-25 05:23:23 -0700
committerFilipe Brandenburger <filbranden@google.com>2015-10-27 17:56:26 -0700
commita26662ce9b25c400ead61854ed7be636f186fdb0 (patch)
treef1441b826920f40ad03b738634208705741f28d6 /src/basic/cpu-set-util.c
parent28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4 (diff)
cpu-set-util: Support ranges in parse_cpu_set_and_warn
Tested CPUAffinity ranges on both a service unit and in system.conf and confirmed they work as expected (by inspecting /proc/PID/status, for the main pid of the service and for pid 1). Also mixed ranges with both spaces, commas, trailing commas and spaces. Added new tests to increase coverage of ranges and prevent regressions.
Diffstat (limited to 'src/basic/cpu-set-util.c')
-rw-r--r--src/basic/cpu-set-util.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c
index 441144d5cc..4950c66767 100644
--- a/src/basic/cpu-set-util.c
+++ b/src/basic/cpu-set-util.c
@@ -72,14 +72,12 @@ int parse_cpu_set_and_warn(
for (;;) {
_cleanup_free_ char *word = NULL;
- unsigned cpu;
+ unsigned cpu, cpu_lower, cpu_upper;
int r;
r = extract_first_word(&rvalue, &word, WHITESPACE ",", EXTRACT_QUOTES);
- if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Invalid value for %s: %s", lvalue, whole_rvalue);
- return r;
- }
+ if (r < 0)
+ return log_syntax(unit, LOG_ERR, filename, line, r, "Invalid value for %s: %s", lvalue, whole_rvalue);
if (r == 0)
break;
@@ -89,13 +87,17 @@ int parse_cpu_set_and_warn(
return log_oom();
}
- r = safe_atou(word, &cpu);
- if (r < 0 || cpu >= ncpus) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse CPU affinity '%s'", rvalue);
- return -EINVAL;
- }
-
- CPU_SET_S(cpu, CPU_ALLOC_SIZE(ncpus), c);
+ r = parse_range(word, &cpu_lower, &cpu_upper);
+ if (r < 0)
+ return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse CPU affinity '%s'", word);
+ if (cpu_lower >= ncpus || cpu_upper >= ncpus)
+ return log_syntax(unit, LOG_ERR, filename, line, EINVAL, "CPU out of range '%s' ncpus is %u", word, ncpus);
+
+ if (cpu_lower > cpu_upper)
+ log_syntax(unit, LOG_WARNING, filename, line, 0, "Range '%s' is invalid, %u > %u", word, cpu_lower, cpu_upper);
+ else
+ for (cpu = cpu_lower; cpu <= cpu_upper; cpu++)
+ CPU_SET_S(cpu, CPU_ALLOC_SIZE(ncpus), c);
}
/* On success, sets *cpu_set and returns ncpus for the system. */