Currently, Unit.freezer_state is always initialized to
FREEZER_RUNNING. While realizing cgroups for frozen units
was disabled in
7923e9493c48694b32d1a6de7b9a996c0194bf17,
the commit only checked for freezer_state of the unit inself,
meaning that newly-loaded units might be started and the kernel
would hang pid1 when trying to spawn sd-executor into sub-cgroup.
This can be easily reproduced by the following:
```console
# systemd-run --slice=test.slice sleep infinity
# systemctl freeze test.slice
# systemd-run --slice=test.slice sleep infinity
```
Therefore, let's correctly initialize Unit.freezer_state
based on the parent slice.
static int unit_add_slice_dependencies(Unit *u) {
Unit *slice;
+
assert(u);
if (!UNIT_HAS_CGROUP_CONTEXT(u))
UnitDependencyMask mask = u->type == UNIT_SLICE ? UNIT_DEPENDENCY_IMPLICIT : UNIT_DEPENDENCY_FILE;
slice = UNIT_GET_SLICE(u);
- if (slice)
+ if (slice) {
+ if (!IN_SET(slice->freezer_state, FREEZER_RUNNING, FREEZER_THAWING))
+ u->freezer_state = FREEZER_FROZEN_BY_PARENT;
+
return unit_add_two_dependencies(u, UNIT_AFTER, UNIT_REQUIRES, slice, true, mask);
+ }
if (unit_has_name(u, SPECIAL_ROOT_SLICE))
return 0;