diff options
-rw-r--r-- | pkg/cgroups/blkio.go | 2 | ||||
-rw-r--r-- | pkg/cgroups/cgroups.go | 52 | ||||
-rw-r--r-- | pkg/cgroups/cpu.go | 17 | ||||
-rw-r--r-- | pkg/cgroups/cpuset.go | 19 | ||||
-rw-r--r-- | pkg/cgroups/memory.go | 2 | ||||
-rw-r--r-- | pkg/cgroups/pids.go | 3 |
6 files changed, 78 insertions, 17 deletions
diff --git a/pkg/cgroups/blkio.go b/pkg/cgroups/blkio.go index ca9107d97..9c2a811d9 100644 --- a/pkg/cgroups/blkio.go +++ b/pkg/cgroups/blkio.go @@ -30,7 +30,7 @@ func (c *blkioHandler) Apply(ctr *CgroupControl, res *spec.LinuxResources) error // Create the cgroup func (c *blkioHandler) Create(ctr *CgroupControl) (bool, error) { if ctr.cgroup2 { - return false, fmt.Errorf("io create not implemented for cgroup v2") + return false, nil } return ctr.createCgroupDirectory(Blkio) } diff --git a/pkg/cgroups/cgroups.go b/pkg/cgroups/cgroups.go index d6c19212b..1dad45d7f 100644 --- a/pkg/cgroups/cgroups.go +++ b/pkg/cgroups/cgroups.go @@ -149,6 +149,51 @@ func (c *CgroupControl) getCgroupv1Path(name string) string { return filepath.Join(cgroupRoot, name, c.path) } +// createCgroupv2Path creates the cgroupv2 path and enables all the available controllers +func createCgroupv2Path(path string) (Err error) { + content, err := ioutil.ReadFile("/sys/fs/cgroup/cgroup.controllers") + if err != nil { + return errors.Wrapf(err, "read /sys/fs/cgroup/cgroup.controllers") + } + if !filepath.HasPrefix(path, "/sys/fs/cgroup") { + return fmt.Errorf("invalid cgroup path %s", path) + } + + res := "" + for i, c := range strings.Split(strings.TrimSpace(string(content)), " ") { + if i == 0 { + res = fmt.Sprintf("+%s", c) + } else { + res = res + fmt.Sprintf(" +%s", c) + } + } + resByte := []byte(res) + + current := "/sys/fs" + elements := strings.Split(path, "/") + for i, e := range elements[3:] { + current = filepath.Join(current, e) + if i > 0 { + if err := os.Mkdir(current, 0755); err != nil { + if !os.IsExist(err) { + return errors.Wrapf(err, "mkdir %s", path) + } + } else { + // If the directory was created, be sure it is not left around on errors. + defer func() { + if Err != nil { + os.Remove(current) + } + }() + } + } + if err := ioutil.WriteFile(filepath.Join(current, "cgroup.subtree_control"), resByte, 0755); err != nil { + return errors.Wrapf(err, "write %s", filepath.Join(current, "cgroup.subtree_control")) + } + } + return nil +} + // initialize initializes the specified hierarchy func (c *CgroupControl) initialize() (err error) { createdSoFar := map[string]controllerHandler{} @@ -161,6 +206,11 @@ func (c *CgroupControl) initialize() (err error) { } } }() + if c.cgroup2 { + if err := createCgroupv2Path(filepath.Join(cgroupRoot, c.path)); err != nil { + return errors.Wrapf(err, "error creating cgroup path %s", c.path) + } + } for name, handler := range handlers { created, err := handler.Create(c) if err != nil { @@ -341,7 +391,7 @@ func (c *CgroupControl) AddPid(pid int) error { pidString := []byte(fmt.Sprintf("%d\n", pid)) if c.cgroup2 { - p := filepath.Join(cgroupRoot, c.path, "tasks") + p := filepath.Join(cgroupRoot, c.path, "cgroup.procs") if err := ioutil.WriteFile(p, pidString, 0644); err != nil { return errors.Wrapf(err, "write %s", p) } diff --git a/pkg/cgroups/cpu.go b/pkg/cgroups/cpu.go index 8640d490e..1c8610cc4 100644 --- a/pkg/cgroups/cpu.go +++ b/pkg/cgroups/cpu.go @@ -61,7 +61,7 @@ func (c *cpuHandler) Apply(ctr *CgroupControl, res *spec.LinuxResources) error { // Create the cgroup func (c *cpuHandler) Create(ctr *CgroupControl) (bool, error) { if ctr.cgroup2 { - return false, fmt.Errorf("cpu create not implemented for cgroup v2") + return false, nil } return ctr.createCgroupDirectory(CPU) } @@ -98,15 +98,24 @@ func (c *cpuHandler) Stat(ctr *CgroupControl, m *Metrics) error { } else { usage.Total, err = readAcct(ctr, "cpuacct.usage") if err != nil { - return err + if !os.IsNotExist(errors.Cause(err)) { + return err + } + usage.Total = 0 } usage.Kernel, err = readAcct(ctr, "cpuacct.usage_sys") if err != nil { - return err + if !os.IsNotExist(errors.Cause(err)) { + return err + } + usage.Kernel = 0 } usage.PerCPU, err = readAcctList(ctr, "cpuacct.usage_percpu") if err != nil { - return err + if !os.IsNotExist(errors.Cause(err)) { + return err + } + usage.PerCPU = nil } } m.CPU = CPUMetrics{Usage: usage} diff --git a/pkg/cgroups/cpuset.go b/pkg/cgroups/cpuset.go index 9aef493c9..25d2f7f76 100644 --- a/pkg/cgroups/cpuset.go +++ b/pkg/cgroups/cpuset.go @@ -14,19 +14,23 @@ import ( type cpusetHandler struct { } -func cpusetCopyFileFromParent(dir, file string) ([]byte, error) { +func cpusetCopyFileFromParent(dir, file string, cgroupv2 bool) ([]byte, error) { if dir == cgroupRoot { return nil, fmt.Errorf("could not find parent to initialize cpuset %s", file) } path := filepath.Join(dir, file) - data, err := ioutil.ReadFile(path) + parentPath := path + if cgroupv2 { + parentPath = fmt.Sprintf("%s.effective", parentPath) + } + data, err := ioutil.ReadFile(parentPath) if err != nil { return nil, errors.Wrapf(err, "open %s", path) } if len(strings.Trim(string(data), "\n")) != 0 { return data, nil } - data, err = cpusetCopyFileFromParent(filepath.Dir(dir), file) + data, err = cpusetCopyFileFromParent(filepath.Dir(dir), file, cgroupv2) if err != nil { return nil, err } @@ -36,9 +40,9 @@ func cpusetCopyFileFromParent(dir, file string) ([]byte, error) { return data, nil } -func cpusetCopyFromParent(path string) error { +func cpusetCopyFromParent(path string, cgroupv2 bool) error { for _, file := range []string{"cpuset.cpus", "cpuset.mems"} { - if _, err := cpusetCopyFileFromParent(path, file); err != nil { + if _, err := cpusetCopyFileFromParent(path, file, cgroupv2); err != nil { return err } } @@ -60,14 +64,15 @@ func (c *cpusetHandler) Apply(ctr *CgroupControl, res *spec.LinuxResources) erro // Create the cgroup func (c *cpusetHandler) Create(ctr *CgroupControl) (bool, error) { if ctr.cgroup2 { - return false, fmt.Errorf("cpuset create not implemented for cgroup v2") + path := filepath.Join(cgroupRoot, ctr.path) + return true, cpusetCopyFromParent(path, true) } created, err := ctr.createCgroupDirectory(CPUset) if !created || err != nil { return created, err } - return true, cpusetCopyFromParent(ctr.getCgroupv1Path(CPUset)) + return true, cpusetCopyFromParent(ctr.getCgroupv1Path(CPUset), false) } // Destroy the cgroup diff --git a/pkg/cgroups/memory.go b/pkg/cgroups/memory.go index 0505eac40..80e88d17c 100644 --- a/pkg/cgroups/memory.go +++ b/pkg/cgroups/memory.go @@ -26,7 +26,7 @@ func (c *memHandler) Apply(ctr *CgroupControl, res *spec.LinuxResources) error { // Create the cgroup func (c *memHandler) Create(ctr *CgroupControl) (bool, error) { if ctr.cgroup2 { - return false, fmt.Errorf("memory create not implemented for cgroup v2") + return false, nil } return ctr.createCgroupDirectory(Memory) } diff --git a/pkg/cgroups/pids.go b/pkg/cgroups/pids.go index c90dc1c02..ffbde100d 100644 --- a/pkg/cgroups/pids.go +++ b/pkg/cgroups/pids.go @@ -35,9 +35,6 @@ func (c *pidHandler) Apply(ctr *CgroupControl, res *spec.LinuxResources) error { // Create the cgroup func (c *pidHandler) Create(ctr *CgroupControl) (bool, error) { - if ctr.cgroup2 { - return false, fmt.Errorf("pid create not implemented for cgroup v2") - } return ctr.createCgroupDirectory(Pids) } |