Merge pull request #904 from euank/fix-cgroup-parsing-err
cgroups: Fix issue if cgroup path contains :
This commit is contained in:
commit
42dfd60643
|
@ -262,6 +262,8 @@ func readProcsFile(dir string) ([]int, error) {
|
||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ParseCgroupFile parses the given cgroup file, typically from
|
||||||
|
// /proc/<pid>/cgroup, into a map of subgroups to cgroup names.
|
||||||
func ParseCgroupFile(path string) (map[string]string, error) {
|
func ParseCgroupFile(path string) (map[string]string, error) {
|
||||||
f, err := os.Open(path)
|
f, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -269,7 +271,12 @@ func ParseCgroupFile(path string) (map[string]string, error) {
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
s := bufio.NewScanner(f)
|
return parseCgroupFromReader(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
// helper function for ParseCgroupFile to make testing easier
|
||||||
|
func parseCgroupFromReader(r io.Reader) (map[string]string, error) {
|
||||||
|
s := bufio.NewScanner(r)
|
||||||
cgroups := make(map[string]string)
|
cgroups := make(map[string]string)
|
||||||
|
|
||||||
for s.Scan() {
|
for s.Scan() {
|
||||||
|
@ -278,7 +285,16 @@ func ParseCgroupFile(path string) (map[string]string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
text := s.Text()
|
text := s.Text()
|
||||||
parts := strings.Split(text, ":")
|
// from cgroups(7):
|
||||||
|
// /proc/[pid]/cgroup
|
||||||
|
// ...
|
||||||
|
// For each cgroup hierarchy ... there is one entry
|
||||||
|
// containing three colon-separated fields of the form:
|
||||||
|
// hierarchy-ID:subsystem-list:cgroup-path
|
||||||
|
parts := strings.SplitN(text, ":", 3)
|
||||||
|
if len(parts) < 3 {
|
||||||
|
return nil, fmt.Errorf("invalid cgroup entry: must contain at least two colons: %v", text)
|
||||||
|
}
|
||||||
|
|
||||||
for _, subs := range strings.Split(parts[1], ",") {
|
for _, subs := range strings.Split(parts[1], ",") {
|
||||||
cgroups[subs] = parts[2]
|
cgroups[subs] = parts[2]
|
||||||
|
|
|
@ -4,6 +4,8 @@ package cgroups
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
@ -190,3 +192,56 @@ func BenchmarkGetCgroupMounts(b *testing.B) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestParseCgroupString(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
input string
|
||||||
|
expectedError error
|
||||||
|
expectedOutput map[string]string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
// Taken from a CoreOS instance running systemd 225 with CPU/Mem
|
||||||
|
// accounting enabled in systemd
|
||||||
|
input: `9:blkio:/
|
||||||
|
8:freezer:/
|
||||||
|
7:perf_event:/
|
||||||
|
6:devices:/system.slice/system-sshd.slice
|
||||||
|
5:cpuset:/
|
||||||
|
4:cpu,cpuacct:/system.slice/system-sshd.slice/sshd@126-10.240.0.15:22-xxx.yyy.zzz.aaa:33678.service
|
||||||
|
3:net_cls,net_prio:/
|
||||||
|
2:memory:/system.slice/system-sshd.slice/sshd@126-10.240.0.15:22-xxx.yyy.zzz.aaa:33678.service
|
||||||
|
1:name=systemd:/system.slice/system-sshd.slice/sshd@126-10.240.0.15:22-xxx.yyy.zzz.aaa:33678.service`,
|
||||||
|
expectedOutput: map[string]string{
|
||||||
|
"name=systemd": "/system.slice/system-sshd.slice/sshd@126-10.240.0.15:22-xxx.yyy.zzz.aaa:33678.service",
|
||||||
|
"blkio": "/",
|
||||||
|
"freezer": "/",
|
||||||
|
"perf_event": "/",
|
||||||
|
"devices": "/system.slice/system-sshd.slice",
|
||||||
|
"cpuset": "/",
|
||||||
|
"cpu": "/system.slice/system-sshd.slice/sshd@126-10.240.0.15:22-xxx.yyy.zzz.aaa:33678.service",
|
||||||
|
"cpuacct": "/system.slice/system-sshd.slice/sshd@126-10.240.0.15:22-xxx.yyy.zzz.aaa:33678.service",
|
||||||
|
"net_cls": "/",
|
||||||
|
"net_prio": "/",
|
||||||
|
"memory": "/system.slice/system-sshd.slice/sshd@126-10.240.0.15:22-xxx.yyy.zzz.aaa:33678.service",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: `malformed input`,
|
||||||
|
expectedError: fmt.Errorf(`invalid cgroup entry: must contain at least two colons: malformed input`),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for ndx, testCase := range testCases {
|
||||||
|
out, err := parseCgroupFromReader(strings.NewReader(testCase.input))
|
||||||
|
if err != nil {
|
||||||
|
if testCase.expectedError == nil || testCase.expectedError.Error() != err.Error() {
|
||||||
|
t.Errorf("%v: expected error %v, got error %v", ndx, testCase.expectedError, err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if !reflect.DeepEqual(testCase.expectedOutput, out) {
|
||||||
|
t.Errorf("%v: expected output %v, got error %v", ndx, testCase.expectedOutput, out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue