/
cgroups_linux.go
107 lines (94 loc) · 2.22 KB
/
cgroups_linux.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
//go:build linux
// +build linux
package node
import (
"errors"
"os"
"path/filepath"
"sync"
"github.com/containers/common/pkg/cgroups"
libctrcgroups "github.com/opencontainers/runc/libcontainer/cgroups"
)
var (
cgroupHasMemorySwapOnce sync.Once
cgroupHasMemorySwap bool
cgroupHasMemorySwapErr error
cgroupControllerOnce sync.Once
cgroupControllerErr error
cgroupHasHugetlb bool
cgroupHasPid bool
cgroupIsV2Err error
)
func CgroupIsV2() bool {
var cgroupIsV2 bool
cgroupIsV2, cgroupIsV2Err = cgroups.IsCgroup2UnifiedMode()
return cgroupIsV2
}
// CgroupHasMemorySwap returns whether the memory swap controller is present
func CgroupHasMemorySwap() bool {
cgroupHasMemorySwapOnce.Do(func() {
if CgroupIsV2() {
cg, err := libctrcgroups.ParseCgroupFile("/proc/self/cgroup")
if err != nil {
cgroupHasMemorySwapErr = err
cgroupHasMemorySwap = false
return
}
memSwap := filepath.Join("/sys/fs/cgroup", cg[""], "memory.swap.current")
if _, err := os.Stat(memSwap); err != nil {
cgroupHasMemorySwap = false
return
}
cgroupHasMemorySwap = true
return
}
_, err := os.Stat("/sys/fs/cgroup/memory/memory.memsw.limit_in_bytes")
if err != nil {
cgroupHasMemorySwapErr = errors.New("node not configured with memory swap")
cgroupHasMemorySwap = false
return
}
cgroupHasMemorySwap = true
})
return cgroupHasMemorySwap
}
// CgroupHasHugetlb returns whether the hugetlb controller is present
func CgroupHasHugetlb() bool {
checkRelevantControllers()
return cgroupHasHugetlb
}
// CgroupHasPid returns whether the pid controller is present
func CgroupHasPid() bool {
checkRelevantControllers()
return cgroupHasPid
}
func checkRelevantControllers() {
cgroupControllerOnce.Do(func() {
relevantControllers := []struct {
name string
enabled *bool
}{
{
name: "pids",
enabled: &cgroupHasPid,
},
{
name: "hugetlb",
enabled: &cgroupHasHugetlb,
},
}
ctrls, err := libctrcgroups.GetAllSubsystems()
if err != nil {
cgroupControllerErr = err
return
}
for _, toCheck := range relevantControllers {
for _, ctrl := range ctrls {
if ctrl == toCheck.name {
*toCheck.enabled = true
break
}
}
}
})
}