Comment 18 for bug 1933128

Revision history for this message
Maciej Borzecki (maciek-borzecki) wrote :

I did a bit more digging. When starting snap-confine will prepare and capture the mount namespace of a snap.

In the process it does a recursive bind mount of /sys inside the new mount namespace of a snap (MS_BIND|MS_REC), and then recursively change the propagation to slave (MS_REC|MS_SLAVE). This should /sys/fs/cgroup/freezer appear later in the parent namespace, it should also appear in the snap mount namespace.

On 20.04 VM, findmnt -o +PROPAGATION indicates that /sys/fs/cgroup is a mount point of tmpfs, with propagation set to shared:
/sys/fs/cgroup tmpfs tmpfs ro,nosuid,nodev,noexec,mode=755 shared

Thus in the snap mount namespace it becomes:
/sys/fs/cgroup tmpfs tmpfs ro,nosuid,nodev,noexec,mode=755 private,slave

However, inside the LXD container, it is already private (so mount and unmount events do not propagate):
/sys/fs/cgroup tmpfs tmpfs ro,nosuid,nodev,noexec,mode=755,uid=1000000,gid=1000000 private

Inside the snap mount ns is then:
/sys/fs/cgroup tmpfs tmpfs ro,nosuid,nodev,noexec,mode=755,uid=1000000,gid=1000000 private

As trying to change the propagation of a private mount has no effect. So even if freezer is mounted later it will not become visible.

That state of mount namespace is captured and reused for subsequent attempts to start the snap. Since the freezer is unavailable, s-c cannot setup the cgroup and thus fails.

This code has not been changed since late 2018/early 2019, so some other change must have made this behavior visible just now. It still is unclear why the freezer is unavailable at the time the snap is started, perhaps the system is still booting (as much as containers can boot) but the shell is already acessible and it is possible to try to `snap install`.