diff --git a/runsc/cgroup/cgroup.go b/runsc/cgroup/cgroup.go index e7140ea53..0cc6bbfec 100644 --- a/runsc/cgroup/cgroup.go +++ b/runsc/cgroup/cgroup.go @@ -39,7 +39,9 @@ import ( ) const ( - cgroupRoot = "/sys/fs/cgroup" + cgroupRoot = "/sys/fs/cgroup" + cgroupv1FsName = "cgroup" + cgroupv2FsName = "cgroup2" ) var controllers = map[string]controller{ @@ -255,6 +257,7 @@ func loadPathsHelper(cgroup, mountinfo io.Reader, unified bool) (map[string]stri // which don't exist in container, so recover the container paths here by // double-checking with /proc/[pid]/mountinfo mountScanner := bufio.NewScanner(mountinfo) + haveCg2Path := false for mountScanner.Scan() { // Format: ID parent major:minor root mount-point options opt-fields - fs-type source super-options // Example: 39 32 0:34 / /sys/fs/cgroup/devices rw,noexec shared:18 - cgroup cgroup rw,devices @@ -264,7 +267,7 @@ func loadPathsHelper(cgroup, mountinfo io.Reader, unified bool) (map[string]stri continue } switch fields[len(fields)-3] { - case "cgroup": + case cgroupv1FsName: // Cgroup controller type is in the super-options field. superOptions := strings.Split(fields[len(fields)-1], ",") for _, opt := range superOptions { @@ -286,13 +289,14 @@ func loadPathsHelper(cgroup, mountinfo io.Reader, unified bool) (map[string]stri } } } - case "cgroup2": - if cgroupPath, ok := paths[cgroup2Key]; ok { + case cgroupv2FsName: + if cgroupPath, ok := paths[cgroup2Key]; !haveCg2Path && ok { root := fields[3] relCgroupPath, err := filepath.Rel(root, cgroupPath) if err != nil { return nil, err } + haveCg2Path = true paths[cgroup2Key] = relCgroupPath } } diff --git a/runsc/cgroup/cgroup_v2_test.go b/runsc/cgroup/cgroup_v2_test.go index 717a0ae73..f2a8bcc4c 100644 --- a/runsc/cgroup/cgroup_v2_test.go +++ b/runsc/cgroup/cgroup_v2_test.go @@ -26,7 +26,12 @@ import ( "gvisor.dev/gvisor/pkg/test/testutil" ) -var cgroupv2MountInfo = `29 22 0:26 / /sys/fs/cgroup rw shared:4 - cgroup2 cgroup2 rw,seclabel,nsdelegate` +var ( + cgroupv2MountInfo = `29 22 0:26 / /sys/fs/cgroup rw shared:4 - cgroup2 cgroup2 rw,seclabel,nsdelegate` + multipleCg2MountInfo = `34 28 0:29 / /sys/fs/cgroup rw,nosuid,nodev,noexec,relatime shared:8 - cgroup2 cgroup2 rw +1479 28 0:29 / /run/some/module/cgroupv2 rw,relatime shared:650 - cgroup2 none rw +` +) func TestIO(t *testing.T) { for _, tc := range []struct { @@ -149,6 +154,14 @@ func TestLoadPathsCgroupv2(t *testing.T) { "cgroup2": ".", }, }, + { + name: "multiple-cgv2", + cgroups: "0::/system.slice/containerd.service\n", + mountinfo: multipleCg2MountInfo, + want: map[string]string{ + "cgroup2": "system.slice/containerd.service", + }, + }, } { t.Run(tc.name, func(t *testing.T) { r := strings.NewReader(tc.cgroups)