...
1
16
17 package cgroups
18
19 import (
20 "errors"
21 "fmt"
22 "path/filepath"
23 )
24
25 type Path func(subsystem Name) (string, error)
26
27 func RootPath(subsystem Name) (string, error) {
28 return "/", nil
29 }
30
31
32 func StaticPath(path string) Path {
33 return func(_ Name) (string, error) {
34 return path, nil
35 }
36 }
37
38
39
40 func NestedPath(suffix string) Path {
41 paths, err := ParseCgroupFile("/proc/self/cgroup")
42 if err != nil {
43 return errorPath(err)
44 }
45 return existingPath(paths, suffix)
46 }
47
48
49
50 func PidPath(pid int) Path {
51 p := fmt.Sprintf("/proc/%d/cgroup", pid)
52 paths, err := ParseCgroupFile(p)
53 if err != nil {
54 return errorPath(fmt.Errorf("parse cgroup file %s: %w", p, err))
55 }
56 return existingPath(paths, "")
57 }
58
59
60 var ErrControllerNotActive = errors.New("controller is not supported")
61
62 func existingPath(paths map[string]string, suffix string) Path {
63
64 for n, p := range paths {
65 dest, err := getCgroupDestination(n)
66 if err != nil {
67 return errorPath(err)
68 }
69 rel, err := filepath.Rel(dest, p)
70 if err != nil {
71 return errorPath(err)
72 }
73 if rel == "." {
74 rel = dest
75 }
76 paths[n] = filepath.Join("/", rel)
77 }
78 return func(name Name) (string, error) {
79 root, ok := paths[string(name)]
80 if !ok {
81 if root, ok = paths["name="+string(name)]; !ok {
82 return "", ErrControllerNotActive
83 }
84 }
85 if suffix != "" {
86 return filepath.Join(root, suffix), nil
87 }
88 return root, nil
89 }
90 }
91
92 func subPath(path Path, subName string) Path {
93 return func(name Name) (string, error) {
94 p, err := path(name)
95 if err != nil {
96 return "", err
97 }
98 return filepath.Join(p, subName), nil
99 }
100 }
101
102 func errorPath(err error) Path {
103 return func(_ Name) (string, error) {
104 return "", err
105 }
106 }
107
View as plain text