diff --git a/libcontainer/cgroups/fscommon/utils.go b/libcontainer/cgroups/fscommon/utils.go index 235c98859..db0caded1 100644 --- a/libcontainer/cgroups/fscommon/utils.go +++ b/libcontainer/cgroups/fscommon/utils.go @@ -53,6 +53,26 @@ func ParseKeyValue(t string) (string, uint64, error) { return parts[0], value, nil } +// GetValueByKey reads a key-value pairs from the specified cgroup file, +// and returns a value of the specified key. ParseUint is used for value +// conversion. +func GetValueByKey(path, file, key string) (uint64, error) { + content, err := ReadFile(path, file) + if err != nil { + return 0, err + } + + lines := strings.Split(string(content), "\n") + for _, line := range lines { + arr := strings.Split(line, " ") + if len(arr) == 2 && arr[0] == key { + return ParseUint(arr[1], 10, 64) + } + } + + return 0, nil +} + // GetCgroupParamUint reads a single uint64 value from the specified cgroup file. // If the value read is "max", the math.MaxUint64 is returned. func GetCgroupParamUint(path, file string) (uint64, error) { diff --git a/libcontainer/notify_linux_v2.go b/libcontainer/notify_linux_v2.go index 1d81f38c2..dd0ec290e 100644 --- a/libcontainer/notify_linux_v2.go +++ b/libcontainer/notify_linux_v2.go @@ -4,8 +4,6 @@ package libcontainer import ( "path/filepath" - "strconv" - "strings" "unsafe" "github.com/opencontainers/runc/libcontainer/cgroups/fscommon" @@ -14,22 +12,6 @@ import ( "golang.org/x/sys/unix" ) -func getValueFromCgroup(path, file, key string) (int, error) { - content, err := fscommon.ReadFile(path, file) - if err != nil { - return 0, err - } - - lines := strings.Split(string(content), "\n") - for _, line := range lines { - arr := strings.Split(line, " ") - if len(arr) == 2 && arr[0] == key { - return strconv.Atoi(arr[1]) - } - } - return 0, nil -} - func registerMemoryEventV2(cgDir, evName, cgEvName string) (<-chan struct{}, error) { fd, err := unix.InotifyInit() if err != nil { @@ -77,12 +59,12 @@ func registerMemoryEventV2(cgDir, evName, cgEvName string) (<-chan struct{}, err } switch int(rawEvent.Wd) { case evFd: - oom, err := getValueFromCgroup(cgDir, evName, "oom_kill") + oom, err := fscommon.GetValueByKey(cgDir, evName, "oom_kill") if err != nil || oom > 0 { ch <- struct{}{} } case cgFd: - pids, err := getValueFromCgroup(cgDir, cgEvName, "populated") + pids, err := fscommon.GetValueByKey(cgDir, cgEvName, "populated") if err != nil || pids == 0 { return }