When OpenRC runs as PID 1 inside an Incus/LXC container with cgroup v2 delegated controllers, it leaves PID 1 and early processes such as agetty in the cgroup namespace root (in /sys/fs/cgroup/cgroup.procs). This cgroup is not the root cgroup as defined in man 7 cgroups, and thus the cgroups v2 "no internal processes" rule that is mentioned on the same man page applies.
As a result, the "container-root-cgroup" contains member processes and cannot enable domain controllers in cgroup.subtree_control. This breaks the delegation of CPU, memory, I/O, and pids controllers to child cgroups.
Consequences in more details
The cgroups service effectively starts “successfully”, but the controllers are not enabled.
During the boot process, errors from init.d/cgroups.in are clearly visible when it tries to write to cgroup.subtree_control:
uz-app3 ~ # lxc-start -F uz-app3-docker
INIT: version 3.14 booting
OpenRC 0.62.6 is starting up Gentoo Linux (x86_64) [LXC]
* /proc is already mounted
* Mounting /run ... [ ok ]
* /run/openrc: creating directory
* /run/lock: creating directory
* /run/lock: correcting owner
/etc/init.d/cgroups: line 92: echo: write error: Device or resource busy
/etc/init.d/cgroups: line 92: echo: write error: Device or resource busy
/etc/init.d/cgroups: line 92: echo: write error: Device or resource busy
The failing operation is effectively (see init.d/cgroups.in line 80):
echo "+${x}" > cgroup.subtree_control
Because the root cgroup contains member processes, the kernel rejects this with Device or resource busy.
OpenRC resource limits do not work correctly under this hierarchy.
Nested runtimes such as Docker can still create cgroup directories and start containers, but Docker resource accounting is incomplete or empty: docker stats reports zeros for CPU, memory, pids and block I/O.
The same problem and possible workaround were reported here:
https://discuss.linuxcontainers.org/t/enabling-root-cgroup-subtree-control-with-alpine-linux-containers/26515
When OpenRC runs as PID 1 inside an Incus/LXC container with cgroup v2 delegated controllers, it leaves PID 1 and early processes such as agetty in the cgroup namespace root (in
/sys/fs/cgroup/cgroup.procs). This cgroup is not theroot cgroupas defined inman 7 cgroups, and thus the cgroups v2 "no internal processes" rule that is mentioned on the same man page applies.As a result, the "container-root-cgroup" contains member processes and cannot enable domain controllers in cgroup.subtree_control. This breaks the delegation of CPU, memory, I/O, and pids controllers to child cgroups.
Consequences in more details
The
cgroupsservice effectively starts “successfully”, but the controllers are not enabled.During the boot process, errors from init.d/cgroups.in are clearly visible when it tries to write to cgroup.subtree_control:
The failing operation is effectively (see
init.d/cgroups.inline 80):Because the root cgroup contains member processes, the kernel rejects this with Device or resource busy.
OpenRC resource limits do not work correctly under this hierarchy.
Nested runtimes such as Docker can still create cgroup directories and start containers, but Docker resource accounting is incomplete or empty: docker stats reports zeros for CPU, memory, pids and block I/O.
The same problem and possible workaround were reported here:
https://discuss.linuxcontainers.org/t/enabling-root-cgroup-subtree-control-with-alpine-linux-containers/26515