Skip to content

Commit e8a4323

Browse files
author
Kazuyoshi Kato
authored
Merge pull request #231 from jellor/main
Support to handle more than 4 fields in cpuacct.stat
2 parents 04ebfd6 + 037a7c5 commit e8a4323

2 files changed

Lines changed: 87 additions & 13 deletions

File tree

cpuacct.go

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717
package cgroups
1818

1919
import (
20+
"bufio"
2021
"fmt"
2122
"io/ioutil"
23+
"os"
2224
"path/filepath"
2325
"strconv"
2426
"strings"
@@ -86,36 +88,41 @@ func (c *cpuacctController) percpuUsage(path string) ([]uint64, error) {
8688

8789
func (c *cpuacctController) getUsage(path string) (user uint64, kernel uint64, err error) {
8890
statPath := filepath.Join(c.Path(path), "cpuacct.stat")
89-
data, err := ioutil.ReadFile(statPath)
91+
f, err := os.Open(statPath)
9092
if err != nil {
9193
return 0, 0, err
9294
}
93-
fields := strings.Fields(string(data))
94-
if len(fields) != 4 {
95-
return 0, 0, fmt.Errorf("%q is expected to have 4 fields", statPath)
95+
defer f.Close()
96+
var (
97+
raw = make(map[string]uint64)
98+
sc = bufio.NewScanner(f)
99+
)
100+
for sc.Scan() {
101+
key, v, err := parseKV(sc.Text())
102+
if err != nil {
103+
return 0, 0, err
104+
}
105+
raw[key] = v
106+
}
107+
if err := sc.Err(); err != nil {
108+
return 0, 0, err
96109
}
97110
for _, t := range []struct {
98-
index int
99111
name string
100112
value *uint64
101113
}{
102114
{
103-
index: 0,
104115
name: "user",
105116
value: &user,
106117
},
107118
{
108-
index: 2,
109119
name: "system",
110120
value: &kernel,
111121
},
112122
} {
113-
if fields[t.index] != t.name {
114-
return 0, 0, fmt.Errorf("expected field %q but found %q in %q", t.name, fields[t.index], statPath)
115-
}
116-
v, err := strconv.ParseUint(fields[t.index+1], 10, 64)
117-
if err != nil {
118-
return 0, 0, err
123+
v, ok := raw[t.name]
124+
if !ok {
125+
return 0, 0, fmt.Errorf("expected field %q but not found in %q", t.name, statPath)
119126
}
120127
*t.value = v
121128
}

cpuacct_test.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
Copyright The containerd Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package cgroups
18+
19+
import (
20+
"io/ioutil"
21+
"os"
22+
"path/filepath"
23+
"testing"
24+
)
25+
26+
const cpuacctStatData = `user 1
27+
system 2
28+
sched_delay 3
29+
`
30+
31+
func TestGetUsage(t *testing.T) {
32+
mock, err := newMock()
33+
if err != nil {
34+
t.Fatal(err)
35+
}
36+
defer mock.delete()
37+
cpuacct := NewCpuacct(mock.root)
38+
if cpuacct == nil {
39+
t.Fatal("cpuacct is nil")
40+
}
41+
err = os.Mkdir(filepath.Join(mock.root, string(Cpuacct), "test"), defaultDirPerm)
42+
if err != nil {
43+
t.Fatal(err)
44+
}
45+
current := filepath.Join(mock.root, string(Cpuacct), "test", "cpuacct.stat")
46+
if err = ioutil.WriteFile(
47+
current,
48+
[]byte(cpuacctStatData),
49+
defaultFilePerm,
50+
); err != nil {
51+
t.Fatal(err)
52+
}
53+
user, kernel, err := cpuacct.getUsage("test")
54+
if err != nil {
55+
t.Fatalf("can't get usage: %v", err)
56+
}
57+
index := []uint64{
58+
user,
59+
kernel,
60+
}
61+
for i, v := range index {
62+
expected := ((uint64(i) + 1) * nanosecondsInSecond) / clockTicks
63+
if v != expected {
64+
t.Errorf("expected value at index %d to be %d but received %d", i, expected, v)
65+
}
66+
}
67+
}

0 commit comments

Comments
 (0)