From 5ebba75dbd4462da47283b3f018804b7361d52bf Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Thu, 10 Oct 2024 17:35:44 +0200 Subject: [PATCH] spec: always specify default rlimits the previous implementation was expecting the rlimits to be set for the entire process and clamping the values only when running as rootless. Change the implementation to always specify the expected values in the OCI spec file and do the clamping only when running as rootless and using the default values. Signed-off-by: Giuseppe Scrivano --- docs/source/markdown/options/ulimit.md | 5 ++++ libpod/container_internal_common.go | 34 ++++++++++++++------------ 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/docs/source/markdown/options/ulimit.md b/docs/source/markdown/options/ulimit.md index be5bdaecb6..a387b2f02a 100644 --- a/docs/source/markdown/options/ulimit.md +++ b/docs/source/markdown/options/ulimit.md @@ -14,6 +14,11 @@ $ podman run --ulimit nofile=1024:1024 --rm ubi9 ulimit -n Set -1 for the soft or hard limit to set the limit to the maximum limit of the current process. In rootful mode this is often unlimited. + +If nofile and nproc are unset, a default value of 1048576 will be used, unless overridden +in containers.conf(5). However, if the default value exceeds the hard limit for the current +rootless user, the current hard limit will be applied instead. + Use **host** to copy the current configuration from the host. Don't use nproc with the ulimit flag as Linux uses nproc to set the diff --git a/libpod/container_internal_common.go b/libpod/container_internal_common.go index a2b856245b..3000aeafdf 100644 --- a/libpod/container_internal_common.go +++ b/libpod/container_internal_common.go @@ -671,18 +671,18 @@ func (c *Container) generateSpec(ctx context.Context) (s *spec.Spec, cleanupFunc return nil, nil, err } } - if isRootless { - for _, rlimit := range c.config.Spec.Process.Rlimits { - if rlimit.Type == "RLIMIT_NOFILE" { - nofileSet = true - } - if rlimit.Type == "RLIMIT_NPROC" { - nprocSet = true - } + for _, rlimit := range c.config.Spec.Process.Rlimits { + if rlimit.Type == "RLIMIT_NOFILE" { + nofileSet = true } - if !nofileSet { - max := rlimT(define.RLimitDefaultValue) - current := rlimT(define.RLimitDefaultValue) + if rlimit.Type == "RLIMIT_NPROC" { + nprocSet = true + } + } + if !nofileSet { + max := rlimT(define.RLimitDefaultValue) + current := rlimT(define.RLimitDefaultValue) + if isRootless { var rlimit unix.Rlimit if err := unix.Getrlimit(unix.RLIMIT_NOFILE, &rlimit); err != nil { logrus.Warnf("Failed to return RLIMIT_NOFILE ulimit %q", err) @@ -693,11 +693,13 @@ func (c *Container) generateSpec(ctx context.Context) (s *spec.Spec, cleanupFunc if rlimT(rlimit.Max) < max { max = rlimT(rlimit.Max) } - g.AddProcessRlimits("RLIMIT_NOFILE", uint64(max), uint64(current)) } - if !nprocSet { - max := rlimT(define.RLimitDefaultValue) - current := rlimT(define.RLimitDefaultValue) + g.AddProcessRlimits("RLIMIT_NOFILE", uint64(max), uint64(current)) + } + if !nprocSet { + max := rlimT(define.RLimitDefaultValue) + current := rlimT(define.RLimitDefaultValue) + if isRootless { var rlimit unix.Rlimit if err := unix.Getrlimit(unix.RLIMIT_NPROC, &rlimit); err != nil { logrus.Warnf("Failed to return RLIMIT_NPROC ulimit %q", err) @@ -708,8 +710,8 @@ func (c *Container) generateSpec(ctx context.Context) (s *spec.Spec, cleanupFunc if rlimT(rlimit.Max) < max { max = rlimT(rlimit.Max) } - g.AddProcessRlimits("RLIMIT_NPROC", uint64(max), uint64(current)) } + g.AddProcessRlimits("RLIMIT_NPROC", uint64(max), uint64(current)) } c.addMaskedPaths(&g)