diff options
author | Giuseppe Scrivano <gscrivan@redhat.com> | 2019-07-08 10:16:13 +0200 |
---|---|---|
committer | Giuseppe Scrivano <gscrivan@redhat.com> | 2019-07-10 10:54:35 +0200 |
commit | bbe03e61a375416180432fbd9d00d23a7c2a4714 (patch) | |
tree | 959eb8a850da9f9ba10d5e0cfb0fe213d20c4fdb /pkg/cgroups/cgroups.go | |
parent | 551edd287e7cb31327d18c3ebc0d2e6b1160c235 (diff) | |
download | podman-bbe03e61a375416180432fbd9d00d23a7c2a4714.tar.gz podman-bbe03e61a375416180432fbd9d00d23a7c2a4714.tar.bz2 podman-bbe03e61a375416180432fbd9d00d23a7c2a4714.zip |
cgroups: support creating cgroupsv2 paths
drop the limitation of not supporting creating new cgroups v2 paths.
Every controller enabled /sys/fs/cgroup will be propagated down to the
created path. This won't work for rootless cgroupsv2, but it is not
an issue for now, as this code is used only by CRI-O.
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Diffstat (limited to 'pkg/cgroups/cgroups.go')
-rw-r--r-- | pkg/cgroups/cgroups.go | 52 |
1 files changed, 51 insertions, 1 deletions
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) } |