-
Notifications
You must be signed in to change notification settings - Fork 141
/
linux_cgroups_cpus.go
133 lines (109 loc) · 3.3 KB
/
linux_cgroups_cpus.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package main
import (
"fmt"
"os"
"path/filepath"
"runtime"
"github.com/mndrix/tap-go"
"github.com/opencontainers/runtime-tools/cgroups"
"github.com/opencontainers/runtime-tools/validation/util"
)
const (
defaultRealtimePeriod uint64 = 1000000
defaultRealtimeRuntime int64 = 950000
)
func testCPUCgroups() error {
t := tap.New()
t.Header(0)
defer t.AutoPlan()
CPUrange := fmt.Sprintf("0-%d", runtime.NumCPU()-1)
// Test with different combinations of values.
// NOTE: most systems have only one memory node (mems=="0"), so we cannot
// simply test with multiple values of mems.
cases := []struct {
shares uint64
period uint64
quota int64
cpus string
mems string
}{
{1024, 100000, 50000, "0", "0"},
{1024, 100000, 50000, CPUrange, "0"},
{1024, 100000, 200000, "0", "0"},
{1024, 100000, 200000, CPUrange, "0"},
{1024, 500000, 50000, "0", "0"},
{1024, 500000, 50000, CPUrange, "0"},
{1024, 500000, 200000, "0", "0"},
{1024, 500000, 200000, CPUrange, "0"},
{2048, 100000, 50000, "0", "0"},
{2048, 100000, 50000, CPUrange, "0"},
{2048, 100000, 200000, "0", "0"},
{2048, 100000, 200000, CPUrange, "0"},
{2048, 500000, 50000, "0", "0"},
{2048, 500000, 50000, CPUrange, "0"},
{2048, 500000, 200000, "0", "0"},
{2048, 500000, 200000, CPUrange, "0"},
}
for _, c := range cases {
g, err := util.GetDefaultGenerator()
if err != nil {
return fmt.Errorf("cannot get default config from generator: %v", err)
}
g.SetLinuxCgroupsPath(cgroups.AbsCgroupPath)
if c.shares > 0 {
g.SetLinuxResourcesCPUShares(c.shares)
}
if c.period > 0 {
g.SetLinuxResourcesCPUPeriod(c.period)
}
if c.quota > 0 {
g.SetLinuxResourcesCPUQuota(c.quota)
}
if c.cpus != "" {
g.SetLinuxResourcesCPUCpus(c.cpus)
}
if c.mems != "" {
g.SetLinuxResourcesCPUMems(c.mems)
}
// NOTE: On most systems where CONFIG_RT_GROUP & CONFIG_RT_GROUP_SCHED are not enabled,
// the following tests will fail, because sysfs knobs like
// /sys/fs/cgroup/cpu,cpuacct/cpu.rt_{period,runtime}_us do not exist.
// So we need to check if the sysfs knobs exist before setting the variables.
if _, err := os.Stat(filepath.Join(util.CPUCgroupPrefix, "cpu.rt_period_us")); !os.IsNotExist(err) {
g.SetLinuxResourcesCPURealtimePeriod(defaultRealtimePeriod)
}
if _, err := os.Stat(filepath.Join(util.CPUCgroupPrefix, "cpu.rt_runtime_us")); !os.IsNotExist(err) {
g.SetLinuxResourcesCPURealtimeRuntime(defaultRealtimeRuntime)
}
if err := util.RuntimeOutsideValidate(g, t, util.ValidateLinuxResourcesCPU); err != nil {
return fmt.Errorf("cannot validate CPU cgroups: %v", err)
}
}
return nil
}
func testEmptyCPU() error {
t := tap.New()
t.Header(0)
defer t.AutoPlan()
g, err := util.GetDefaultGenerator()
if err != nil {
return fmt.Errorf("cannot get default config from generator: %v", err)
}
g.InitConfigLinuxResourcesCPU()
g.SetLinuxCgroupsPath(cgroups.AbsCgroupPath)
if err := util.RuntimeOutsideValidate(g, t, util.ValidateLinuxResourcesCPUEmpty); err != nil {
return fmt.Errorf("cannot validate empty CPU cgroups: %v", err)
}
return nil
}
func main() {
if "linux" != runtime.GOOS {
util.Fatal(fmt.Errorf("linux-specific cgroup test"))
}
if err := testCPUCgroups(); err != nil {
util.Fatal(err)
}
if err := testEmptyCPU(); err != nil {
util.Fatal(err)
}
}