Pids-limit should only be set if the user set it

Currently we are sending over pids-limits from the user even if they
never modified the defaults.  The pids limit should be set at the server
side unless modified by the user.

This issue has led to failures on systems that were running with cgroups V1.

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
Daniel J Walsh
2020-07-10 03:29:34 -04:00
parent 2ac8c69534
commit 677ad10e07
6 changed files with 43 additions and 28 deletions

View File

@ -330,8 +330,7 @@ func GetCreateFlags(cf *ContainerCLIOpts) *pflag.FlagSet {
"pid", "", "pid", "",
"PID namespace to use", "PID namespace to use",
) )
createFlags.Int64Var( createFlags.Int64(
&cf.PIDsLimit,
"pids-limit", containerConfig.PidsLimit(), "pids-limit", containerConfig.PidsLimit(),
"Tune container pids limit (set 0 for unlimited, -1 for server defaults)", "Tune container pids limit (set 0 for unlimited, -1 for server defaults)",
) )

View File

@ -66,7 +66,7 @@ type ContainerCLIOpts struct {
OverrideArch string OverrideArch string
OverrideOS string OverrideOS string
PID string PID string
PIDsLimit int64 PIDsLimit *int64
Pod string Pod string
PodIDFile string PodIDFile string
PreserveFDs uint PreserveFDs uint

View File

@ -7,14 +7,12 @@ import (
"strings" "strings"
"time" "time"
"github.com/containers/common/pkg/config"
"github.com/containers/image/v5/manifest" "github.com/containers/image/v5/manifest"
"github.com/containers/libpod/v2/cmd/podman/parse" "github.com/containers/libpod/v2/cmd/podman/parse"
"github.com/containers/libpod/v2/libpod/define" "github.com/containers/libpod/v2/libpod/define"
ann "github.com/containers/libpod/v2/pkg/annotations" ann "github.com/containers/libpod/v2/pkg/annotations"
envLib "github.com/containers/libpod/v2/pkg/env" envLib "github.com/containers/libpod/v2/pkg/env"
ns "github.com/containers/libpod/v2/pkg/namespaces" ns "github.com/containers/libpod/v2/pkg/namespaces"
"github.com/containers/libpod/v2/pkg/rootless"
"github.com/containers/libpod/v2/pkg/specgen" "github.com/containers/libpod/v2/pkg/specgen"
systemdGen "github.com/containers/libpod/v2/pkg/systemd/generate" systemdGen "github.com/containers/libpod/v2/pkg/systemd/generate"
"github.com/containers/libpod/v2/pkg/util" "github.com/containers/libpod/v2/pkg/util"
@ -127,25 +125,6 @@ func getIOLimits(s *specgen.SpecGenerator, c *ContainerCLIOpts) (*specs.LinuxBlo
return io, nil return io, nil
} }
func getPidsLimits(c *ContainerCLIOpts) *specs.LinuxPids {
pids := &specs.LinuxPids{}
if c.CGroupsMode == "disabled" && c.PIDsLimit != 0 {
return nil
}
if c.PIDsLimit < 0 {
if rootless.IsRootless() && containerConfig.Engine.CgroupManager != config.SystemdCgroupsManager {
return nil
}
pids.Limit = containerConfig.PidsLimit()
return pids
}
if c.PIDsLimit > 0 {
pids.Limit = c.PIDsLimit
return pids
}
return nil
}
func getMemoryLimits(s *specgen.SpecGenerator, c *ContainerCLIOpts) (*specs.LinuxMemory, error) { func getMemoryLimits(s *specgen.SpecGenerator, c *ContainerCLIOpts) (*specs.LinuxMemory, error) {
var err error var err error
memory := &specs.LinuxMemory{} memory := &specs.LinuxMemory{}
@ -457,7 +436,13 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
if err != nil { if err != nil {
return err return err
} }
s.ResourceLimits.Pids = getPidsLimits(c) if c.PIDsLimit != nil {
pids := specs.LinuxPids{
Limit: *c.PIDsLimit,
}
s.ResourceLimits.Pids = &pids
}
s.ResourceLimits.CPU = getCPULimits(c) s.ResourceLimits.CPU = getCPULimits(c)
if s.ResourceLimits.CPU == nil && s.ResourceLimits.Pids == nil && s.ResourceLimits.BlockIO == nil && s.ResourceLimits.Memory == nil { if s.ResourceLimits.CPU == nil && s.ResourceLimits.Pids == nil && s.ResourceLimits.BlockIO == nil && s.ResourceLimits.Memory == nil {
s.ResourceLimits = nil s.ResourceLimits = nil

View File

@ -4,6 +4,7 @@ import (
"context" "context"
"fmt" "fmt"
"os" "os"
"strconv"
"strings" "strings"
"github.com/containers/common/pkg/config" "github.com/containers/common/pkg/config"
@ -195,13 +196,18 @@ func createInit(c *cobra.Command) error {
cliVals.UTS = c.Flag("uts").Value.String() cliVals.UTS = c.Flag("uts").Value.String()
cliVals.PID = c.Flag("pid").Value.String() cliVals.PID = c.Flag("pid").Value.String()
cliVals.CGroupsNS = c.Flag("cgroupns").Value.String() cliVals.CGroupsNS = c.Flag("cgroupns").Value.String()
if !c.Flag("pids-limit").Changed {
cliVals.PIDsLimit = -1
}
if c.Flag("entrypoint").Changed { if c.Flag("entrypoint").Changed {
val := c.Flag("entrypoint").Value.String() val := c.Flag("entrypoint").Value.String()
cliVals.Entrypoint = &val cliVals.Entrypoint = &val
} }
if c.Flags().Changed("pids-limit") {
val := c.Flag("pids-limit").Value.String()
pidsLimit, err := strconv.ParseInt(val, 10, 32)
if err != nil {
return err
}
cliVals.PIDsLimit = &pidsLimit
}
if c.Flags().Changed("env") { if c.Flags().Changed("env") {
env, err := c.Flags().GetStringArray("env") env, err := c.Flags().GetStringArray("env")
if err != nil { if err != nil {

View File

@ -10,6 +10,7 @@ import (
envLib "github.com/containers/libpod/v2/pkg/env" envLib "github.com/containers/libpod/v2/pkg/env"
"github.com/containers/libpod/v2/pkg/signal" "github.com/containers/libpod/v2/pkg/signal"
"github.com/containers/libpod/v2/pkg/specgen" "github.com/containers/libpod/v2/pkg/specgen"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors" "github.com/pkg/errors"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
) )
@ -169,6 +170,21 @@ func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerat
} }
} }
// If caller did not specify Pids Limits load default
if s.ResourceLimits == nil || s.ResourceLimits.Pids == nil {
if s.CgroupsMode != "disabled" {
limit := rtc.PidsLimit()
if limit != 0 {
if s.ResourceLimits == nil {
s.ResourceLimits = &spec.LinuxResources{}
}
s.ResourceLimits.Pids = &spec.LinuxPids{
Limit: limit,
}
}
}
}
return verifyContainerResources(s) return verifyContainerResources(s)
} }

View File

@ -1072,4 +1072,13 @@ USER mail`
Expect(session.OutputToString()).To(ContainSubstring(h)) Expect(session.OutputToString()).To(ContainSubstring(h))
}) })
It("podman run verify pids-limit", func() {
SkipIfCgroupV1()
limit := "4321"
session := podmanTest.Podman([]string{"run", "--pids-limit", limit, "--rm", ALPINE, "cat", "/sys/fs/cgroup/pids.max"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring(limit))
})
}) })