libct/cg/fs.getCgroupRoot: reuse (cached) cgroup mountinfo
Drop the custom mountinfo parser, reuse the cgroups.GetCgroupMounts()
to get the cgroup root. Faster, and much less code.
package fs
import (
- "bufio"
"fmt"
"os"
"path/filepath"
- "strings"
"sync"
"github.com/opencontainers/runc/libcontainer/cgroups"
@@ -133,46 +131,19 @@ func getCgroupRoot() (string, error) {
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")
+ // slow path: parse mountinfo
+ mi, err := cgroups.GetCgroupMounts(false)
if err != nil {
return "", err
}
- defer f.Close()
-
- var root string
- scanner := bufio.NewScanner(f)
- for scanner.Scan() {
- text := scanner.Text()
- fields := strings.Split(text, " ")
- // Safe as mountinfo encodes mountpoints with spaces as \040.
- index := strings.Index(text, " - ")
- postSeparatorFields := strings.Fields(text[index+3:])
- numPostFields := len(postSeparatorFields)
-
- // This is an error as we can't detect if the mount is for "cgroup"
- if numPostFields == 0 {
- return "", fmt.Errorf("mountinfo: found no fields post '-' in %q", text)
- }
-
- if postSeparatorFields[0] == "cgroup" {
- // Check that the mount is properly formatted.
- if numPostFields < 3 {
- return "", fmt.Errorf("Error found less than 3 fields post '-' in %q", text)
- }
-
- root = filepath.Dir(fields[4])
- break
- }
- }
- if err := scanner.Err(); err != nil {
- return "", err
- }
- if root == "" {
+ if len(mi) < 1 {
return "", errors.New("no cgroup mount found in mountinfo")
}
+ // Get the first cgroup mount (e.g. "/sys/fs/cgroup/memory"),
+ // use its parent directory.
+ root := filepath.Dir(mi[0].Mountpoint)
+
if _, err := os.Stat(root); err != nil {
return "", err
}
