mirror of
https://github.com/containers/podman.git
synced 2025-06-23 10:38:20 +08:00
Support passing of Ulimits as -1 to mean max
Docker allows the passing of -1 to indicate the maximum limit allowed for the current process. Fixes: https://github.com/containers/podman/issues/19319 Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
@ -11,6 +11,9 @@ Ulimit options. Sets the ulimits values inside of the container.
|
||||
$ podman run --ulimit nofile=1024:1024 --rm ubi9 ulimit -n
|
||||
1024
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
|
@ -644,7 +644,8 @@ func (c *Container) generateSpec(ctx context.Context) (s *spec.Spec, cleanupFunc
|
||||
for _, rlimit := range c.config.Spec.Process.Rlimits {
|
||||
if rlimit.Type == "RLIMIT_NOFILE" {
|
||||
nofileSet = true
|
||||
} else if rlimit.Type == "RLIMIT_NPROC" {
|
||||
}
|
||||
if rlimit.Type == "RLIMIT_NPROC" {
|
||||
nprocSet = true
|
||||
}
|
||||
}
|
||||
|
@ -324,6 +324,5 @@ func GetLimits(resource *spec.LinuxResources) (runcconfig.Resources, error) {
|
||||
|
||||
// Unified state
|
||||
final.Unified = resource.Unified
|
||||
|
||||
return *final, nil
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ func addRlimits(s *specgen.SpecGenerator, g *generate.Generator) {
|
||||
|
||||
for _, u := range s.Rlimits {
|
||||
name := "RLIMIT_" + strings.ToUpper(u.Type)
|
||||
u = subNegativeOne(u)
|
||||
g.AddProcessRlimits(name, u.Hard, u.Soft)
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
"github.com/containers/podman/v4/libpod"
|
||||
"github.com/containers/podman/v4/libpod/define"
|
||||
"github.com/containers/podman/v4/pkg/specgen"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
spec "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/opencontainers/runtime-tools/generate"
|
||||
)
|
||||
@ -172,3 +173,7 @@ func WeightDevices(wtDevices map[string]spec.LinuxWeightDevice) ([]spec.LinuxWei
|
||||
devs := []spec.LinuxWeightDevice{}
|
||||
return devs, nil
|
||||
}
|
||||
|
||||
func subNegativeOne(u specs.POSIXRlimit) specs.POSIXRlimit {
|
||||
return u
|
||||
}
|
||||
|
@ -17,8 +17,10 @@ import (
|
||||
"github.com/containers/podman/v4/libpod/define"
|
||||
"github.com/containers/podman/v4/pkg/rootless"
|
||||
"github.com/containers/podman/v4/pkg/specgen"
|
||||
"github.com/docker/go-units"
|
||||
spec "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/opencontainers/runtime-tools/generate"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
@ -357,3 +359,37 @@ func WeightDevices(wtDevices map[string]spec.LinuxWeightDevice) ([]spec.LinuxWei
|
||||
}
|
||||
return devs, nil
|
||||
}
|
||||
|
||||
// subNegativeOne translates Hard or soft limits of -1 to the current
|
||||
// processes Max limit
|
||||
func subNegativeOne(u spec.POSIXRlimit) spec.POSIXRlimit {
|
||||
if !rootless.IsRootless() ||
|
||||
(int64(u.Hard) != -1 && int64(u.Soft) != -1) {
|
||||
return u
|
||||
}
|
||||
|
||||
ul, err := units.ParseUlimit(fmt.Sprintf("%s=%d:%d", u.Type, int64(u.Soft), int64(u.Hard)))
|
||||
if err != nil {
|
||||
logrus.Warnf("Failed to check %s ulimit %q", u.Type, err)
|
||||
return u
|
||||
}
|
||||
rl, err := ul.GetRlimit()
|
||||
if err != nil {
|
||||
logrus.Warnf("Failed to check %s ulimit %q", u.Type, err)
|
||||
return u
|
||||
}
|
||||
|
||||
var rlimit unix.Rlimit
|
||||
|
||||
if err := unix.Getrlimit(rl.Type, &rlimit); err != nil {
|
||||
logrus.Warnf("Failed to return RLIMIT_NOFILE ulimit %q", err)
|
||||
return u
|
||||
}
|
||||
if int64(u.Hard) == -1 {
|
||||
u.Hard = rlimit.Max
|
||||
}
|
||||
if int64(u.Soft) == -1 {
|
||||
u.Soft = rlimit.Max
|
||||
}
|
||||
return u
|
||||
}
|
||||
|
@ -465,7 +465,7 @@ var _ = Describe("Podman inspect", func() {
|
||||
Expect(inspect[0].NetworkSettings.Networks).To(HaveLen(1))
|
||||
})
|
||||
|
||||
It("Container inspect with unlimited uilimits should be -1", func() {
|
||||
It("Container inspect with unlimited ulimits should be -1", func() {
|
||||
ctrName := "testctr"
|
||||
session := podmanTest.Podman([]string{"run", "-d", "--ulimit", "core=-1:-1", "--name", ctrName, ALPINE, "top"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
|
@ -1149,6 +1149,23 @@ EOF
|
||||
assert "$output" =~ " ${nofile2} * ${nofile2} * files"
|
||||
}
|
||||
|
||||
@test "podman run ulimit with -1" {
|
||||
max=unlimited
|
||||
if is_rootless; then
|
||||
run ulimit -c -H
|
||||
max=$output
|
||||
fi
|
||||
|
||||
run_podman run --ulimit core=-1:-1 --rm $IMAGE grep core /proc/self/limits
|
||||
assert "$output" =~ " ${max} * ${max} * bytes"
|
||||
|
||||
run_podman run --ulimit core=1000:-1 --rm $IMAGE grep core /proc/self/limits
|
||||
assert "$output" =~ " 1000 * ${max} * bytes"
|
||||
|
||||
run_podman 125 run --ulimit core=-1:1000 --rm $IMAGE grep core /proc/self/limits
|
||||
is "$output" "Error: ulimit option \"core=-1:1000\" requires name=SOFT:HARD, failed to be parsed: ulimit soft limit must be less than or equal to hard limit: soft: -1 (unlimited), hard: 1000"
|
||||
}
|
||||
|
||||
@test "podman run bad --name" {
|
||||
randomname=$(random_string 30)
|
||||
run_podman 125 create --name "$randomname/bad" $IMAGE
|
||||
|
Reference in New Issue
Block a user