diff --git a/libcontainer/rootfs_linux.go b/libcontainer/rootfs_linux.go index e4a4df20c78..96a5da2a472 100644 --- a/libcontainer/rootfs_linux.go +++ b/libcontainer/rootfs_linux.go @@ -397,11 +397,13 @@ func mountCgroupV1(m mountEntry, c *mountConfig) error { } func mountCgroupV2(m mountEntry, c *mountConfig) error { - err := utils.WithProcfdFile(m.dstFile, func(dstFd string) error { - return mountViaFds(m.Source, nil, m.Destination, dstFd, "cgroup2", uintptr(m.Flags), m.Data) - }) - if err == nil || (!errors.Is(err, unix.EPERM) && !errors.Is(err, unix.EBUSY)) { - return err + if c.cgroupns { + err := utils.WithProcfdFile(m.dstFile, func(dstFd string) error { + return mountViaFds(m.Source, nil, m.Destination, dstFd, "cgroup2", uintptr(m.Flags), m.Data) + }) + if err == nil || (!errors.Is(err, unix.EPERM) && !errors.Is(err, unix.EBUSY)) { + return err + } } // When we are in UserNS but CgroupNS is not unshared, we cannot mount @@ -418,8 +420,14 @@ func mountCgroupV2(m mountEntry, c *mountConfig) error { // rather than the whole /sys/fs/cgroup. bindM.Source = c.cgroup2Path } + if !c.cgroupns { + // With host cgroup namespace, bind-mount the existing cgroup2 + // hierarchy instead of mounting a fresh cgroup2 instance, and detach + // it from host-side propagation. + bindM.PropagationFlags = append(bindM.PropagationFlags, unix.MS_PRIVATE) + } // mountToRootfs() handles remounting for MS_RDONLY. - err = mountToRootfs(c, mountEntry{Mount: bindM}) + err := mountToRootfs(c, mountEntry{Mount: bindM}) if c.rootlessCgroups && errors.Is(err, unix.ENOENT) { // ENOENT (for `src = c.cgroup2Path`) happens when rootless runc is being executed // outside the userns+mountns. diff --git a/tests/integration/mounts.bats b/tests/integration/mounts.bats index 6bab15727a3..ba514d40f16 100644 --- a/tests/integration/mounts.bats +++ b/tests/integration/mounts.bats @@ -163,6 +163,10 @@ test_mount_target() { mv "$old_config" "./config.json" } +function get_cgroup_mount_flags() { + awk '$5 == "/sys/fs/cgroup" {print $10; exit}' /proc/self/mountinfo +} + # https://github.com/opencontainers/runc/issues/3991 @test "runc run [tmpcopyup]" { mkdir -p rootfs/dir1/dir2 @@ -354,7 +358,13 @@ test_mount_target() { @test "runc run [ro /sys/fs/cgroup mounts]" { # Without cgroup namespace. update_config '.linux.namespaces -= [{"type": "cgroup"}]' + # Save the host cgroup mount flags. + CG_MNT=$(get_cgroup_mount_flags) test_ro_cgroup_mount + # Verify that the cgroup mount flags after container creation are the same as before container creation. + if [ "$CG_MNT" != "$(get_cgroup_mount_flags)" ]; then + fail "Host cgroup mount flags changed" + fi } @test "runc run [ro /sys/fs/cgroup mounts + cgroupns]" {