Snapd fails on systems without freezer cgroups (CgroupV2)


#1

As we’re preparing support for full CGroupV2 on LXD, we tried installing the lxd snap on such a system.

This resulted in:

root@djanet:~# snap install lxd
error: cannot perform the following tasks:
- Run install hook of "lxd" snap if present (run hook "install": cannot open freezer cgroup (/sys/fs/cgroup/freezer): No such file or directory)

I then tried to install the simple hello-world snap, which resulted in:

root@djanet:~# snap install hello-world
hello-world 6.3 from Canonical✓ installed
root@djanet:~# hello-world
cannot open freezer cgroup (/sys/fs/cgroup/freezer): No such file or directory

So it looks like snapd is very much assuming that the freezer cgroup will always be present and will always be mounted at /sys/fs/cgroup/freezer. This sadly isn’t true with a CGroupV2 system, on which the freezer cgroup simply doesn’t exist at all.

At this point in time, there are no equivalent to the freezer cgroup controller, it wasn’t ported to V2 due to it being considered of poor quality and reliability in V1. I’m hoping this will change as its feature is genuinely useful and something we use too, however it seems likely that Linux distributions may begin the V2 switch prior to this happening.

In order to reproduce the behavior above, boot your system with this added to the boot command line:

systemd.unified_cgroup_hierarchy=true

#2

+1

Been trying to use the non-hybrid cgroupv2 mode to enable resource limits for user slices (e.g. constraining google chrome processes in the amount of memory they can consume) and ran into the same problem - snaps stopped working without the freezer cgroup controller.

https://www.freedesktop.org/software/systemd/man/systemd.resource-control.html#Memory
Legacy control group hierarchy (see cgroups.txt), also called cgroup-v1, doesn't allow safe delegation of controllers to unprivileged processes. If the system uses the legacy control group hierarchy, ***resource control is disabled for systemd user instance***, see systemd(1).