-
Notifications
You must be signed in to change notification settings - Fork 111
/
Copy pathexec_linux.go
110 lines (101 loc) · 2.74 KB
/
exec_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
108
109
110
/*
* Copyright 1999-2020 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package exec
import (
"errors"
"fmt"
"github.com/containerd/cgroups"
"os"
)
func PidPath(pid int) cgroups.Path {
p := fmt.Sprintf("/proc/%d/cgroup", pid)
paths, err := cgroups.ParseCgroupFile(p)
if err != nil {
return func(_ cgroups.Name) (string, error) {
return "", fmt.Errorf("failed to parse cgroup file %s: %s", p, err.Error())
}
}
return func(name cgroups.Name) (string, error) {
root, ok := paths[string(name)]
if !ok {
if root, ok = paths["name="+string(name)]; !ok {
return "", errors.New("controller is not supported")
}
}
return root, nil
}
}
func Hierarchy(root string) func() ([]cgroups.Subsystem, error) {
return func() ([]cgroups.Subsystem, error) {
subsystems, err := defaults(root)
if err != nil {
return nil, err
}
var enabled []cgroups.Subsystem
for _, s := range pathers(subsystems) {
// check and remove the default groups that do not exist
if _, err := os.Lstat(s.Path("/")); err == nil {
enabled = append(enabled, s)
}
}
return enabled, nil
}
}
// defaults returns all known groups
func defaults(root string) ([]cgroups.Subsystem, error) {
h, err := cgroups.NewHugetlb(root)
if err != nil && !os.IsNotExist(err) {
return nil, err
}
s := []cgroups.Subsystem{
cgroups.NewNamed(root, "systemd"),
cgroups.NewFreezer(root),
cgroups.NewPids(root),
cgroups.NewNetCls(root),
cgroups.NewNetPrio(root),
cgroups.NewPerfEvent(root),
cgroups.NewCpuset(root),
cgroups.NewCpu(root),
cgroups.NewCpuacct(root),
cgroups.NewMemory(root),
cgroups.NewBlkio(root),
cgroups.NewRdma(root),
}
// only add the devices cgroup if we are not in a user namespace
// because modifications are not allowed
if !cgroups.RunningInUserNS() {
s = append(s, cgroups.NewDevices(root))
}
// add the hugetlb cgroup if error wasn't due to missing hugetlb
// cgroup support on the host
if err == nil {
s = append(s, h)
}
return s, nil
}
type pather interface {
cgroups.Subsystem
Path(path string) string
}
func pathers(subystems []cgroups.Subsystem) []pather {
var out []pather
for _, s := range subystems {
if p, ok := s.(pather); ok {
out = append(out, p)
}
}
return out
}