diff --git a/libcontainer/cgroups/fs/cpuset.go b/libcontainer/cgroups/fs/cpuset.go index a0c3c5f68..6081abd1a 100644 --- a/libcontainer/cgroups/fs/cpuset.go +++ b/libcontainer/cgroups/fs/cpuset.go @@ -9,6 +9,7 @@ import ( "os" "path/filepath" + "github.com/moby/sys/mountinfo" "github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/cgroups/fscommon" "github.com/opencontainers/runc/libcontainer/configs" @@ -52,17 +53,35 @@ func (s *CpusetGroup) GetStats(path string, stats *cgroups.Stats) error { return nil } +// Get the source mount point of directory passed in as argument. +func getMount(dir string) (string, error) { + mi, err := mountinfo.GetMounts(mountinfo.ParentsFilter(dir)) + if err != nil { + return "", err + } + if len(mi) < 1 { + return "", fmt.Errorf("Can't find mount point of %s", dir) + } + + // find the longest mount point + var idx, maxlen int + for i := range mi { + if len(mi[i].Mountpoint) > maxlen { + maxlen = len(mi[i].Mountpoint) + idx = i + } + } + + return mi[idx].Mountpoint, nil +} + func (s *CpusetGroup) ApplyDir(dir string, cgroup *configs.Cgroup, pid int) error { // This might happen if we have no cpuset cgroup mounted. // Just do nothing and don't fail. if dir == "" { return nil } - mountInfo, err := ioutil.ReadFile("/proc/self/mountinfo") - if err != nil { - return err - } - root, err := cgroups.GetClosestMountpointAncestor(dir, string(mountInfo)) + root, err := getMount(dir) if err != nil { return err } diff --git a/libcontainer/cgroups/utils.go b/libcontainer/cgroups/utils.go index 9859557a7..3b6ef4af9 100644 --- a/libcontainer/cgroups/utils.go +++ b/libcontainer/cgroups/utils.go @@ -16,7 +16,6 @@ import ( "time" units "github.com/docker/go-units" - "github.com/moby/sys/mountinfo" "golang.org/x/sys/unix" ) @@ -127,27 +126,6 @@ func isSubsystemAvailable(subsystem string) bool { return avail } -func GetClosestMountpointAncestor(dir, data string) (string, error) { - mi, err := mountinfo.GetMountsFromReader(strings.NewReader(data), mountinfo.ParentsFilter(dir)) - if err != nil { - return "", err - } - if len(mi) < 1 { - return "", err - } - - // find the longest mount point - var idx, maxlen int - for i := range mi { - if len(mi[i].Mountpoint) > maxlen { - maxlen = len(mi[i].Mountpoint) - idx = i - } - } - - return mi[idx].Mountpoint, nil -} - func FindCgroupMountpointDir() (string, error) { f, err := os.Open("/proc/self/mountinfo") if err != nil { diff --git a/libcontainer/cgroups/utils_test.go b/libcontainer/cgroups/utils_test.go index a3be72443..f4d6b4e7e 100644 --- a/libcontainer/cgroups/utils_test.go +++ b/libcontainer/cgroups/utils_test.go @@ -373,38 +373,6 @@ func TestIgnoreCgroup2Mount(t *testing.T) { } } -func TestGetClosestMountpointAncestor(t *testing.T) { - const fakeMountInfo = `18 24 0:17 / /sys rw,nosuid,nodev,noexec,relatime - sysfs sysfs rw -100 99 1:31 / /foo/bar rw,relatime - fake fake rw,fake -100 99 1:31 / /foo/bar/baz2 rw,relatime - fake fake rw,fake -100 99 1:31 / /foo/bar/baz rw,relatime - fake fake rw,fake -100 99 1:31 / /foo/bar/bazza rw,relatime - fake fake rw,fake -100 99 1:31 / /foo/bar/baz3 rw,relatime - fake fake rw,fake -100 99 1:31 / /foo rw,relatime - fake fake rw,fake -100 99 1:31 / /unrelated rw,relatime - fake fake rw,fake -100 99 1:31 / / rw,relatime - fake fake rw,fake` - - testCases := []struct { - input string - output string - }{ - {input: "/foo/bar/baz/a/b/c", output: "/foo/bar/baz"}, - {input: "/foo/bar/baz", output: "/foo/bar/baz"}, - {input: "/foo/bar/bazza", output: "/foo/bar/bazza"}, - {input: "/a/b/c/d", output: "/"}, - } - - for _, c := range testCases { - mountpoint, err := GetClosestMountpointAncestor(c.input, fakeMountInfo) - if err != nil { - t.Fatal(err) - } - if mountpoint != c.output { - t.Errorf("expected %s, got %s", c.output, mountpoint) - } - } -} - func TestFindCgroupMountpointAndRoot(t *testing.T) { fakeMountInfo := ` 35 27 0:29 / /foo rw,nosuid,nodev,noexec,relatime shared:18 - cgroup cgroup rw,devices