summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/rootless/rootless.go45
-rw-r--r--pkg/rootless/rootless_linux.go3
-rw-r--r--pkg/spec/spec.go23
-rw-r--r--pkg/sysinfo/sysinfo.go9
-rw-r--r--pkg/sysinfo/sysinfo_linux.go15
5 files changed, 86 insertions, 9 deletions
diff --git a/pkg/rootless/rootless.go b/pkg/rootless/rootless.go
new file mode 100644
index 000000000..7e9fe9db6
--- /dev/null
+++ b/pkg/rootless/rootless.go
@@ -0,0 +1,45 @@
+package rootless
+
+import (
+ "os"
+
+ "github.com/containers/storage"
+ "github.com/pkg/errors"
+)
+
+func TryJoinPauseProcess(pausePidPath string) (bool, int, error) {
+ if _, err := os.Stat(pausePidPath); err != nil {
+ return false, -1, nil
+ }
+
+ became, ret, err := TryJoinFromFilePaths("", false, []string{pausePidPath})
+ if err == nil {
+ return became, ret, err
+ }
+
+ // It could not join the pause process, let's lock the file before trying to delete it.
+ pidFileLock, err := storage.GetLockfile(pausePidPath)
+ if err != nil {
+ // The file was deleted by another process.
+ if os.IsNotExist(err) {
+ return false, -1, nil
+ }
+ return false, -1, errors.Wrapf(err, "error acquiring lock on %s", pausePidPath)
+ }
+
+ pidFileLock.Lock()
+ defer func() {
+ if pidFileLock.Locked() {
+ pidFileLock.Unlock()
+ }
+ }()
+
+ // Now the pause PID file is locked. Try to join once again in case it changed while it was not locked.
+ became, ret, err = TryJoinFromFilePaths("", false, []string{pausePidPath})
+ if err != nil {
+ // It is still failing. We can safely remove it.
+ os.Remove(pausePidPath)
+ return false, -1, nil
+ }
+ return became, ret, err
+}
diff --git a/pkg/rootless/rootless_linux.go b/pkg/rootless/rootless_linux.go
index 6f6239e5f..05d641383 100644
--- a/pkg/rootless/rootless_linux.go
+++ b/pkg/rootless/rootless_linux.go
@@ -566,10 +566,10 @@ func TryJoinFromFilePaths(pausePidPath string, needNewNamespace bool, paths []st
r, w := os.NewFile(uintptr(fds[0]), "read file"), os.NewFile(uintptr(fds[1]), "write file")
- defer errorhandling.CloseQuiet(w)
defer errorhandling.CloseQuiet(r)
if _, _, err := becomeRootInUserNS("", path, w); err != nil {
+ w.Close()
lastErr = err
continue
}
@@ -578,7 +578,6 @@ func TryJoinFromFilePaths(pausePidPath string, needNewNamespace bool, paths []st
return false, 0, err
}
defer func() {
- errorhandling.CloseQuiet(r)
C.reexec_in_user_namespace_wait(-1, 0)
}()
diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go
index c7aa003e8..57c6e8da7 100644
--- a/pkg/spec/spec.go
+++ b/pkg/spec/spec.go
@@ -7,6 +7,7 @@ import (
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/cgroups"
"github.com/containers/libpod/pkg/rootless"
+ "github.com/containers/libpod/pkg/sysinfo"
"github.com/docker/docker/oci/caps"
"github.com/docker/go-units"
"github.com/opencontainers/runc/libcontainer/user"
@@ -300,9 +301,25 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM
blockAccessToKernelFilesystems(config, &g)
// RESOURCES - PIDS
- if config.Resources.PidsLimit != 0 {
- g.SetLinuxResourcesPidsLimit(config.Resources.PidsLimit)
- addedResources = true
+ if config.Resources.PidsLimit > 0 {
+ // if running on rootless on a cgroupv1 machine, pids limit is
+ // not supported. If the value is still the default
+ // then ignore the settings. If the caller asked for a
+ // non-default, then try to use it.
+ setPidLimit := true
+ if rootless.IsRootless() {
+ cgroup2, err := cgroups.IsCgroup2UnifiedMode()
+ if err != nil {
+ return nil, err
+ }
+ if !cgroup2 && config.Resources.PidsLimit == sysinfo.GetDefaultPidsLimit() {
+ setPidLimit = false
+ }
+ }
+ if setPidLimit {
+ g.SetLinuxResourcesPidsLimit(config.Resources.PidsLimit)
+ addedResources = true
+ }
}
for name, val := range config.Env {
diff --git a/pkg/sysinfo/sysinfo.go b/pkg/sysinfo/sysinfo.go
index f046de4b1..686f66ce5 100644
--- a/pkg/sysinfo/sysinfo.go
+++ b/pkg/sysinfo/sysinfo.go
@@ -142,3 +142,12 @@ func popcnt(x uint64) (n byte) {
x *= 0x0101010101010101
return byte(x >> 56)
}
+
+// GetDefaultPidsLimit returns the default pids limit to run containers with
+func GetDefaultPidsLimit() int64 {
+ sysInfo := New(true)
+ if !sysInfo.PidsLimit {
+ return 0
+ }
+ return 4096
+}
diff --git a/pkg/sysinfo/sysinfo_linux.go b/pkg/sysinfo/sysinfo_linux.go
index 9e675c655..76bda23c6 100644
--- a/pkg/sysinfo/sysinfo_linux.go
+++ b/pkg/sysinfo/sysinfo_linux.go
@@ -7,6 +7,7 @@ import (
"path"
"strings"
+ cg "github.com/containers/libpod/pkg/cgroups"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
@@ -227,12 +228,18 @@ func checkCgroupCpusetInfo(cgMounts map[string]string, quiet bool) cgroupCpusetI
// checkCgroupPids reads the pids information from the pids cgroup mount point.
func checkCgroupPids(quiet bool) cgroupPids {
- _, err := cgroups.FindCgroupMountpoint("", "pids")
+ cgroup2, err := cg.IsCgroup2UnifiedMode()
if err != nil {
- if !quiet {
- logrus.Warn(err)
+ logrus.Errorf("Failed to check cgroups version: %v", err)
+ }
+ if !cgroup2 {
+ _, err := cgroups.FindCgroupMountpoint("", "pids")
+ if err != nil {
+ if !quiet {
+ logrus.Warn(err)
+ }
+ return cgroupPids{}
}
- return cgroupPids{}
}
return cgroupPids{