summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com>2019-07-10 14:50:04 +0200
committerGitHub <noreply@github.com>2019-07-10 14:50:04 +0200
commitcef566306c9132c610cdd028f7e5035433c12798 (patch)
treeff42b12fb448ad05e1381bb1f7bc38106dadc29a
parent551edd287e7cb31327d18c3ebc0d2e6b1160c235 (diff)
parentb0c2bb996276a706585d1a3eebcaa0b687715b5a (diff)
downloadpodman-cef566306c9132c610cdd028f7e5035433c12798.tar.gz
podman-cef566306c9132c610cdd028f7e5035433c12798.tar.bz2
podman-cef566306c9132c610cdd028f7e5035433c12798.zip
Merge pull request #3506 from giuseppe/cgroup2-improvements
cgroups: support creating cgroupsv2 paths
-rw-r--r--pkg/cgroups/blkio.go2
-rw-r--r--pkg/cgroups/cgroups.go52
-rw-r--r--pkg/cgroups/cpu.go17
-rw-r--r--pkg/cgroups/cpuset.go19
-rw-r--r--pkg/cgroups/memory.go2
-rw-r--r--pkg/cgroups/pids.go3
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)
}