mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-02-03 13:47:04 +03:00
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.
This commit is contained in:
parent
28cb17ef02
commit
a26662ce9b
@ -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,12 +87,16 @@ 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;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -1209,14 +1209,58 @@ static void test_parse_cpu_set(void) {
|
||||
|
||||
/* Ranges */
|
||||
ncpus = parse_cpu_set_and_warn("0-3,8-11", &c, NULL, "fake", 1, "CPUAffinity");
|
||||
assert_se(ncpus < 0);
|
||||
assert_se(!c);
|
||||
assert_se(ncpus >= 1024);
|
||||
assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
|
||||
for (cpu = 0; cpu < 4; cpu++)
|
||||
assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
|
||||
for (cpu = 8; cpu < 12; cpu++)
|
||||
assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
|
||||
c = mfree(c);
|
||||
|
||||
/* Ranges with trailing comma, space */
|
||||
ncpus = parse_cpu_set_and_warn("0-3 8-11, ", &c, NULL, "fake", 1, "CPUAffinity");
|
||||
assert_se(ncpus >= 1024);
|
||||
assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
|
||||
for (cpu = 0; cpu < 4; cpu++)
|
||||
assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
|
||||
for (cpu = 8; cpu < 12; cpu++)
|
||||
assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
|
||||
c = mfree(c);
|
||||
|
||||
/* Negative range (returns empty cpu_set) */
|
||||
ncpus = parse_cpu_set_and_warn("3-0", &c, NULL, "fake", 1, "CPUAffinity");
|
||||
assert_se(ncpus >= 1024);
|
||||
assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 0);
|
||||
c = mfree(c);
|
||||
|
||||
/* Overlapping ranges */
|
||||
ncpus = parse_cpu_set_and_warn("0-7 4-11", &c, NULL, "fake", 1, "CPUAffinity");
|
||||
assert_se(ncpus >= 1024);
|
||||
assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 12);
|
||||
for (cpu = 0; cpu < 12; cpu++)
|
||||
assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
|
||||
c = mfree(c);
|
||||
|
||||
/* Mix ranges and individual CPUs */
|
||||
ncpus = parse_cpu_set_and_warn("0,1 4-11", &c, NULL, "fake", 1, "CPUAffinity");
|
||||
assert_se(ncpus >= 1024);
|
||||
assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 10);
|
||||
assert_se(CPU_ISSET_S(0, CPU_ALLOC_SIZE(ncpus), c));
|
||||
assert_se(CPU_ISSET_S(1, CPU_ALLOC_SIZE(ncpus), c));
|
||||
for (cpu = 4; cpu < 12; cpu++)
|
||||
assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
|
||||
c = mfree(c);
|
||||
|
||||
/* Garbage */
|
||||
ncpus = parse_cpu_set_and_warn("0 1 2 3 garbage", &c, NULL, "fake", 1, "CPUAffinity");
|
||||
assert_se(ncpus < 0);
|
||||
assert_se(!c);
|
||||
|
||||
/* Range with garbage */
|
||||
ncpus = parse_cpu_set_and_warn("0-3 8-garbage", &c, NULL, "fake", 1, "CPUAffinity");
|
||||
assert_se(ncpus < 0);
|
||||
assert_se(!c);
|
||||
|
||||
/* Empty string */
|
||||
c = NULL;
|
||||
ncpus = parse_cpu_set_and_warn("", &c, NULL, "fake", 1, "CPUAffinity");
|
||||
|
Loading…
x
Reference in New Issue
Block a user