libct/cgroups: rm GetClosestMountpointAncestor

The function GetClosestMountpointAncestor is not very efficient,
does not really belong to cgroup package, and is only used once
(from fs/cpuset.go).

Remove it, replacing with the implementation based on moby/sys/mountinfo
parser.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This commit is contained in:
Kir Kolyshkin 2020-05-13 17:32:06 -07:00
parent f160352682
commit 2db3240f35
3 changed files with 24 additions and 59 deletions

View File

@ -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
}

View File

@ -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 {

View File

@ -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