Skip to content

Commit

Permalink
Merge pull request #2507 from kolyshkin/alt-to-2497
Browse files Browse the repository at this point in the history
libct/cgroups/GetCgroupRoot: make it faster
  • Loading branch information
AkihiroSuda authored Jul 31, 2020
2 parents 46243fc + e0c0b0c commit d6f5641
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 0 deletions.
58 changes: 58 additions & 0 deletions libcontainer/cgroups/fs/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,56 @@ func NewManager(cg *configs.Cgroup, paths map[string]string, rootless bool) cgro
var cgroupRootLock sync.Mutex
var cgroupRoot string

const defaultCgroupRoot = "/sys/fs/cgroup"

func tryDefaultCgroupRoot() string {
var st, pst unix.Stat_t

// (1) it should be a directory...
err := unix.Lstat(defaultCgroupRoot, &st)
if err != nil || st.Mode&unix.S_IFDIR == 0 {
return ""
}

// (2) ... and a mount point ...
err = unix.Lstat(filepath.Dir(defaultCgroupRoot), &pst)
if err != nil {
return ""
}

if st.Dev == pst.Dev {
// parent dir has the same dev -- not a mount point
return ""
}

// (3) ... of 'tmpfs' fs type.
var fst unix.Statfs_t
err = unix.Statfs(defaultCgroupRoot, &fst)
if err != nil || fst.Type != unix.TMPFS_MAGIC {
return ""
}

// (4) it should have at least 1 entry ...
dir, err := os.Open(defaultCgroupRoot)
if err != nil {
return ""
}
names, err := dir.Readdirnames(1)
if err != nil {
return ""
}
if len(names) < 1 {
return ""
}
// ... which is a cgroup mount point.
err = unix.Statfs(filepath.Join(defaultCgroupRoot, names[0]), &fst)
if err != nil || fst.Type != unix.CGROUP_SUPER_MAGIC {
return ""
}

return defaultCgroupRoot
}

// Gets the cgroupRoot.
func getCgroupRoot() (string, error) {
cgroupRootLock.Lock()
Expand All @@ -77,6 +127,14 @@ func getCgroupRoot() (string, error) {
return cgroupRoot, nil
}

// fast path
cgroupRoot = tryDefaultCgroupRoot()
if cgroupRoot != "" {
return cgroupRoot, nil
}

// slow path: parse mountinfo, find the first mount where fs=cgroup
// (e.g. "/sys/fs/cgroup/memory"), use its parent.
f, err := os.Open("/proc/self/mountinfo")
if err != nil {
return "", err
Expand Down
13 changes: 13 additions & 0 deletions libcontainer/cgroups/fs/fs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,3 +295,16 @@ func TestInvalidAbsoluteCgroupNameAndParent(t *testing.T) {
t.Errorf("SECURITY: cgroup path() is outside cgroup mountpoint!")
}
}

func TestTryDefaultCgroupRoot(t *testing.T) {
res := tryDefaultCgroupRoot()
exp := defaultCgroupRoot
if cgroups.IsCgroup2UnifiedMode() {
// checking that tryDefaultCgroupRoot does return ""
// in case /sys/fs/cgroup is not cgroup v1 root dir.
exp = ""
}
if res != exp {
t.Errorf("tryDefaultCgroupRoot: want %q, got %q", exp, res)
}
}

0 comments on commit d6f5641

Please sign in to comment.