...
1 package linux
2
3 import (
4 "fmt"
5 "os"
6 "path/filepath"
7 "strconv"
8 "strings"
9 "sync"
10
11 "golang.conradwood.net/go-easyops/errors"
12 "golang.conradwood.net/go-easyops/utils"
13 )
14
15 var (
16 cgroup_check_lock sync.Mutex
17 )
18
19 func MyCgroup() (string, error) {
20 b, err := utils.ReadFile("/proc/self/cgroup")
21 if err != nil {
22 return "", errors.Wrap(err)
23 }
24 s := string(b)
25 idx := strings.Index(s, "/")
26 if idx == -1 {
27 return "", errors.Errorf("odd /proc/self/cgroup line: \"%s\"", s)
28 }
29 res := s[idx:]
30 return res, nil
31
32 }
33
34
35 func CreateStandardAdjacentCgroup() (string, error) {
36 myc, err := MyCgroup()
37 if err != nil {
38 return "", err
39 }
40 ancestor := filepath.Dir(myc)
41 ctr := 0
42 cgroup_check_lock.Lock()
43 defer cgroup_check_lock.Unlock()
44 name := ""
45 for {
46 ctr++
47 name = fmt.Sprintf("/sys/fs/cgroup/%s/com_%d", ancestor, ctr)
48 _, err := os.Stat(name)
49 if err != nil {
50
51 break
52 }
53
54 }
55 if name == "" {
56 return "", errors.Errorf("Unable to determine adjacent cgroup")
57 }
58 err = CreateStandardCgroup(name)
59 if err != nil {
60 return "", err
61 }
62 return name, nil
63 }
64
65 func CreateStandardCgroup(dir string) error {
66 if utils.FileExists(dir) {
67 return errors.Errorf("dir \"%s\" exists already", dir)
68 }
69 err := mkdir(dir)
70 if err != nil {
71 return errors.Errorf("failed to create parent cgroup (%s): %s", dir, err)
72 }
73 taskdir := dir + "/tasks"
74 err = mkdir(taskdir)
75 if err != nil {
76 return errors.Errorf("failed to create cgroup tasks (%s): %s", taskdir, err)
77 }
78 return nil
79 }
80
81 func get_pids_for_cgroup(cgroupdir string) ([]uint64, error) {
82 fname := cgroupdir + "/cgroup.procs"
83 if !utils.FileExists(fname) {
84 return nil, nil
85 }
86 b, err := utils.ReadFile(fname)
87 if err != nil {
88 return nil, errors.Wrap(err)
89 }
90 var res []uint64
91 for _, line := range strings.Split(string(b), "\n") {
92 if line == "" {
93 continue
94 }
95 pid, err := strconv.ParseUint(line, 10, 64)
96 if err != nil {
97 return nil, errors.Wrap(err)
98 }
99 res = append(res, pid)
100 }
101 return res, nil
102 }
103
104
105 func remove_cgroup(cgroupdir string) error {
106 rmdir(cgroupdir + "/tasks")
107 rmdir(cgroupdir)
108 return nil
109 }
110 func rmdir(dir string) error {
111 err := os.Remove(dir)
112 if err != nil {
113 fmt.Printf("failed to remove dir: %s\n", err)
114 }
115 return err
116 }
117
View as plain text