Parse cgroupv2 path only once while scanning mountinfo.

Some systems have multiple cgroup2 mounts. In these cases, loadPathsHelper
incorrectly attempts to overwrite `paths[cgroup2Key]` with an already
processed value, which causes an error in filepath.Rel.

Fixes #7334

PiperOrigin-RevId: 438583982
This commit is contained in:
Lucas Manning
2022-03-31 09:17:06 -07:00
committed by gVisor bot
parent fcd82c8ebf
commit d9cffce328
2 changed files with 22 additions and 5 deletions
+8 -4
View File
@@ -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
}
}
+14 -1
View File
@@ -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)