summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com>2022-05-25 08:53:15 -0400
committerGitHub <noreply@github.com>2022-05-25 08:53:15 -0400
commit1dcd1c970d3438bd6044cce0aba9b7258cb6849d (patch)
treecaba8a5ca67cb093c456f4f532d03bdff4591d7f
parentda26439e2976cf1d6da0f9078e9c7eddebbab45c (diff)
parent94e82121bf73c163d86d99fa37b0d64adf996fba (diff)
downloadpodman-1dcd1c970d3438bd6044cce0aba9b7258cb6849d.tar.gz
podman-1dcd1c970d3438bd6044cce0aba9b7258cb6849d.tar.bz2
podman-1dcd1c970d3438bd6044cce0aba9b7258cb6849d.zip
Merge pull request #14308 from n1hility/root-cgroup
Support running podman under a root v2 cgroup
-rw-r--r--libpod/container_internal_linux.go2
-rw-r--r--pkg/specgen/generate/validate.go9
-rw-r--r--utils/testdata/cgroup.empty0
-rw-r--r--utils/testdata/cgroup.other1
-rw-r--r--utils/testdata/cgroup.root1
-rw-r--r--utils/utils_supported.go14
-rw-r--r--utils/utils_test.go26
-rw-r--r--utils/utils_windows.go4
8 files changed, 51 insertions, 6 deletions
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index 82e5fa992..298eb1947 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -3109,7 +3109,7 @@ func (c *Container) getOCICgroupPath() (string, error) {
case c.config.NoCgroups:
return "", nil
case c.config.CgroupsMode == cgroupSplit:
- selfCgroup, err := utils.GetOwnCgroup()
+ selfCgroup, err := utils.GetOwnCgroupDisallowRoot()
if err != nil {
return "", err
}
diff --git a/pkg/specgen/generate/validate.go b/pkg/specgen/generate/validate.go
index 44c7818e7..a1affef31 100644
--- a/pkg/specgen/generate/validate.go
+++ b/pkg/specgen/generate/validate.go
@@ -1,6 +1,7 @@
package generate
import (
+ "io/ioutil"
"os"
"path/filepath"
@@ -166,6 +167,14 @@ func verifyContainerResourcesCgroupV2(s *specgen.SpecGenerator) ([]string, error
if err != nil {
return warnings, err
}
+
+ if own == "/" {
+ // If running under the root cgroup try to create or reuse a "probe" cgroup to read memory values
+ own = "podman_probe"
+ _ = os.MkdirAll(filepath.Join("/sys/fs/cgroup", own), 0o755)
+ _ = ioutil.WriteFile("/sys/fs/cgroup/cgroup.subtree_control", []byte("+memory"), 0o644)
+ }
+
memoryMax := filepath.Join("/sys/fs/cgroup", own, "memory.max")
memorySwapMax := filepath.Join("/sys/fs/cgroup", own, "memory.swap.max")
_, errMemoryMax := os.Stat(memoryMax)
diff --git a/utils/testdata/cgroup.empty b/utils/testdata/cgroup.empty
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/utils/testdata/cgroup.empty
diff --git a/utils/testdata/cgroup.other b/utils/testdata/cgroup.other
new file mode 100644
index 000000000..239a7cded
--- /dev/null
+++ b/utils/testdata/cgroup.other
@@ -0,0 +1 @@
+0::/other
diff --git a/utils/testdata/cgroup.root b/utils/testdata/cgroup.root
new file mode 100644
index 000000000..1e027b2a3
--- /dev/null
+++ b/utils/testdata/cgroup.root
@@ -0,0 +1 @@
+0::/
diff --git a/utils/utils_supported.go b/utils/utils_supported.go
index 493ea61ce..c2dcc4631 100644
--- a/utils/utils_supported.go
+++ b/utils/utils_supported.go
@@ -64,7 +64,7 @@ func RunUnderSystemdScope(pid int, slice string, unitName string) error {
return nil
}
-func getCgroupProcess(procFile string) (string, error) {
+func getCgroupProcess(procFile string, allowRoot bool) (string, error) {
f, err := os.Open(procFile)
if err != nil {
return "", err
@@ -72,7 +72,7 @@ func getCgroupProcess(procFile string) (string, error) {
defer f.Close()
scanner := bufio.NewScanner(f)
- cgroup := "/"
+ cgroup := ""
for scanner.Scan() {
line := scanner.Text()
parts := strings.SplitN(line, ":", 3)
@@ -87,7 +87,7 @@ func getCgroupProcess(procFile string) (string, error) {
cgroup = parts[2]
}
}
- if cgroup == "/" {
+ if len(cgroup) == 0 || (!allowRoot && cgroup == "/") {
return "", errors.Errorf("could not find cgroup mount in %q", procFile)
}
return cgroup, nil
@@ -95,12 +95,16 @@ func getCgroupProcess(procFile string) (string, error) {
// GetOwnCgroup returns the cgroup for the current process.
func GetOwnCgroup() (string, error) {
- return getCgroupProcess("/proc/self/cgroup")
+ return getCgroupProcess("/proc/self/cgroup", true)
+}
+
+func GetOwnCgroupDisallowRoot() (string, error) {
+ return getCgroupProcess("/proc/self/cgroup", false)
}
// GetCgroupProcess returns the cgroup for the specified process process.
func GetCgroupProcess(pid int) (string, error) {
- return getCgroupProcess(fmt.Sprintf("/proc/%d/cgroup", pid))
+ return getCgroupProcess(fmt.Sprintf("/proc/%d/cgroup", pid), true)
}
// MoveUnderCgroupSubtree moves the PID under a cgroup subtree.
diff --git a/utils/utils_test.go b/utils/utils_test.go
new file mode 100644
index 000000000..f34dbdd7e
--- /dev/null
+++ b/utils/utils_test.go
@@ -0,0 +1,26 @@
+//go:build linux || darwin
+// +build linux darwin
+
+package utils
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestCgroupProcess(t *testing.T) {
+ val, err := getCgroupProcess("testdata/cgroup.root", true)
+ assert.Nil(t, err)
+ assert.Equal(t, "/", val)
+
+ _, err = getCgroupProcess("testdata/cgroup.root", false)
+ assert.NotNil(t, err)
+
+ val, err = getCgroupProcess("testdata/cgroup.other", true)
+ assert.Nil(t, err)
+ assert.Equal(t, "/other", val)
+
+ _, err = getCgroupProcess("testdata/cgroup.empty", true)
+ assert.NotNil(t, err)
+}
diff --git a/utils/utils_windows.go b/utils/utils_windows.go
index 2c159ab06..1d017f5ae 100644
--- a/utils/utils_windows.go
+++ b/utils/utils_windows.go
@@ -17,6 +17,10 @@ func GetOwnCgroup() (string, error) {
return "", errors.New("not implemented for windows")
}
+func GetOwnCgroupDisallowRoot() (string, error) {
+ return "", errors.New("not implemented for windows")
+}
+
func GetCgroupProcess(pid int) (string, error) {
return "", errors.New("not implemented for windows")
}