Rework ParseCgroupFile

Currently we parse /proc/self/cgroup for each controller.
It's ineffective.

Signed-off-by: Andrey Vagin <avagin@openvz.org>
This commit is contained in:
Andrey Vagin 2015-09-10 11:06:45 +03:00
parent 5731a045fe
commit e49c1dc559
2 changed files with 33 additions and 29 deletions

View File

@ -3,27 +3,16 @@
package cgroups
import (
"bytes"
"testing"
)
const (
cgroupsContents = `11:hugetlb:/
10:perf_event:/
9:blkio:/
8:net_cls:/
7:freezer:/
6:devices:/
5:memory:/
4:cpuacct,cpu:/
3:cpuset:/
2:name=systemd:/user.slice/user-1000.slice/session-16.scope`
)
func TestParseCgroups(t *testing.T) {
r := bytes.NewBuffer([]byte(cgroupsContents))
_, err := ParseCgroupFile("blkio", r)
cgroups, err := ParseCgroupFile("/proc/self/cgroup")
if err != nil {
t.Fatal(err)
}
if _, ok := cgroups["cpu"]; !ok {
t.Fail()
}
}

View File

@ -5,7 +5,6 @@ package cgroups
import (
"bufio"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
@ -170,23 +169,22 @@ func GetAllSubsystems() ([]string, error) {
// Returns the relative path to the cgroup docker is running in.
func GetThisCgroupDir(subsystem string) (string, error) {
f, err := os.Open("/proc/self/cgroup")
cgroups, err := ParseCgroupFile("/proc/self/cgroup")
if err != nil {
return "", err
}
defer f.Close()
return ParseCgroupFile(subsystem, f)
return getControllerPath(subsystem, cgroups)
}
func GetInitCgroupDir(subsystem string) (string, error) {
f, err := os.Open("/proc/1/cgroup")
cgroups, err := ParseCgroupFile("/proc/1/cgroup")
if err != nil {
return "", err
}
defer f.Close()
return ParseCgroupFile(subsystem, f)
return getControllerPath(subsystem, cgroups)
}
func ReadProcsFile(dir string) ([]int, error) {
@ -213,23 +211,40 @@ func ReadProcsFile(dir string) ([]int, error) {
return out, nil
}
func ParseCgroupFile(subsystem string, r io.Reader) (string, error) {
s := bufio.NewScanner(r)
func ParseCgroupFile(path string) (map[string]string, error) {
f, err := os.Open(path)
if err != nil {
return nil, err
}
defer f.Close()
s := bufio.NewScanner(f)
cgroups := make(map[string]string)
for s.Scan() {
if err := s.Err(); err != nil {
return "", err
return nil, err
}
text := s.Text()
parts := strings.Split(text, ":")
for _, subs := range strings.Split(parts[1], ",") {
if subs == subsystem || subs == cgroupNamePrefix+subsystem {
return parts[2], nil
}
cgroups[subs] = parts[2]
}
}
return cgroups, nil
}
func getControllerPath(subsystem string, cgroups map[string]string) (string, error) {
if p, ok := cgroups[subsystem]; ok {
return p, nil
}
if p, ok := cgroups[cgroupNamePrefix+subsystem]; ok {
return p, nil
}
return "", NewNotFoundError(subsystem)
}