846 lines
43 KiB
Diff
846 lines
43 KiB
Diff
|
|
From 2ea8175b3d8ec118fa0f42392485ce0f4308456a Mon Sep 17 00:00:00 2001
|
||
|
|
From: licunlong <licunlong1@huawei.com>
|
||
|
|
Date: Thu, 6 May 2021 09:38:54 +0800
|
||
|
|
Subject: [PATCH] core-cgroup: support cpuset
|
||
|
|
|
||
|
|
This patch add support for cpuset subsystem.
|
||
|
|
---
|
||
|
|
src/basic/cgroup-util.c | 3 +-
|
||
|
|
src/basic/cgroup-util.h | 10 +-
|
||
|
|
src/basic/string-util.c | 42 +++++++
|
||
|
|
src/basic/string-util.h | 1 +
|
||
|
|
src/core/cgroup.c | 112 ++++++++++++++----
|
||
|
|
src/core/cgroup.h | 14 ++-
|
||
|
|
src/core/dbus-cgroup.c | 60 ++++++++--
|
||
|
|
src/core/dbus-manager.c | 1 +
|
||
|
|
src/core/load-fragment-gperf.gperf.in | 13 +-
|
||
|
|
src/core/load-fragment.c | 69 +++++++++++
|
||
|
|
src/core/load-fragment.h | 1 +
|
||
|
|
src/core/main.c | 4 +
|
||
|
|
src/core/manager.c | 1 +
|
||
|
|
src/core/manager.h | 1 +
|
||
|
|
src/core/system.conf.in | 1 +
|
||
|
|
src/core/unit.c | 1 +
|
||
|
|
src/shared/bus-unit-util.c | 15 ++-
|
||
|
|
src/shared/cpu-set-util.c | 1 +
|
||
|
|
src/test/test-cgroup-mask.c | 5 +-
|
||
|
|
.../fuzz-unit-file/directives-all.service | 5 +
|
||
|
|
20 files changed, 309 insertions(+), 51 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c
|
||
|
|
index feda596..1bb07f7 100644
|
||
|
|
--- a/src/basic/cgroup-util.c
|
||
|
|
+++ b/src/basic/cgroup-util.c
|
||
|
|
@@ -2248,12 +2248,13 @@ bool fd_is_cgroup_fs(int fd) {
|
||
|
|
static const char *const cgroup_controller_table[_CGROUP_CONTROLLER_MAX] = {
|
||
|
|
[CGROUP_CONTROLLER_CPU] = "cpu",
|
||
|
|
[CGROUP_CONTROLLER_CPUACCT] = "cpuacct",
|
||
|
|
- [CGROUP_CONTROLLER_CPUSET] = "cpuset",
|
||
|
|
+ [CGROUP_CONTROLLER_CPUSET2] = "cpuset2",
|
||
|
|
[CGROUP_CONTROLLER_IO] = "io",
|
||
|
|
[CGROUP_CONTROLLER_BLKIO] = "blkio",
|
||
|
|
[CGROUP_CONTROLLER_MEMORY] = "memory",
|
||
|
|
[CGROUP_CONTROLLER_DEVICES] = "devices",
|
||
|
|
[CGROUP_CONTROLLER_PIDS] = "pids",
|
||
|
|
+ [CGROUP_CONTROLLER_CPUSET] = "cpuset",
|
||
|
|
[CGROUP_CONTROLLER_BPF_FIREWALL] = "bpf-firewall",
|
||
|
|
[CGROUP_CONTROLLER_BPF_DEVICES] = "bpf-devices",
|
||
|
|
[CGROUP_CONTROLLER_BPF_FOREIGN] = "bpf-foreign",
|
||
|
|
diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h
|
||
|
|
index b69f168..764d47a 100644
|
||
|
|
--- a/src/basic/cgroup-util.h
|
||
|
|
+++ b/src/basic/cgroup-util.h
|
||
|
|
@@ -21,12 +21,13 @@ typedef enum CGroupController {
|
||
|
|
/* Original cgroup controllers */
|
||
|
|
CGROUP_CONTROLLER_CPU,
|
||
|
|
CGROUP_CONTROLLER_CPUACCT, /* v1 only */
|
||
|
|
- CGROUP_CONTROLLER_CPUSET, /* v2 only */
|
||
|
|
+ CGROUP_CONTROLLER_CPUSET2, /* v2 only */
|
||
|
|
CGROUP_CONTROLLER_IO, /* v2 only */
|
||
|
|
CGROUP_CONTROLLER_BLKIO, /* v1 only */
|
||
|
|
CGROUP_CONTROLLER_MEMORY,
|
||
|
|
CGROUP_CONTROLLER_DEVICES, /* v1 only */
|
||
|
|
CGROUP_CONTROLLER_PIDS,
|
||
|
|
+ CGROUP_CONTROLLER_CPUSET,
|
||
|
|
|
||
|
|
/* BPF-based pseudo-controllers, v2 only */
|
||
|
|
CGROUP_CONTROLLER_BPF_FIREWALL,
|
||
|
|
@@ -48,12 +49,13 @@ typedef enum CGroupController {
|
||
|
|
typedef enum CGroupMask {
|
||
|
|
CGROUP_MASK_CPU = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_CPU),
|
||
|
|
CGROUP_MASK_CPUACCT = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_CPUACCT),
|
||
|
|
- CGROUP_MASK_CPUSET = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_CPUSET),
|
||
|
|
+ CGROUP_MASK_CPUSET2 = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_CPUSET2),
|
||
|
|
CGROUP_MASK_IO = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_IO),
|
||
|
|
CGROUP_MASK_BLKIO = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_BLKIO),
|
||
|
|
CGROUP_MASK_MEMORY = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_MEMORY),
|
||
|
|
CGROUP_MASK_DEVICES = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_DEVICES),
|
||
|
|
CGROUP_MASK_PIDS = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_PIDS),
|
||
|
|
+ CGROUP_MASK_CPUSET = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_CPUSET),
|
||
|
|
CGROUP_MASK_BPF_FIREWALL = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_BPF_FIREWALL),
|
||
|
|
CGROUP_MASK_BPF_DEVICES = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_BPF_DEVICES),
|
||
|
|
CGROUP_MASK_BPF_FOREIGN = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_BPF_FOREIGN),
|
||
|
|
@@ -61,10 +63,10 @@ typedef enum CGroupMask {
|
||
|
|
CGROUP_MASK_BPF_RESTRICT_NETWORK_INTERFACES = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_BPF_RESTRICT_NETWORK_INTERFACES),
|
||
|
|
|
||
|
|
/* All real cgroup v1 controllers */
|
||
|
|
- CGROUP_MASK_V1 = CGROUP_MASK_CPU|CGROUP_MASK_CPUACCT|CGROUP_MASK_BLKIO|CGROUP_MASK_MEMORY|CGROUP_MASK_DEVICES|CGROUP_MASK_PIDS,
|
||
|
|
+ CGROUP_MASK_V1 = CGROUP_MASK_CPU|CGROUP_MASK_CPUACCT|CGROUP_MASK_BLKIO|CGROUP_MASK_MEMORY|CGROUP_MASK_CPUSET|CGROUP_MASK_DEVICES|CGROUP_MASK_PIDS,
|
||
|
|
|
||
|
|
/* All real cgroup v2 controllers */
|
||
|
|
- CGROUP_MASK_V2 = CGROUP_MASK_CPU|CGROUP_MASK_CPUSET|CGROUP_MASK_IO|CGROUP_MASK_MEMORY|CGROUP_MASK_PIDS,
|
||
|
|
+ CGROUP_MASK_V2 = CGROUP_MASK_CPU|CGROUP_MASK_CPUSET2|CGROUP_MASK_IO|CGROUP_MASK_MEMORY|CGROUP_MASK_PIDS,
|
||
|
|
|
||
|
|
/* All cgroup v2 BPF pseudo-controllers */
|
||
|
|
CGROUP_MASK_BPF = CGROUP_MASK_BPF_FIREWALL|CGROUP_MASK_BPF_DEVICES|CGROUP_MASK_BPF_FOREIGN|CGROUP_MASK_BPF_SOCKET_BIND|CGROUP_MASK_BPF_RESTRICT_NETWORK_INTERFACES,
|
||
|
|
diff --git a/src/basic/string-util.c b/src/basic/string-util.c
|
||
|
|
index ad8c986..755ad11 100644
|
||
|
|
--- a/src/basic/string-util.c
|
||
|
|
+++ b/src/basic/string-util.c
|
||
|
|
@@ -1159,6 +1159,48 @@ int string_contains_word_strv(const char *string, const char *separators, char *
|
||
|
|
return !!found;
|
||
|
|
}
|
||
|
|
|
||
|
|
+int string_isvalid_interval(const char *instr)
|
||
|
|
+{
|
||
|
|
+ const char *pstr = instr; /* tmp */
|
||
|
|
+ const char *pstr_front = instr; /* front char */
|
||
|
|
+ const char *pstr_behind = instr; /* behind char */
|
||
|
|
+
|
||
|
|
+ if (isempty(instr))
|
||
|
|
+ {
|
||
|
|
+ return 1;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ while (*pstr != '\0')
|
||
|
|
+ {
|
||
|
|
+ /* behind */
|
||
|
|
+ pstr_behind = pstr + 1;
|
||
|
|
+
|
||
|
|
+ /* 0-3,4,6,7-10 */
|
||
|
|
+ if (((*pstr < '0') || (*pstr > '9')) &&
|
||
|
|
+ (*pstr != '-') &&
|
||
|
|
+ (*pstr != ','))
|
||
|
|
+ {
|
||
|
|
+ return 2;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ /* - , must is a num */
|
||
|
|
+ if (('-' == *pstr) || (',' == *pstr))
|
||
|
|
+ {
|
||
|
|
+ if ((*pstr_front < '0') || (*pstr_front > '9') ||
|
||
|
|
+ (*pstr_behind < '0') || (*pstr_behind > '9'))
|
||
|
|
+ {
|
||
|
|
+ return 3;
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ /* front */
|
||
|
|
+ pstr_front = pstr;
|
||
|
|
+ pstr++;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return 0;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
bool streq_skip_trailing_chars(const char *s1, const char *s2, const char *ok) {
|
||
|
|
if (!s1 && !s2)
|
||
|
|
return true;
|
||
|
|
diff --git a/src/basic/string-util.h b/src/basic/string-util.h
|
||
|
|
index e0a47a2..b025c06 100644
|
||
|
|
--- a/src/basic/string-util.h
|
||
|
|
+++ b/src/basic/string-util.h
|
||
|
|
@@ -235,6 +235,7 @@ static inline int string_contains_word(const char *string, const char *separator
|
||
|
|
return string_contains_word_strv(string, separators, STRV_MAKE(word), NULL);
|
||
|
|
}
|
||
|
|
|
||
|
|
+int string_isvalid_interval(const char *instr);
|
||
|
|
bool streq_skip_trailing_chars(const char *s1, const char *s2, const char *ok);
|
||
|
|
|
||
|
|
char *string_replace_char(char *str, char old_char, char new_char);
|
||
|
|
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
|
||
|
|
index f6ae2ab..a6396e1 100644
|
||
|
|
--- a/src/core/cgroup.c
|
||
|
|
+++ b/src/core/cgroup.c
|
||
|
|
@@ -90,8 +90,8 @@ bool unit_has_startup_cgroup_constraints(Unit *u) {
|
||
|
|
return c->startup_cpu_shares != CGROUP_CPU_SHARES_INVALID ||
|
||
|
|
c->startup_io_weight != CGROUP_WEIGHT_INVALID ||
|
||
|
|
c->startup_blockio_weight != CGROUP_BLKIO_WEIGHT_INVALID ||
|
||
|
|
- c->startup_cpuset_cpus.set ||
|
||
|
|
- c->startup_cpuset_mems.set;
|
||
|
|
+ c->startup_cpuset_cpus2.set ||
|
||
|
|
+ c->startup_cpuset_mems2.set;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool unit_has_host_root_cgroup(Unit *u) {
|
||
|
|
@@ -277,10 +277,16 @@ void cgroup_context_done(CGroupContext *c) {
|
||
|
|
|
||
|
|
c->restrict_network_interfaces = set_free(c->restrict_network_interfaces);
|
||
|
|
|
||
|
|
- cpu_set_reset(&c->cpuset_cpus);
|
||
|
|
- cpu_set_reset(&c->startup_cpuset_cpus);
|
||
|
|
- cpu_set_reset(&c->cpuset_mems);
|
||
|
|
- cpu_set_reset(&c->startup_cpuset_mems);
|
||
|
|
+ if (c->cpuset_cpus)
|
||
|
|
+ c->cpuset_cpus = mfree(c->cpuset_cpus);
|
||
|
|
+
|
||
|
|
+ if (c->cpuset_mems)
|
||
|
|
+ c->cpuset_mems = mfree(c->cpuset_mems);
|
||
|
|
+
|
||
|
|
+ cpu_set_reset(&c->cpuset_cpus2);
|
||
|
|
+ cpu_set_reset(&c->startup_cpuset_cpus2);
|
||
|
|
+ cpu_set_reset(&c->cpuset_mems2);
|
||
|
|
+ cpu_set_reset(&c->startup_cpuset_mems2);
|
||
|
|
}
|
||
|
|
|
||
|
|
static int unit_get_kernel_memory_limit(Unit *u, const char *file, uint64_t *ret) {
|
||
|
|
@@ -415,7 +421,7 @@ static char *format_cgroup_memory_limit_comparison(char *buf, size_t l, Unit *u,
|
||
|
|
}
|
||
|
|
|
||
|
|
void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
|
||
|
|
- _cleanup_free_ char *disable_controllers_str = NULL, *cpuset_cpus = NULL, *cpuset_mems = NULL, *startup_cpuset_cpus = NULL, *startup_cpuset_mems = NULL;
|
||
|
|
+ _cleanup_free_ char *disable_controllers_str = NULL, *cpuset_cpus2 = NULL, *cpuset_mems2 = NULL, *startup_cpuset_cpus2 = NULL, *startup_cpuset_mems2 = NULL;
|
||
|
|
CGroupContext *c;
|
||
|
|
struct in_addr_prefix *iaai;
|
||
|
|
|
||
|
|
@@ -434,16 +440,17 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
|
||
|
|
|
||
|
|
(void) cg_mask_to_string(c->disable_controllers, &disable_controllers_str);
|
||
|
|
|
||
|
|
- cpuset_cpus = cpu_set_to_range_string(&c->cpuset_cpus);
|
||
|
|
- startup_cpuset_cpus = cpu_set_to_range_string(&c->startup_cpuset_cpus);
|
||
|
|
- cpuset_mems = cpu_set_to_range_string(&c->cpuset_mems);
|
||
|
|
- startup_cpuset_mems = cpu_set_to_range_string(&c->startup_cpuset_mems);
|
||
|
|
+ cpuset_cpus2 = cpu_set_to_range_string(&c->cpuset_cpus2);
|
||
|
|
+ startup_cpuset_cpus2 = cpu_set_to_range_string(&c->startup_cpuset_cpus2);
|
||
|
|
+ cpuset_mems2 = cpu_set_to_range_string(&c->cpuset_mems2);
|
||
|
|
+ startup_cpuset_mems2 = cpu_set_to_range_string(&c->startup_cpuset_mems2);
|
||
|
|
|
||
|
|
fprintf(f,
|
||
|
|
"%sCPUAccounting: %s\n"
|
||
|
|
"%sIOAccounting: %s\n"
|
||
|
|
"%sBlockIOAccounting: %s\n"
|
||
|
|
"%sMemoryAccounting: %s\n"
|
||
|
|
+ "%sCPUSetAccounting: %s\n"
|
||
|
|
"%sTasksAccounting: %s\n"
|
||
|
|
"%sIPAccounting: %s\n"
|
||
|
|
"%sCPUWeight: %" PRIu64 "\n"
|
||
|
|
@@ -469,6 +476,10 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
|
||
|
|
"%sMemorySwapMax: %" PRIu64 "%s\n"
|
||
|
|
"%sMemoryZSwapMax: %" PRIu64 "%s\n"
|
||
|
|
"%sMemoryLimit: %" PRIu64 "\n"
|
||
|
|
+ "%sCPUSetCpus=%s\n"
|
||
|
|
+ "%sCPUSetMems=%s\n"
|
||
|
|
+ "%sCPUSetCloneChildren=%s\n"
|
||
|
|
+ "%sCPUSetMemMigrate=%s\n"
|
||
|
|
"%sTasksMax: %" PRIu64 "\n"
|
||
|
|
"%sDevicePolicy: %s\n"
|
||
|
|
"%sDisableControllers: %s\n"
|
||
|
|
@@ -481,6 +492,7 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
|
||
|
|
prefix, yes_no(c->io_accounting),
|
||
|
|
prefix, yes_no(c->blockio_accounting),
|
||
|
|
prefix, yes_no(c->memory_accounting),
|
||
|
|
+ prefix, yes_no(c->cpuset_accounting),
|
||
|
|
prefix, yes_no(c->tasks_accounting),
|
||
|
|
prefix, yes_no(c->ip_accounting),
|
||
|
|
prefix, c->cpu_weight,
|
||
|
|
@@ -489,10 +501,10 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
|
||
|
|
prefix, c->startup_cpu_shares,
|
||
|
|
prefix, FORMAT_TIMESPAN(c->cpu_quota_per_sec_usec, 1),
|
||
|
|
prefix, FORMAT_TIMESPAN(c->cpu_quota_period_usec, 1),
|
||
|
|
- prefix, strempty(cpuset_cpus),
|
||
|
|
- prefix, strempty(startup_cpuset_cpus),
|
||
|
|
- prefix, strempty(cpuset_mems),
|
||
|
|
- prefix, strempty(startup_cpuset_mems),
|
||
|
|
+ prefix, strempty(cpuset_cpus2),
|
||
|
|
+ prefix, strempty(startup_cpuset_cpus2),
|
||
|
|
+ prefix, strempty(cpuset_mems2),
|
||
|
|
+ prefix, strempty(startup_cpuset_mems2),
|
||
|
|
prefix, c->io_weight,
|
||
|
|
prefix, c->startup_io_weight,
|
||
|
|
prefix, c->blockio_weight,
|
||
|
|
@@ -506,6 +518,10 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
|
||
|
|
prefix, c->memory_swap_max, format_cgroup_memory_limit_comparison(cde, sizeof(cde), u, "MemorySwapMax"),
|
||
|
|
prefix, c->memory_zswap_max, format_cgroup_memory_limit_comparison(cde, sizeof(cde), u, "MemoryZSwapMax"),
|
||
|
|
prefix, c->memory_limit,
|
||
|
|
+ prefix, c->cpuset_cpus,
|
||
|
|
+ prefix, c->cpuset_mems,
|
||
|
|
+ prefix, yes_no(c->cpuset_clone_children),
|
||
|
|
+ prefix, yes_no(c->cpuset_memory_migrate),
|
||
|
|
prefix, tasks_max_resolve(&c->tasks_max),
|
||
|
|
prefix, cgroup_device_policy_to_string(c->device_policy),
|
||
|
|
prefix, strempty(disable_controllers_str),
|
||
|
|
@@ -921,11 +937,11 @@ static bool cgroup_context_has_cpu_shares(CGroupContext *c) {
|
||
|
|
}
|
||
|
|
|
||
|
|
static bool cgroup_context_has_allowed_cpus(CGroupContext *c) {
|
||
|
|
- return c->cpuset_cpus.set || c->startup_cpuset_cpus.set;
|
||
|
|
+ return c->cpuset_cpus2.set || c->startup_cpuset_cpus2.set;
|
||
|
|
}
|
||
|
|
|
||
|
|
static bool cgroup_context_has_allowed_mems(CGroupContext *c) {
|
||
|
|
- return c->cpuset_mems.set || c->startup_cpuset_mems.set;
|
||
|
|
+ return c->cpuset_mems2.set || c->startup_cpuset_mems2.set;
|
||
|
|
}
|
||
|
|
|
||
|
|
static uint64_t cgroup_context_cpu_weight(CGroupContext *c, ManagerState state) {
|
||
|
|
@@ -950,18 +966,18 @@ static uint64_t cgroup_context_cpu_shares(CGroupContext *c, ManagerState state)
|
||
|
|
|
||
|
|
static CPUSet *cgroup_context_allowed_cpus(CGroupContext *c, ManagerState state) {
|
||
|
|
if (IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING, MANAGER_STOPPING) &&
|
||
|
|
- c->startup_cpuset_cpus.set)
|
||
|
|
- return &c->startup_cpuset_cpus;
|
||
|
|
+ c->startup_cpuset_cpus2.set)
|
||
|
|
+ return &c->startup_cpuset_cpus2;
|
||
|
|
else
|
||
|
|
- return &c->cpuset_cpus;
|
||
|
|
+ return &c->cpuset_cpus2;
|
||
|
|
}
|
||
|
|
|
||
|
|
static CPUSet *cgroup_context_allowed_mems(CGroupContext *c, ManagerState state) {
|
||
|
|
if (IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING, MANAGER_STOPPING) &&
|
||
|
|
- c->startup_cpuset_mems.set)
|
||
|
|
- return &c->startup_cpuset_mems;
|
||
|
|
+ c->startup_cpuset_mems2.set)
|
||
|
|
+ return &c->startup_cpuset_mems2;
|
||
|
|
else
|
||
|
|
- return &c->cpuset_mems;
|
||
|
|
+ return &c->cpuset_mems2;
|
||
|
|
}
|
||
|
|
|
||
|
|
usec_t cgroup_cpu_adjust_period(usec_t period, usec_t quota, usec_t resolution, usec_t max_period) {
|
||
|
|
@@ -1495,7 +1511,7 @@ static void cgroup_context_apply(
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
- if ((apply_mask & CGROUP_MASK_CPUSET) && !is_local_root) {
|
||
|
|
+ if ((apply_mask & CGROUP_MASK_CPUSET2) && !is_local_root) {
|
||
|
|
cgroup_apply_unified_cpuset(u, cgroup_context_allowed_cpus(c, state), "cpuset.cpus");
|
||
|
|
cgroup_apply_unified_cpuset(u, cgroup_context_allowed_mems(c, state), "cpuset.mems");
|
||
|
|
}
|
||
|
|
@@ -1667,6 +1683,45 @@ static void cgroup_context_apply(
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
+ if ((apply_mask & CGROUP_MASK_CPUSET) && !is_local_root) {
|
||
|
|
+ (void) set_attribute_and_warn(u, "cpuset", "cgroup.clone_children", one_zero(c->cpuset_clone_children));
|
||
|
|
+ (void) set_attribute_and_warn(u, "cpuset", "cpuset.memory_migrate", one_zero(c->cpuset_memory_migrate));
|
||
|
|
+ if (c->cpuset_cpus) {
|
||
|
|
+ if (streq(c->cpuset_cpus, "all")) {
|
||
|
|
+ _cleanup_free_ char *str_cpuset_cpus = NULL;
|
||
|
|
+ _cleanup_free_ char *cg_root_path_cpus = NULL;
|
||
|
|
+ r = cg_get_root_path(&cg_root_path_cpus);
|
||
|
|
+ if (r < 0)
|
||
|
|
+ log_info_errno(r, "Failed to determine root cgroup, ignoring cgroup cpuset cpus: %m");
|
||
|
|
+ if (cg_root_path_cpus) {
|
||
|
|
+ r = cg_get_attribute("cpuset", cg_root_path_cpus, "cpuset.cpus", &str_cpuset_cpus);
|
||
|
|
+ if (r < 0)
|
||
|
|
+ log_error("cgroup context apply: cg get attribute is error(%d), path=%s.", r, cg_root_path_cpus);
|
||
|
|
+ if (str_cpuset_cpus)
|
||
|
|
+ (void) set_attribute_and_warn(u, "cpuset", "cpuset.cpus", str_cpuset_cpus);
|
||
|
|
+ }
|
||
|
|
+ } else
|
||
|
|
+ (void) set_attribute_and_warn(u, "cpuset", "cpuset.cpus", c->cpuset_cpus);
|
||
|
|
+ }
|
||
|
|
+ if (c->cpuset_mems) {
|
||
|
|
+ if (streq(c->cpuset_mems, "all")) {
|
||
|
|
+ _cleanup_free_ char *str_cpuset_mems = NULL;
|
||
|
|
+ _cleanup_free_ char *cg_root_path_mems = NULL;
|
||
|
|
+ r = cg_get_root_path(&cg_root_path_mems);
|
||
|
|
+ if (r < 0)
|
||
|
|
+ log_info_errno(r, "Failed to determine root cgroup, ignoring cgroup cpuset mems: %m");
|
||
|
|
+ if (cg_root_path_mems) {
|
||
|
|
+ r = cg_get_attribute("cpuset", cg_root_path_mems, "cpuset.mems", &str_cpuset_mems);
|
||
|
|
+ if (r < 0)
|
||
|
|
+ log_error("cgroup context apply: cg get attribute is error(%d), path=%s.", r, cg_root_path_mems);
|
||
|
|
+ if (str_cpuset_mems)
|
||
|
|
+ (void) set_attribute_and_warn(u, "cpuset", "cpuset.mems", str_cpuset_mems);
|
||
|
|
+ }
|
||
|
|
+ } else
|
||
|
|
+ (void) set_attribute_and_warn(u, "cpuset", "cpuset.mems", c->cpuset_mems);
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
/* On cgroup v2 we can apply BPF everywhere. On cgroup v1 we apply it everywhere except for the root of
|
||
|
|
* containers, where we leave this to the manager */
|
||
|
|
if ((apply_mask & (CGROUP_MASK_DEVICES | CGROUP_MASK_BPF_DEVICES)) &&
|
||
|
|
@@ -1808,7 +1863,7 @@ static CGroupMask unit_get_cgroup_mask(Unit *u) {
|
||
|
|
mask |= CGROUP_MASK_CPU;
|
||
|
|
|
||
|
|
if (cgroup_context_has_allowed_cpus(c) || cgroup_context_has_allowed_mems(c))
|
||
|
|
- mask |= CGROUP_MASK_CPUSET;
|
||
|
|
+ mask |= CGROUP_MASK_CPUSET2;
|
||
|
|
|
||
|
|
if (cgroup_context_has_io_config(c) || cgroup_context_has_blockio_config(c))
|
||
|
|
mask |= CGROUP_MASK_IO | CGROUP_MASK_BLKIO;
|
||
|
|
@@ -1818,6 +1873,11 @@ static CGroupMask unit_get_cgroup_mask(Unit *u) {
|
||
|
|
unit_has_unified_memory_config(u))
|
||
|
|
mask |= CGROUP_MASK_MEMORY;
|
||
|
|
|
||
|
|
+ if (c->cpuset_accounting ||
|
||
|
|
+ c->cpuset_cpus ||
|
||
|
|
+ c->cpuset_mems)
|
||
|
|
+ mask |= CGROUP_MASK_CPUSET;
|
||
|
|
+
|
||
|
|
if (c->device_allow ||
|
||
|
|
c->device_policy != CGROUP_DEVICE_POLICY_AUTO)
|
||
|
|
mask |= CGROUP_MASK_DEVICES | CGROUP_MASK_BPF_DEVICES;
|
||
|
|
@@ -4286,7 +4346,7 @@ int unit_get_cpuset(Unit *u, CPUSet *cpus, const char *name) {
|
||
|
|
if (!u->cgroup_path)
|
||
|
|
return -ENODATA;
|
||
|
|
|
||
|
|
- if ((u->cgroup_realized_mask & CGROUP_MASK_CPUSET) == 0)
|
||
|
|
+ if ((u->cgroup_realized_mask & CGROUP_MASK_CPUSET2) == 0)
|
||
|
|
return -ENODATA;
|
||
|
|
|
||
|
|
r = cg_all_unified();
|
||
|
|
diff --git a/src/core/cgroup.h b/src/core/cgroup.h
|
||
|
|
index d137e3a..501cba4 100644
|
||
|
|
--- a/src/core/cgroup.h
|
||
|
|
+++ b/src/core/cgroup.h
|
||
|
|
@@ -115,6 +115,7 @@ struct CGroupContext {
|
||
|
|
bool io_accounting;
|
||
|
|
bool blockio_accounting;
|
||
|
|
bool memory_accounting;
|
||
|
|
+ bool cpuset_accounting;
|
||
|
|
bool tasks_accounting;
|
||
|
|
bool ip_accounting;
|
||
|
|
|
||
|
|
@@ -131,10 +132,10 @@ struct CGroupContext {
|
||
|
|
usec_t cpu_quota_per_sec_usec;
|
||
|
|
usec_t cpu_quota_period_usec;
|
||
|
|
|
||
|
|
- CPUSet cpuset_cpus;
|
||
|
|
- CPUSet startup_cpuset_cpus;
|
||
|
|
- CPUSet cpuset_mems;
|
||
|
|
- CPUSet startup_cpuset_mems;
|
||
|
|
+ CPUSet cpuset_cpus2;
|
||
|
|
+ CPUSet startup_cpuset_cpus2;
|
||
|
|
+ CPUSet cpuset_mems2;
|
||
|
|
+ CPUSet startup_cpuset_mems2;
|
||
|
|
|
||
|
|
uint64_t io_weight;
|
||
|
|
uint64_t startup_io_weight;
|
||
|
|
@@ -151,6 +152,11 @@ struct CGroupContext {
|
||
|
|
uint64_t memory_swap_max;
|
||
|
|
uint64_t memory_zswap_max;
|
||
|
|
|
||
|
|
+ char *cpuset_cpus;
|
||
|
|
+ char *cpuset_mems;
|
||
|
|
+ bool cpuset_clone_children;
|
||
|
|
+ bool cpuset_memory_migrate;
|
||
|
|
+
|
||
|
|
bool default_memory_min_set:1;
|
||
|
|
bool default_memory_low_set:1;
|
||
|
|
bool memory_min_set:1;
|
||
|
|
diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c
|
||
|
|
index b5484ed..c3b140e 100644
|
||
|
|
--- a/src/core/dbus-cgroup.c
|
||
|
|
+++ b/src/core/dbus-cgroup.c
|
||
|
|
@@ -441,10 +441,10 @@ const sd_bus_vtable bus_cgroup_vtable[] = {
|
||
|
|
SD_BUS_PROPERTY("StartupCPUShares", "t", NULL, offsetof(CGroupContext, startup_cpu_shares), 0),
|
||
|
|
SD_BUS_PROPERTY("CPUQuotaPerSecUSec", "t", bus_property_get_usec, offsetof(CGroupContext, cpu_quota_per_sec_usec), 0),
|
||
|
|
SD_BUS_PROPERTY("CPUQuotaPeriodUSec", "t", bus_property_get_usec, offsetof(CGroupContext, cpu_quota_period_usec), 0),
|
||
|
|
- SD_BUS_PROPERTY("AllowedCPUs", "ay", property_get_cpuset, offsetof(CGroupContext, cpuset_cpus), 0),
|
||
|
|
- SD_BUS_PROPERTY("StartupAllowedCPUs", "ay", property_get_cpuset, offsetof(CGroupContext, startup_cpuset_cpus), 0),
|
||
|
|
- SD_BUS_PROPERTY("AllowedMemoryNodes", "ay", property_get_cpuset, offsetof(CGroupContext, cpuset_mems), 0),
|
||
|
|
- SD_BUS_PROPERTY("StartupAllowedMemoryNodes", "ay", property_get_cpuset, offsetof(CGroupContext, startup_cpuset_mems), 0),
|
||
|
|
+ SD_BUS_PROPERTY("AllowedCPUs", "ay", property_get_cpuset, offsetof(CGroupContext, cpuset_cpus2), 0),
|
||
|
|
+ SD_BUS_PROPERTY("StartupAllowedCPUs", "ay", property_get_cpuset, offsetof(CGroupContext, startup_cpuset_cpus2), 0),
|
||
|
|
+ SD_BUS_PROPERTY("AllowedMemoryNodes", "ay", property_get_cpuset, offsetof(CGroupContext, cpuset_mems2), 0),
|
||
|
|
+ SD_BUS_PROPERTY("StartupAllowedMemoryNodes", "ay", property_get_cpuset, offsetof(CGroupContext, startup_cpuset_mems2), 0),
|
||
|
|
SD_BUS_PROPERTY("IOAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, io_accounting), 0),
|
||
|
|
SD_BUS_PROPERTY("IOWeight", "t", NULL, offsetof(CGroupContext, io_weight), 0),
|
||
|
|
SD_BUS_PROPERTY("StartupIOWeight", "t", NULL, offsetof(CGroupContext, startup_io_weight), 0),
|
||
|
|
@@ -470,6 +470,11 @@ const sd_bus_vtable bus_cgroup_vtable[] = {
|
||
|
|
SD_BUS_PROPERTY("MemorySwapMax", "t", NULL, offsetof(CGroupContext, memory_swap_max), 0),
|
||
|
|
SD_BUS_PROPERTY("MemoryZSwapMax", "t", NULL, offsetof(CGroupContext, memory_zswap_max), 0),
|
||
|
|
SD_BUS_PROPERTY("MemoryLimit", "t", NULL, offsetof(CGroupContext, memory_limit), 0),
|
||
|
|
+ SD_BUS_PROPERTY("CPUSetAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, cpuset_accounting), 0),
|
||
|
|
+ SD_BUS_PROPERTY("CPUSetCpus", "s", NULL, offsetof(CGroupContext, cpuset_cpus), 0),
|
||
|
|
+ SD_BUS_PROPERTY("CPUSetMems", "s", NULL, offsetof(CGroupContext, cpuset_mems), 0),
|
||
|
|
+ SD_BUS_PROPERTY("CPUSetCloneChildren", "b", bus_property_get_bool, offsetof(CGroupContext, cpuset_clone_children), 0),
|
||
|
|
+ SD_BUS_PROPERTY("CPUSetMemMigrate", "b", bus_property_get_bool, offsetof(CGroupContext, cpuset_memory_migrate), 0),
|
||
|
|
SD_BUS_PROPERTY("DevicePolicy", "s", property_get_cgroup_device_policy, offsetof(CGroupContext, device_policy), 0),
|
||
|
|
SD_BUS_PROPERTY("DeviceAllow", "a(ss)", property_get_device_allow, 0, 0),
|
||
|
|
SD_BUS_PROPERTY("TasksAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, tasks_accounting), 0),
|
||
|
|
@@ -1129,6 +1134,43 @@ int bus_cgroup_set_property(
|
||
|
|
if (streq(name, "MemoryLimitScale"))
|
||
|
|
return bus_cgroup_set_memory_scale(u, name, &c->memory_limit, message, flags, error);
|
||
|
|
|
||
|
|
+ if (streq(name, "CPUSetAccounting"))
|
||
|
|
+ return bus_cgroup_set_boolean(u, name, &c->cpuset_accounting, CGROUP_MASK_CPUSET, message, flags, error);
|
||
|
|
+
|
||
|
|
+ if (STR_IN_SET(name, "CPUSetCpus", "CPUSetMems")) {
|
||
|
|
+ const char *cpuset_str = NULL;
|
||
|
|
+
|
||
|
|
+ r = sd_bus_message_read(message, "s", &cpuset_str);
|
||
|
|
+ if (r < 0)
|
||
|
|
+ return r;
|
||
|
|
+
|
||
|
|
+ if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||
|
|
+ unit_invalidate_cgroup(u, CGROUP_MASK_CPUSET);
|
||
|
|
+ if (streq(name, "CPUSetCpus")) {
|
||
|
|
+ if (c->cpuset_cpus)
|
||
|
|
+ c->cpuset_cpus = mfree(c->cpuset_cpus);
|
||
|
|
+ c->cpuset_cpus = strdup(cpuset_str);
|
||
|
|
+ if (!c->cpuset_cpus)
|
||
|
|
+ return -ENOMEM;
|
||
|
|
+ unit_write_settingf(u, flags, name, "CPUSetCpus=%s", cpuset_str);
|
||
|
|
+ } else {
|
||
|
|
+ if (c->cpuset_mems)
|
||
|
|
+ c->cpuset_mems = mfree(c->cpuset_mems);
|
||
|
|
+ c->cpuset_mems = strdup(cpuset_str);
|
||
|
|
+ if (!c->cpuset_mems)
|
||
|
|
+ return -ENOMEM;
|
||
|
|
+ unit_write_settingf(u, flags, name, "CPUSetMems=%s", cpuset_str);
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+ return 1;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ if (streq(name, "CPUSetCloneChildren"))
|
||
|
|
+ return bus_cgroup_set_boolean(u, name, &c->cpuset_clone_children, CGROUP_MASK_CPUSET, message, flags, error);
|
||
|
|
+
|
||
|
|
+ if (streq(name, "CPUSetMemMigrate"))
|
||
|
|
+ return bus_cgroup_set_boolean(u, name, &c->cpuset_memory_migrate, CGROUP_MASK_CPUSET, message, flags, error);
|
||
|
|
+
|
||
|
|
if (streq(name, "TasksAccounting"))
|
||
|
|
return bus_cgroup_set_boolean(u, name, &c->tasks_accounting, CGROUP_MASK_PIDS, message, flags, error);
|
||
|
|
|
||
|
|
@@ -1208,13 +1250,13 @@ int bus_cgroup_set_property(
|
||
|
|
return -ENOMEM;
|
||
|
|
|
||
|
|
if (streq(name, "AllowedCPUs"))
|
||
|
|
- set = &c->cpuset_cpus;
|
||
|
|
+ set = &c->cpuset_cpus2;
|
||
|
|
else if (streq(name, "StartupAllowedCPUs"))
|
||
|
|
- set = &c->startup_cpuset_cpus;
|
||
|
|
+ set = &c->startup_cpuset_cpus2;
|
||
|
|
else if (streq(name, "AllowedMemoryNodes"))
|
||
|
|
- set = &c->cpuset_mems;
|
||
|
|
+ set = &c->cpuset_mems2;
|
||
|
|
else if (streq(name, "StartupAllowedMemoryNodes"))
|
||
|
|
- set = &c->startup_cpuset_mems;
|
||
|
|
+ set = &c->startup_cpuset_mems2;
|
||
|
|
|
||
|
|
assert(set);
|
||
|
|
|
||
|
|
@@ -1222,7 +1264,7 @@ int bus_cgroup_set_property(
|
||
|
|
*set = new_set;
|
||
|
|
new_set = (CPUSet) {};
|
||
|
|
|
||
|
|
- unit_invalidate_cgroup(u, CGROUP_MASK_CPUSET);
|
||
|
|
+ unit_invalidate_cgroup(u, CGROUP_MASK_CPUSET2);
|
||
|
|
unit_write_settingf(u, flags, name, "%s=%s", name, setstr);
|
||
|
|
}
|
||
|
|
|
||
|
|
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
|
||
|
|
index c4f205b..d6f45a7 100644
|
||
|
|
--- a/src/core/dbus-manager.c
|
||
|
|
+++ b/src/core/dbus-manager.c
|
||
|
|
@@ -2910,6 +2910,7 @@ const sd_bus_vtable bus_manager_vtable[] = {
|
||
|
|
SD_BUS_PROPERTY("DefaultCPUAccounting", "b", bus_property_get_bool, offsetof(Manager, default_cpu_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
|
||
|
|
SD_BUS_PROPERTY("DefaultBlockIOAccounting", "b", bus_property_get_bool, offsetof(Manager, default_blockio_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
|
||
|
|
SD_BUS_PROPERTY("DefaultMemoryAccounting", "b", bus_property_get_bool, offsetof(Manager, default_memory_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
|
||
|
|
+ SD_BUS_PROPERTY("DefaultCpusetAccounting", "b", bus_property_get_bool, offsetof(Manager, default_cpuset_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
|
||
|
|
SD_BUS_PROPERTY("DefaultTasksAccounting", "b", bus_property_get_bool, offsetof(Manager, default_tasks_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
|
||
|
|
SD_BUS_PROPERTY("DefaultLimitCPU", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
|
||
|
|
SD_BUS_PROPERTY("DefaultLimitCPUSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
|
||
|
|
diff --git a/src/core/load-fragment-gperf.gperf.in b/src/core/load-fragment-gperf.gperf.in
|
||
|
|
index 3ea3ca3..8600faa 100644
|
||
|
|
--- a/src/core/load-fragment-gperf.gperf.in
|
||
|
|
+++ b/src/core/load-fragment-gperf.gperf.in
|
||
|
|
@@ -187,10 +187,10 @@
|
||
|
|
|
||
|
|
{%- macro CGROUP_CONTEXT_CONFIG_ITEMS(type) -%}
|
||
|
|
{{type}}.Slice, config_parse_unit_slice, 0, 0
|
||
|
|
-{{type}}.AllowedCPUs, config_parse_allowed_cpuset, 0, offsetof({{type}}, cgroup_context.cpuset_cpus)
|
||
|
|
-{{type}}.StartupAllowedCPUs, config_parse_allowed_cpuset, 0, offsetof({{type}}, cgroup_context.startup_cpuset_cpus)
|
||
|
|
-{{type}}.AllowedMemoryNodes, config_parse_allowed_cpuset, 0, offsetof({{type}}, cgroup_context.cpuset_mems)
|
||
|
|
-{{type}}.StartupAllowedMemoryNodes, config_parse_allowed_cpuset, 0, offsetof({{type}}, cgroup_context.startup_cpuset_mems)
|
||
|
|
+{{type}}.AllowedCPUs, config_parse_allowed_cpuset, 0, offsetof({{type}}, cgroup_context.cpuset_cpus2)
|
||
|
|
+{{type}}.StartupAllowedCPUs, config_parse_allowed_cpuset, 0, offsetof({{type}}, cgroup_context.startup_cpuset_cpus2)
|
||
|
|
+{{type}}.AllowedMemoryNodes, config_parse_allowed_cpuset, 0, offsetof({{type}}, cgroup_context.cpuset_mems2)
|
||
|
|
+{{type}}.StartupAllowedMemoryNodes, config_parse_allowed_cpuset, 0, offsetof({{type}}, cgroup_context.startup_cpuset_mems2)
|
||
|
|
{{type}}.CPUAccounting, config_parse_bool, 0, offsetof({{type}}, cgroup_context.cpu_accounting)
|
||
|
|
{{type}}.CPUWeight, config_parse_cg_cpu_weight, 0, offsetof({{type}}, cgroup_context.cpu_weight)
|
||
|
|
{{type}}.StartupCPUWeight, config_parse_cg_cpu_weight, 0, offsetof({{type}}, cgroup_context.startup_cpu_weight)
|
||
|
|
@@ -208,6 +208,11 @@
|
||
|
|
{{type}}.MemorySwapMax, config_parse_memory_limit, 0, offsetof({{type}}, cgroup_context)
|
||
|
|
{{type}}.MemoryZSwapMax, config_parse_memory_limit, 0, offsetof({{type}}, cgroup_context)
|
||
|
|
{{type}}.MemoryLimit, config_parse_memory_limit, 0, offsetof({{type}}, cgroup_context)
|
||
|
|
+{{type}}.CPUSetAccounting, config_parse_bool, 0, offsetof({{type}}, cgroup_context.cpuset_accounting)
|
||
|
|
+{{type}}.CPUSetCpus, config_parse_cpuset_cpumems, 0, offsetof({{type}}, cgroup_context.cpuset_cpus)
|
||
|
|
+{{type}}.CPUSetMems, config_parse_cpuset_cpumems, 0, offsetof({{type}}, cgroup_context.cpuset_mems)
|
||
|
|
+{{type}}.CPUSetCloneChildren, config_parse_bool, 0, offsetof({{type}}, cgroup_context.cpuset_clone_children)
|
||
|
|
+{{type}}.CPUSetMemMigrate, config_parse_bool, 0, offsetof({{type}}, cgroup_context.cpuset_memory_migrate)
|
||
|
|
{{type}}.DeviceAllow, config_parse_device_allow, 0, offsetof({{type}}, cgroup_context)
|
||
|
|
{{type}}.DevicePolicy, config_parse_device_policy, 0, offsetof({{type}}, cgroup_context.device_policy)
|
||
|
|
{{type}}.IOAccounting, config_parse_bool, 0, offsetof({{type}}, cgroup_context.io_accounting)
|
||
|
|
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
|
||
|
|
index ce15758..b0feac7 100644
|
||
|
|
--- a/src/core/load-fragment.c
|
||
|
|
+++ b/src/core/load-fragment.c
|
||
|
|
@@ -3864,6 +3864,75 @@ int config_parse_memory_limit(
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
+int config_parse_cpuset_cpumems(
|
||
|
|
+ const char *unit,
|
||
|
|
+ const char *filename,
|
||
|
|
+ unsigned line,
|
||
|
|
+ const char *section,
|
||
|
|
+ unsigned section_line,
|
||
|
|
+ const char *lvalue,
|
||
|
|
+ int ltype,
|
||
|
|
+ const char *rvalue,
|
||
|
|
+ void *data,
|
||
|
|
+ void *userdata)
|
||
|
|
+{
|
||
|
|
+ char **pcpumems = data;
|
||
|
|
+ char *pinstr = NULL;
|
||
|
|
+ int iret = 0;
|
||
|
|
+
|
||
|
|
+ assert(filename);
|
||
|
|
+ assert(lvalue);
|
||
|
|
+ assert(rvalue);
|
||
|
|
+ assert(data);
|
||
|
|
+ (void)section;
|
||
|
|
+ (void)section_line;
|
||
|
|
+ (void)ltype;
|
||
|
|
+ (void)userdata;
|
||
|
|
+
|
||
|
|
+ if (!utf8_is_valid(rvalue))
|
||
|
|
+ {
|
||
|
|
+ log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, rvalue);
|
||
|
|
+ return 0;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ if (0 == strcmp(rvalue, "all"))
|
||
|
|
+ {
|
||
|
|
+ pinstr = strdup(rvalue);
|
||
|
|
+ if (!pinstr)
|
||
|
|
+ {
|
||
|
|
+ return log_oom();
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ free(*pcpumems);
|
||
|
|
+ *pcpumems = pinstr;
|
||
|
|
+
|
||
|
|
+ return 0;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ /* 0-2,4 */
|
||
|
|
+ iret = string_isvalid_interval(rvalue);
|
||
|
|
+ if (0 != iret)
|
||
|
|
+ {
|
||
|
|
+ pinstr = NULL;
|
||
|
|
+ log_syntax(unit, LOG_ERR, filename, line, EINVAL,
|
||
|
|
+ "cpuset cpumems '%s' is invalid, Ignoring(%d).",
|
||
|
|
+ rvalue, iret);
|
||
|
|
+ }
|
||
|
|
+ else
|
||
|
|
+ {
|
||
|
|
+ pinstr = strdup(rvalue);
|
||
|
|
+ if (!pinstr)
|
||
|
|
+ {
|
||
|
|
+ return log_oom();
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ free(*pcpumems);
|
||
|
|
+ *pcpumems = pinstr;
|
||
|
|
+
|
||
|
|
+ return 0;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
int config_parse_tasks_max(
|
||
|
|
const char *unit,
|
||
|
|
const char *filename,
|
||
|
|
diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h
|
||
|
|
index 11d43dd..405681f 100644
|
||
|
|
--- a/src/core/load-fragment.h
|
||
|
|
+++ b/src/core/load-fragment.h
|
||
|
|
@@ -81,6 +81,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_cg_weight);
|
||
|
|
CONFIG_PARSER_PROTOTYPE(config_parse_cg_cpu_weight);
|
||
|
|
CONFIG_PARSER_PROTOTYPE(config_parse_cpu_shares);
|
||
|
|
CONFIG_PARSER_PROTOTYPE(config_parse_memory_limit);
|
||
|
|
+CONFIG_PARSER_PROTOTYPE(config_parse_cpuset_cpumems);
|
||
|
|
CONFIG_PARSER_PROTOTYPE(config_parse_tasks_max);
|
||
|
|
CONFIG_PARSER_PROTOTYPE(config_parse_delegate);
|
||
|
|
CONFIG_PARSER_PROTOTYPE(config_parse_managed_oom_mode);
|
||
|
|
diff --git a/src/core/main.c b/src/core/main.c
|
||
|
|
index c6d16b2..e64882c 100644
|
||
|
|
--- a/src/core/main.c
|
||
|
|
+++ b/src/core/main.c
|
||
|
|
@@ -160,6 +160,7 @@ static bool arg_default_io_accounting;
|
||
|
|
static bool arg_default_ip_accounting;
|
||
|
|
static bool arg_default_blockio_accounting;
|
||
|
|
static bool arg_default_memory_accounting;
|
||
|
|
+static bool arg_default_cpuset_accounting;
|
||
|
|
static bool arg_default_tasks_accounting;
|
||
|
|
static TasksMax arg_default_tasks_max;
|
||
|
|
static sd_id128_t arg_machine_id;
|
||
|
|
@@ -681,6 +682,7 @@ static int parse_config_file(void) {
|
||
|
|
{ "Manager", "DefaultIPAccounting", config_parse_bool, 0, &arg_default_ip_accounting },
|
||
|
|
{ "Manager", "DefaultBlockIOAccounting", config_parse_bool, 0, &arg_default_blockio_accounting },
|
||
|
|
{ "Manager", "DefaultMemoryAccounting", config_parse_bool, 0, &arg_default_memory_accounting },
|
||
|
|
+ { "Manager", "DefaultCpusetAccounting", config_parse_bool, 0, &arg_default_cpuset_accounting },
|
||
|
|
{ "Manager", "DefaultTasksAccounting", config_parse_bool, 0, &arg_default_tasks_accounting },
|
||
|
|
{ "Manager", "DefaultTasksMax", config_parse_tasks_max, 0, &arg_default_tasks_max },
|
||
|
|
{ "Manager", "CtrlAltDelBurstAction", config_parse_emergency_action, arg_system, &arg_cad_burst_action },
|
||
|
|
@@ -762,6 +764,7 @@ static void set_manager_defaults(Manager *m) {
|
||
|
|
m->default_ip_accounting = arg_default_ip_accounting;
|
||
|
|
m->default_blockio_accounting = arg_default_blockio_accounting;
|
||
|
|
m->default_memory_accounting = arg_default_memory_accounting;
|
||
|
|
+ m->default_cpuset_accounting = arg_default_cpuset_accounting;
|
||
|
|
m->default_tasks_accounting = arg_default_tasks_accounting;
|
||
|
|
m->default_tasks_max = arg_default_tasks_max;
|
||
|
|
m->default_oom_policy = arg_default_oom_policy;
|
||
|
|
@@ -2457,6 +2460,7 @@ static void reset_arguments(void) {
|
||
|
|
arg_default_ip_accounting = false;
|
||
|
|
arg_default_blockio_accounting = false;
|
||
|
|
arg_default_memory_accounting = MEMORY_ACCOUNTING_DEFAULT;
|
||
|
|
+ arg_default_cpuset_accounting = false;
|
||
|
|
arg_default_tasks_accounting = true;
|
||
|
|
arg_default_tasks_max = DEFAULT_TASKS_MAX;
|
||
|
|
arg_machine_id = (sd_id128_t) {};
|
||
|
|
diff --git a/src/core/manager.c b/src/core/manager.c
|
||
|
|
index 2c8c726..011de6b 100644
|
||
|
|
--- a/src/core/manager.c
|
||
|
|
+++ b/src/core/manager.c
|
||
|
|
@@ -833,6 +833,7 @@ int manager_new(LookupScope scope, ManagerTestRunFlags test_run_flags, Manager *
|
||
|
|
|
||
|
|
.default_timer_accuracy_usec = USEC_PER_MINUTE,
|
||
|
|
.default_memory_accounting = MEMORY_ACCOUNTING_DEFAULT,
|
||
|
|
+ .default_cpuset_accounting = false,
|
||
|
|
.default_tasks_accounting = true,
|
||
|
|
.default_tasks_max = TASKS_MAX_UNSET,
|
||
|
|
.default_timeout_start_usec = manager_default_timeout(scope == LOOKUP_SCOPE_SYSTEM),
|
||
|
|
diff --git a/src/core/manager.h b/src/core/manager.h
|
||
|
|
index e7b594f..c4edacc 100644
|
||
|
|
--- a/src/core/manager.h
|
||
|
|
+++ b/src/core/manager.h
|
||
|
|
@@ -365,6 +365,7 @@ struct Manager {
|
||
|
|
|
||
|
|
bool default_cpu_accounting;
|
||
|
|
bool default_memory_accounting;
|
||
|
|
+ bool default_cpuset_accounting;
|
||
|
|
bool default_io_accounting;
|
||
|
|
bool default_blockio_accounting;
|
||
|
|
bool default_tasks_accounting;
|
||
|
|
diff --git a/src/core/system.conf.in b/src/core/system.conf.in
|
||
|
|
index 1349b1f..a0ef2bf 100644
|
||
|
|
--- a/src/core/system.conf.in
|
||
|
|
+++ b/src/core/system.conf.in
|
||
|
|
@@ -55,6 +55,7 @@
|
||
|
|
#DefaultIOAccounting=no
|
||
|
|
#DefaultIPAccounting=no
|
||
|
|
#DefaultMemoryAccounting={{ 'yes' if MEMORY_ACCOUNTING_DEFAULT else 'no' }}
|
||
|
|
+#DefaultCpusetAccounting=
|
||
|
|
#DefaultTasksAccounting=yes
|
||
|
|
#DefaultTasksMax=80%
|
||
|
|
#DefaultLimitCPU=
|
||
|
|
diff --git a/src/core/unit.c b/src/core/unit.c
|
||
|
|
index 5e230ef..9ac41b4 100644
|
||
|
|
--- a/src/core/unit.c
|
||
|
|
+++ b/src/core/unit.c
|
||
|
|
@@ -179,6 +179,7 @@ static void unit_init(Unit *u) {
|
||
|
|
cc->io_accounting = u->manager->default_io_accounting;
|
||
|
|
cc->blockio_accounting = u->manager->default_blockio_accounting;
|
||
|
|
cc->memory_accounting = u->manager->default_memory_accounting;
|
||
|
|
+ cc->cpuset_accounting = u->manager->default_cpuset_accounting;
|
||
|
|
cc->tasks_accounting = u->manager->default_tasks_accounting;
|
||
|
|
cc->ip_accounting = u->manager->default_ip_accounting;
|
||
|
|
|
||
|
|
diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c
|
||
|
|
index 1e95e36..e1aed3d 100644
|
||
|
|
--- a/src/shared/bus-unit-util.c
|
||
|
|
+++ b/src/shared/bus-unit-util.c
|
||
|
|
@@ -481,7 +481,10 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
|
||
|
|
"IOAccounting",
|
||
|
|
"BlockIOAccounting",
|
||
|
|
"TasksAccounting",
|
||
|
|
- "IPAccounting"))
|
||
|
|
+ "IPAccounting",
|
||
|
|
+ "CPUSetAccounting",
|
||
|
|
+ "CPUSetCloneChildren",
|
||
|
|
+ "CPUSetMemMigrate"))
|
||
|
|
return bus_append_parse_boolean(m, field, eq);
|
||
|
|
|
||
|
|
if (STR_IN_SET(field, "CPUWeight",
|
||
|
|
@@ -587,6 +590,16 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
|
||
|
|
return bus_append_parse_size(m, field, eq, 1024);
|
||
|
|
}
|
||
|
|
|
||
|
|
+ if (STR_IN_SET(field, "CPUSetCpus", "CPUSetMems")) {
|
||
|
|
+ if (string_isvalid_interval(eq) == 0 || streq(eq, "all"))
|
||
|
|
+ r = sd_bus_message_append(m, "(sv)", field, "s", eq);
|
||
|
|
+ else
|
||
|
|
+ r = -EINVAL;
|
||
|
|
+ if (r < 0)
|
||
|
|
+ return bus_log_create_error(r);
|
||
|
|
+ return 1;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
if (streq(field, "CPUQuota")) {
|
||
|
|
if (isempty(eq))
|
||
|
|
r = sd_bus_message_append(m, "(sv)", "CPUQuotaPerSecUSec", "t", USEC_INFINITY);
|
||
|
|
diff --git a/src/shared/cpu-set-util.c b/src/shared/cpu-set-util.c
|
||
|
|
index 34c13cf..68da01b 100644
|
||
|
|
--- a/src/shared/cpu-set-util.c
|
||
|
|
+++ b/src/shared/cpu-set-util.c
|
||
|
|
@@ -7,6 +7,7 @@
|
||
|
|
|
||
|
|
#include "alloc-util.h"
|
||
|
|
#include "cpu-set-util.h"
|
||
|
|
+#include "cgroup-util.h"
|
||
|
|
#include "dirent-util.h"
|
||
|
|
#include "errno-util.h"
|
||
|
|
#include "extract-word.h"
|
||
|
|
diff --git a/src/test/test-cgroup-mask.c b/src/test/test-cgroup-mask.c
|
||
|
|
index 57483f7..e969569 100644
|
||
|
|
--- a/src/test/test-cgroup-mask.c
|
||
|
|
+++ b/src/test/test-cgroup-mask.c
|
||
|
|
@@ -55,6 +55,7 @@ TEST_RET(cgroup_mask, .sd_booted = true) {
|
||
|
|
* else. */
|
||
|
|
m->default_cpu_accounting =
|
||
|
|
m->default_memory_accounting =
|
||
|
|
+ m->default_cpuset_accounting =
|
||
|
|
m->default_blockio_accounting =
|
||
|
|
m->default_io_accounting =
|
||
|
|
m->default_tasks_accounting = false;
|
||
|
|
@@ -140,10 +141,10 @@ static void test_cg_mask_to_string_one(CGroupMask mask, const char *t) {
|
||
|
|
|
||
|
|
TEST(cg_mask_to_string) {
|
||
|
|
test_cg_mask_to_string_one(0, NULL);
|
||
|
|
- test_cg_mask_to_string_one(_CGROUP_MASK_ALL, "cpu cpuacct cpuset io blkio memory devices pids bpf-firewall bpf-devices bpf-foreign bpf-socket-bind bpf-restrict-network-interfaces");
|
||
|
|
+ test_cg_mask_to_string_one(_CGROUP_MASK_ALL, "cpu cpuacct cpuset2 io blkio memory devices pids cpuset bpf-firewall bpf-devices bpf-foreign bpf-socket-bind bpf-restrict-network-interfaces");
|
||
|
|
test_cg_mask_to_string_one(CGROUP_MASK_CPU, "cpu");
|
||
|
|
test_cg_mask_to_string_one(CGROUP_MASK_CPUACCT, "cpuacct");
|
||
|
|
- test_cg_mask_to_string_one(CGROUP_MASK_CPUSET, "cpuset");
|
||
|
|
+ test_cg_mask_to_string_one(CGROUP_MASK_CPUSET2, "cpuset2");
|
||
|
|
test_cg_mask_to_string_one(CGROUP_MASK_IO, "io");
|
||
|
|
test_cg_mask_to_string_one(CGROUP_MASK_BLKIO, "blkio");
|
||
|
|
test_cg_mask_to_string_one(CGROUP_MASK_MEMORY, "memory");
|
||
|
|
diff --git a/test/fuzz/fuzz-unit-file/directives-all.service b/test/fuzz/fuzz-unit-file/directives-all.service
|
||
|
|
index f8237d7..dcf99e1 100644
|
||
|
|
--- a/test/fuzz/fuzz-unit-file/directives-all.service
|
||
|
|
+++ b/test/fuzz/fuzz-unit-file/directives-all.service
|
||
|
|
@@ -52,6 +52,11 @@ BusName=
|
||
|
|
CoredumpFilter=
|
||
|
|
CPUAccounting=
|
||
|
|
CPUQuota=
|
||
|
|
+CPUSetAccounting=
|
||
|
|
+CPUSetCloneChildren=
|
||
|
|
+CPUSetCpus=
|
||
|
|
+CPUSetMemMigrate=
|
||
|
|
+CPUSetMems=
|
||
|
|
CPUShares=
|
||
|
|
CPUWeight=
|
||
|
|
CapabilityBoundingSet=
|
||
|
|
--
|
||
|
|
2.33.0
|
||
|
|
|