diff options
author | Lennart Poettering <lennart@poettering.net> | 2021-09-27 13:44:54 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-27 13:44:54 +0200 |
commit | 49e9218ae3c69bae73b89da687d957c7327ed780 (patch) | |
tree | bcfe01a531a70102636508f6f7419a7e62ba429f | |
parent | 66a0e222937e145a1722640fab413608f565cf33 (diff) | |
parent | 058a2d8f1376199861555c94b1915af0a6d7c925 (diff) | |
download | systemd-49e9218ae3c69bae73b89da687d957c7327ed780.tar.gz |
Merge pull request #20768 from pdmorrow/shutdown_cgroup_ctrl
cgroups: apply StartupAllowedCPUs= and StartupAllowedMemoryNodes= during shutdown
-rw-r--r-- | man/systemd.resource-control.xml | 38 | ||||
-rw-r--r-- | src/core/cgroup.c | 33 | ||||
-rw-r--r-- | src/core/cgroup.h | 2 | ||||
-rw-r--r-- | src/core/job.c | 2 | ||||
-rw-r--r-- | src/core/unit.c | 10 | ||||
-rw-r--r-- | test/fuzz/fuzz-unit-file/directives.mount | 4 | ||||
-rw-r--r-- | test/fuzz/fuzz-unit-file/directives.scope | 4 | ||||
-rw-r--r-- | test/fuzz/fuzz-unit-file/directives.service | 4 | ||||
-rw-r--r-- | test/fuzz/fuzz-unit-file/directives.slice | 4 | ||||
-rw-r--r-- | test/fuzz/fuzz-unit-file/directives.socket | 4 | ||||
-rw-r--r-- | test/fuzz/fuzz-unit-file/directives.swap | 4 |
11 files changed, 62 insertions, 47 deletions
diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml index b21f8575a0..23aedc8d8d 100644 --- a/man/systemd.resource-control.xml +++ b/man/systemd.resource-control.xml @@ -189,10 +189,10 @@ Scheduler</ulink>. The available CPU time is split up among all units within one slice relative to their CPU time weight. A higher weight means more CPU time, a lower weight means less.</para> - <para>While <varname>StartupCPUWeight=</varname> only applies to the startup phase of the system, + <para>While <varname>StartupCPUWeight=</varname> applies to the startup and shutdown phases of the system, <varname>CPUWeight=</varname> applies to normal runtime of the system, and if the former is not set also to - the startup phase. Using <varname>StartupCPUWeight=</varname> allows prioritizing specific services at - boot-up differently than during normal runtime.</para> + the startup and shutdown phases. Using <varname>StartupCPUWeight=</varname> allows prioritizing specific services at + boot-up and shutdown differently than during normal runtime.</para> <para>These settings replace <varname>CPUShares=</varname> and <varname>StartupCPUShares=</varname>.</para> </listitem> @@ -247,10 +247,10 @@ of the CPUs will be used by the processes as it may be limited by parent units. The effective configuration is reported as <varname>EffectiveCPUs=</varname>.</para> - <para>While <varname>StartupAllowedCPUs=</varname> only applies to the startup phase of the system, + <para>While <varname>StartupAllowedCPUs=</varname> applies to the startup and shutdown phases of the system, <varname>AllowedCPUs=</varname> applies to normal runtime of the system, and if the former is not set also to - the startup phase. Using <varname>StartupAllowedCPUs=</varname> allows prioritizing specific services at - boot-up differently than during normal runtime.</para> + the startup and shutdown phases. Using <varname>StartupAllowedCPUs=</varname> allows prioritizing specific services at + boot-up and shutdown differently than during normal runtime.</para> <para>This setting is supported only with the unified control group hierarchy.</para> </listitem> @@ -269,10 +269,10 @@ guarantee that all of the memory NUMA nodes will be used by the processes as it may be limited by parent units. The effective configuration is reported as <varname>EffectiveMemoryNodes=</varname>.</para> - <para>While <varname>StartupAllowedMemoryNodes=</varname> only applies to the startup phase of the system, + <para>While <varname>StartupAllowedMemoryNodes=</varname> applies to the startup and shutdown phases of the system, <varname>AllowedMemoryNodes=</varname> applies to normal runtime of the system, and if the former is not set also to - the startup phase. Using <varname>StartupAllowedMemoryNodes=</varname> allows prioritizing specific services at - boot-up differently than during normal runtime.</para> + the startup and shutdown phases. Using <varname>StartupAllowedMemoryNodes=</varname> allows prioritizing specific services at + boot-up and shutdown differently than during normal runtime.</para> <para>This setting is supported only with the unified control group hierarchy.</para> </listitem> @@ -458,12 +458,12 @@ relative to their block I/O weight. A higher weight means more I/O bandwidth, a lower weight means less.</para> - <para>While <varname>StartupIOWeight=</varname> only applies - to the startup phase of the system, + <para>While <varname>StartupIOWeight=</varname> applies + to the startup and shutdown phases of the system, <varname>IOWeight=</varname> applies to the later runtime of the system, and if the former is not set also to the startup - phase. This allows prioritizing specific services at boot-up - differently than during runtime.</para> + and shutdown phases. This allows prioritizing specific services at boot-up + and shutdown differently than during runtime.</para> <para>These settings replace <varname>BlockIOWeight=</varname> and <varname>StartupBlockIOWeight=</varname> and disable settings prefixed with <varname>BlockIO</varname> or <varname>StartupBlockIO</varname>.</para> @@ -1194,10 +1194,10 @@ DeviceAllow=/dev/loop-control The available CPU time is split up among all units within one slice relative to their CPU time share weight.</para> - <para>While <varname>StartupCPUShares=</varname> only applies to the startup phase of the system, + <para>While <varname>StartupCPUShares=</varname> applies to the startup and shutdown phases of the system, <varname>CPUShares=</varname> applies to normal runtime of the system, and if the former is not set also to - the startup phase. Using <varname>StartupCPUShares=</varname> allows prioritizing specific services at - boot-up differently than during normal runtime.</para> + the startup and shutdown phases. Using <varname>StartupCPUShares=</varname> allows prioritizing specific services at + boot-up and shutdown differently than during normal runtime.</para> <para>Implies <literal>CPUAccounting=yes</literal>.</para> @@ -1254,11 +1254,11 @@ DeviceAllow=/dev/loop-control weight.</para> <para>While <varname>StartupBlockIOWeight=</varname> only - applies to the startup phase of the system, + applies to the startup and shutdown phases of the system, <varname>BlockIOWeight=</varname> applies to the later runtime of the system, and if the former is not set also to the - startup phase. This allows prioritizing specific services at - boot-up differently than during runtime.</para> + startup and shutdown phases. This allows prioritizing specific services at + boot-up and shutdown differently than during runtime.</para> <para>Implies <literal>BlockIOAccounting=yes</literal>.</para> diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 17e93d7af1..c19454e8bd 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -68,6 +68,25 @@ bool manager_owns_host_root_cgroup(Manager *m) { return empty_or_root(m->cgroup_root); } +bool unit_has_startup_cgroup_constraints(Unit *u) { + assert(u); + + /* Returns true if this unit has any directives which apply during + * startup/shutdown phases. */ + + CGroupContext *c; + + c = unit_get_cgroup_context(u); + if (!c) + return false; + + 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; +} + bool unit_has_host_root_cgroup(Unit *u) { assert(u); @@ -844,7 +863,7 @@ static bool cgroup_context_has_allowed_mems(CGroupContext *c) { } static uint64_t cgroup_context_cpu_weight(CGroupContext *c, ManagerState state) { - if (IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING) && + if (IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING, MANAGER_STOPPING) && c->startup_cpu_weight != CGROUP_WEIGHT_INVALID) return c->startup_cpu_weight; else if (c->cpu_weight != CGROUP_WEIGHT_INVALID) @@ -854,7 +873,7 @@ static uint64_t cgroup_context_cpu_weight(CGroupContext *c, ManagerState state) } static uint64_t cgroup_context_cpu_shares(CGroupContext *c, ManagerState state) { - if (IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING) && + if (IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING, MANAGER_STOPPING) && c->startup_cpu_shares != CGROUP_CPU_SHARES_INVALID) return c->startup_cpu_shares; else if (c->cpu_shares != CGROUP_CPU_SHARES_INVALID) @@ -864,7 +883,7 @@ 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) && + if (IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING, MANAGER_STOPPING) && c->startup_cpuset_cpus.set) return &c->startup_cpuset_cpus; else @@ -872,7 +891,7 @@ static CPUSet *cgroup_context_allowed_cpus(CGroupContext *c, ManagerState state) } static CPUSet *cgroup_context_allowed_mems(CGroupContext *c, ManagerState state) { - if (IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING) && + if (IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING, MANAGER_STOPPING) && c->startup_cpuset_mems.set) return &c->startup_cpuset_mems; else @@ -993,7 +1012,7 @@ static bool cgroup_context_has_blockio_config(CGroupContext *c) { } static uint64_t cgroup_context_io_weight(CGroupContext *c, ManagerState state) { - if (IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING) && + if (IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING, MANAGER_STOPPING) && c->startup_io_weight != CGROUP_WEIGHT_INVALID) return c->startup_io_weight; else if (c->io_weight != CGROUP_WEIGHT_INVALID) @@ -1003,7 +1022,7 @@ static uint64_t cgroup_context_io_weight(CGroupContext *c, ManagerState state) { } static uint64_t cgroup_context_blkio_weight(CGroupContext *c, ManagerState state) { - if (IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING) && + if (IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING, MANAGER_STOPPING) && c->startup_blockio_weight != CGROUP_BLKIO_WEIGHT_INVALID) return c->startup_blockio_weight; else if (c->blockio_weight != CGROUP_BLKIO_WEIGHT_INVALID) @@ -3971,7 +3990,7 @@ void manager_invalidate_startup_units(Manager *m) { assert(m); SET_FOREACH(u, m->startup_units) - unit_invalidate_cgroup(u, CGROUP_MASK_CPU|CGROUP_MASK_IO|CGROUP_MASK_BLKIO); + unit_invalidate_cgroup(u, CGROUP_MASK_CPU|CGROUP_MASK_IO|CGROUP_MASK_BLKIO|CGROUP_MASK_CPUSET); } static int unit_get_nice(Unit *u) { diff --git a/src/core/cgroup.h b/src/core/cgroup.h index 951ddda525..8795f2724e 100644 --- a/src/core/cgroup.h +++ b/src/core/cgroup.h @@ -311,6 +311,8 @@ int unit_reset_accounting(Unit *u); bool manager_owns_host_root_cgroup(Manager *m); bool unit_has_host_root_cgroup(Unit *u); +bool unit_has_startup_cgroup_constraints(Unit *u); + int manager_notify_cgroup_empty(Manager *m, const char *group); void unit_invalidate_cgroup(Unit *u, CGroupMask m); diff --git a/src/core/job.c b/src/core/job.c index 6eb135785b..6dd01a6f49 100644 --- a/src/core/job.c +++ b/src/core/job.c @@ -1335,6 +1335,8 @@ void job_shutdown_magic(Job *j) { /* In case messages on console has been disabled on boot */ j->unit->manager->no_console_output = false; + manager_invalidate_startup_units(j->unit->manager); + if (detect_container() > 0) return; diff --git a/src/core/unit.c b/src/core/unit.c index 1a76abf8a1..4fd499a4f1 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -1557,15 +1557,7 @@ static int unit_add_oomd_dependencies(Unit *u) { } static int unit_add_startup_units(Unit *u) { - CGroupContext *c; - - c = unit_get_cgroup_context(u); - if (!c) - return 0; - - if (c->startup_cpu_shares == CGROUP_CPU_SHARES_INVALID && - c->startup_io_weight == CGROUP_WEIGHT_INVALID && - c->startup_blockio_weight == CGROUP_BLKIO_WEIGHT_INVALID) + if (!unit_has_startup_cgroup_constraints(u)) return 0; return set_ensure_put(&u->manager->startup_units, NULL, u); diff --git a/test/fuzz/fuzz-unit-file/directives.mount b/test/fuzz/fuzz-unit-file/directives.mount index da33c99de3..33c44c79c5 100644 --- a/test/fuzz/fuzz-unit-file/directives.mount +++ b/test/fuzz/fuzz-unit-file/directives.mount @@ -1,9 +1,7 @@ mount [Mount] AllowedCPUs= -StartupAllowedCPUs= AllowedMemoryNodes= -StartupAllowedMemoryNodes= AmbientCapabilities= AppArmorProfile= BPFProgram= @@ -174,6 +172,8 @@ StandardInput= StandardInputData= StandardInputText= StandardOutput= +StartupAllowedCPUs= +StartupAllowedMemoryNodes= StartupBlockIOWeight= StartupCPUShares= StartupCPUWeight= diff --git a/test/fuzz/fuzz-unit-file/directives.scope b/test/fuzz/fuzz-unit-file/directives.scope index d8ea9fcfb5..aa91ebbf58 100644 --- a/test/fuzz/fuzz-unit-file/directives.scope +++ b/test/fuzz/fuzz-unit-file/directives.scope @@ -1,9 +1,7 @@ scope [Scope] AllowedCPUs= -StartupAllowedCPUs= AllowedMemoryNodes= -StartupAllowedMemoryNodes= BPFProgram= BlockIOAccounting= BlockIODeviceWeight= @@ -57,6 +55,8 @@ SendSIGKILL= Slice= SocketBindAllow= SocketBindDeny= +StartupAllowedCPUs= +StartupAllowedMemoryNodes= StartupBlockIOWeight= StartupCPUShares= StartupCPUWeight= diff --git a/test/fuzz/fuzz-unit-file/directives.service b/test/fuzz/fuzz-unit-file/directives.service index 7318c5f9d6..d92d90e118 100644 --- a/test/fuzz/fuzz-unit-file/directives.service +++ b/test/fuzz/fuzz-unit-file/directives.service @@ -115,9 +115,7 @@ RequiredBy= WantedBy= [Service] AllowedCPUs= -StartupAllowedCPUs= AllowedMemoryNodes= -StartupAllowedMemoryNodes= AmbientCapabilities= AppArmorProfile= BindPaths= @@ -308,6 +306,8 @@ StandardOutput= StartLimitAction= StartLimitBurst= StartLimitInterval= +StartupAllowedCPUs= +StartupAllowedMemoryNodes= StartupBlockIOWeight= StartupCPUShares= StartupCPUWeight= diff --git a/test/fuzz/fuzz-unit-file/directives.slice b/test/fuzz/fuzz-unit-file/directives.slice index 1a20987698..ab77070c5e 100644 --- a/test/fuzz/fuzz-unit-file/directives.slice +++ b/test/fuzz/fuzz-unit-file/directives.slice @@ -1,9 +1,7 @@ slice [Slice] AllowedCPUs= -StartupAllowedCPUs= AllowedMemoryNodes= -StartupAllowedMemoryNodes= BPFProgram= BlockIOAccounting= BlockIODeviceWeight= @@ -50,6 +48,8 @@ RestrictNetworkInterfaces= Slice= SocketBindAllow= SocketBindDeny= +StartupAllowedCPUs= +StartupAllowedMemoryNodes= StartupBlockIOWeight= StartupCPUShares= StartupCPUWeight= diff --git a/test/fuzz/fuzz-unit-file/directives.socket b/test/fuzz/fuzz-unit-file/directives.socket index 02b909f00d..fa28ff1042 100644 --- a/test/fuzz/fuzz-unit-file/directives.socket +++ b/test/fuzz/fuzz-unit-file/directives.socket @@ -2,9 +2,7 @@ socket [Socket] Accept= AllowedCPUs= -StartupAllowedCPUs= AllowedMemoryNodes= -StartupAllowedMemoryNodes= AmbientCapabilities= AppArmorProfile= BPFProgram= @@ -220,6 +218,8 @@ StandardInput= StandardInputData= StandardInputText= StandardOutput= +StartupAllowedCPUs= +StartupAllowedMemoryNodes= StartupBlockIOWeight= StartupCPUShares= StartupCPUWeight= diff --git a/test/fuzz/fuzz-unit-file/directives.swap b/test/fuzz/fuzz-unit-file/directives.swap index b7598fdf06..abb3cd54e7 100644 --- a/test/fuzz/fuzz-unit-file/directives.swap +++ b/test/fuzz/fuzz-unit-file/directives.swap @@ -1,9 +1,7 @@ swap [Swap] AllowedCPUs= -StartupAllowedCPUs= AllowedMemoryNodes= -StartupAllowedMemoryNodes= AmbientCapabilities= AppArmorProfile= BPFProgram= @@ -170,6 +168,8 @@ StandardInput= StandardInputData= StandardInputText= StandardOutput= +StartupAllowedCPUs= +StartupAllowedMemoryNodes= StartupBlockIOWeight= StartupCPUShares= StartupCPUWeight= |