forked from shuveb/containers-the-hard-way
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cgroups.go
103 lines (86 loc) · 3.03 KB
/
cgroups.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
package main
import (
"fmt"
"io/ioutil"
"os"
"runtime"
"strconv"
)
func createCGroups(containerID string, createCGroupDirs bool) {
cgroups := []string{"/sys/fs/cgroup/memory/gocker/" + containerID,
"/sys/fs/cgroup/pids/gocker/" + containerID,
"/sys/fs/cgroup/cpu/gocker/" + containerID}
if createCGroupDirs {
doOrDieWithMsg(createDirsIfDontExist(cgroups),
"Unable to create cgroup directories")
}
for _, cgroupDir := range cgroups {
doOrDieWithMsg(ioutil.WriteFile(cgroupDir + "/notify_on_release", []byte("1"), 0700),
"Unable to write to cgroup notification file")
doOrDieWithMsg(ioutil.WriteFile(cgroupDir + "/cgroup.procs",
[]byte(strconv.Itoa(os.Getpid())), 0700), "Unable to write to cgroup procs file")
}
}
func removeCGroups(containerID string) {
cgroups := []string{"/sys/fs/cgroup/memory/gocker/" + containerID,
"/sys/fs/cgroup/pids/gocker/" + containerID,
"/sys/fs/cgroup/cpu/gocker/" + containerID}
for _, cgroupDir := range cgroups {
doOrDieWithMsg(os.Remove(cgroupDir), "Unable to remove cgroup dir")
}
}
func setMemoryLimit(containerID string, limitMB int, swapLimitInMB int) {
memFilePath := "/sys/fs/cgroup/memory/gocker/" + containerID +
"/memory.limit_in_bytes"
swapFilePath := "/sys/fs/cgroup/memory/gocker/" + containerID +
"/memory.memsw.limit_in_bytes"
doOrDieWithMsg(ioutil.WriteFile(memFilePath,
[]byte(strconv.Itoa(limitMB*1024*1024)), 0644),
"Unable to write memory limit")
/*
memory.memsw.limit_in_bytes contains the total amount of memory the
control group can consume: this includes both swap and RAM.
If if memory.limit_in_bytes is specified but memory.memsw.limit_in_bytes
is left untouched, processes in the control group will continue to
consume swap space.
*/
if swapLimitInMB >= 0 {
doOrDieWithMsg(ioutil.WriteFile(swapFilePath,
[]byte(strconv.Itoa((limitMB*1024*1024)+(swapLimitInMB*1024*1024))),
0644), "Unable to write memory limit")
}
}
func setCpuLimit(containerID string, limit float64) {
cfsPeriodPath := "/sys/fs/cgroup/cpu/gocker/" + containerID +
"/cpu.cfs_period_us"
cfsQuotaPath := "/sys/fs/cgroup/cpu/gocker/" + containerID +
"/cpu.cfs_quota_us"
if limit > float64(runtime.NumCPU()) {
fmt.Printf("Ignoring attempt to set CPU quota to great than number of available CPUs")
return
}
doOrDieWithMsg(ioutil.WriteFile(cfsPeriodPath,
[]byte(strconv.Itoa(1000000)), 0644),
"Unable to write CFS period")
doOrDieWithMsg(ioutil.WriteFile(cfsQuotaPath,
[]byte(strconv.Itoa(int(1000000 * limit))), 0644),
"Unable to write CFS period")
}
func setPidsLimit(containerID string, limit int) {
maxProcsPath := "/sys/fs/cgroup/pids/gocker/" + containerID +
"/pids.max"
doOrDieWithMsg(ioutil.WriteFile(maxProcsPath,
[]byte(strconv.Itoa(limit)), 0644),
"Unable to write pids limit")
}
func configureCGroups(containerID string, mem int, swap int, pids int, cpus float64) {
if mem > 0 {
setMemoryLimit(containerID, mem, swap)
}
if cpus > 0 {
setCpuLimit(containerID, cpus)
}
if pids > 0 {
setPidsLimit(containerID, pids)
}
}