From 9fe3b9c7165afeedcf9f31959c436bcec233bb4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= Date: Tue, 14 Apr 2020 16:16:45 +0200 Subject: [PATCH] basic: use comma as separator in cpuset cgroup cpu ranges This is a workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1819152 and should be reverted in RHEL-8.3. RHEL-only Related: #1818054 --- src/basic/cpu-set-util.c | 45 ++++++++++++++++++++++++++++++++++++++++ src/basic/cpu-set-util.h | 1 + src/core/cgroup.c | 2 +- 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c index 36cb017ae7..51752ad1a6 100644 --- a/src/basic/cpu-set-util.c +++ b/src/basic/cpu-set-util.c @@ -86,6 +86,51 @@ char *cpu_set_to_range_string(const CPUSet *set) { return TAKE_PTR(str) ?: strdup(""); } +/* XXX(msekleta): this is the workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1819152, remove in 8.3 */ +char *cpu_set_to_range_string_kernel(const CPUSet *set) { + unsigned range_start = 0, range_end; + _cleanup_free_ char *str = NULL; + size_t allocated = 0, len = 0; + bool in_range = false; + int r; + + for (unsigned i = 0; i < set->allocated * 8; i++) + if (CPU_ISSET_S(i, set->allocated, set->set)) { + if (in_range) + range_end++; + else { + range_start = range_end = i; + in_range = true; + } + } else if (in_range) { + in_range = false; + + if (!GREEDY_REALLOC(str, allocated, len + 2 + 2 * DECIMAL_STR_MAX(unsigned))) + return NULL; + + if (range_end > range_start) + r = sprintf(str + len, len > 0 ? ",%d-%d" : "%d-%d", range_start, range_end); + else + r = sprintf(str + len, len > 0 ? ",%d" : "%d", range_start); + assert_se(r > 0); + len += r; + } + + if (in_range) { + if (!GREEDY_REALLOC(str, allocated, len + 2 + 2 * DECIMAL_STR_MAX(int))) + return NULL; + + if (range_end > range_start) + r = sprintf(str + len, len > 0 ? ",%d-%d" : "%d-%d", range_start, range_end); + else + r = sprintf(str + len, len > 0 ? ",%d" : "%d", range_start); + assert_se(r > 0); + } + + return TAKE_PTR(str) ?: strdup(""); +} + + int cpu_set_realloc(CPUSet *cpu_set, unsigned ncpus) { size_t need; diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h index 295028cb54..8519a9b6c8 100644 --- a/src/basic/cpu-set-util.h +++ b/src/basic/cpu-set-util.h @@ -27,6 +27,7 @@ int cpu_set_add_all(CPUSet *a, const CPUSet *b); char* cpu_set_to_string(const CPUSet *a); char *cpu_set_to_range_string(const CPUSet *a); +char *cpu_set_to_range_string_kernel(const CPUSet *a); int cpu_set_realloc(CPUSet *cpu_set, unsigned ncpus); int parse_cpu_set_full( diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 3f7665b755..9e4c3c7dac 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -557,7 +557,7 @@ static void cgroup_apply_unified_cpuset(Unit *u, CPUSet cpus, const char *name) _cleanup_free_ char *buf = NULL; int r; - buf = cpu_set_to_range_string(&cpus); + buf = cpu_set_to_range_string_kernel(&cpus); if (!buf) return;