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