aboutsummaryrefslogtreecommitdiff
path: root/pkg/cgroups
diff options
context:
space:
mode:
authorGiuseppe Scrivano <gscrivan@redhat.com>2019-07-08 10:16:13 +0200
committerGiuseppe Scrivano <gscrivan@redhat.com>2019-07-10 10:54:35 +0200
commitbbe03e61a375416180432fbd9d00d23a7c2a4714 (patch)
tree959eb8a850da9f9ba10d5e0cfb0fe213d20c4fdb /pkg/cgroups
parent551edd287e7cb31327d18c3ebc0d2e6b1160c235 (diff)
downloadpodman-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')
-rw-r--r--pkg/cgroups/blkio.go2
-rw-r--r--pkg/cgroups/cgroups.go52
-rw-r--r--pkg/cgroups/cpu.go2
-rw-r--r--pkg/cgroups/cpuset.go19
-rw-r--r--pkg/cgroups/memory.go2
-rw-r--r--pkg/cgroups/pids.go3
6 files changed, 66 insertions, 14 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..c9325946b 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)
}
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)
}