Skip to content

Commit 3eb8ea5

Browse files
committed
libcontainer: set pids limit to max when set to 0
Signed-off-by: Peter Hunt <pehunt@redhat.com>
1 parent cb44958 commit 3eb8ea5

File tree

11 files changed

+62
-39
lines changed

11 files changed

+62
-39
lines changed

libcontainer/cgroups/devices/systemd_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,13 @@ func TestPodSkipDevicesUpdate(t *testing.T) {
2828
}
2929

3030
podName := "system-runc_test_pod" + t.Name() + ".slice"
31+
l := int64(42)
3132
podConfig := &configs.Cgroup{
3233
Systemd: true,
3334
Parent: "system.slice",
3435
Name: podName,
3536
Resources: &configs.Resources{
36-
PidsLimit: 42,
37+
PidsLimit: &l,
3738
Memory: 32 * 1024 * 1024,
3839
SkipDevices: true,
3940
},
@@ -97,7 +98,7 @@ func TestPodSkipDevicesUpdate(t *testing.T) {
9798

9899
// Now update the pod a few times.
99100
for i := 0; i < 42; i++ {
100-
podConfig.Resources.PidsLimit++
101+
*podConfig.Resources.PidsLimit++
101102
podConfig.Resources.Memory += 1024 * 1024
102103
if err := pm.Set(podConfig.Resources); err != nil {
103104
t.Fatal(err)

libcontainer/cgroups/fs/pids.go

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,17 @@ func (s *PidsGroup) Apply(path string, _ *configs.Resources, pid int) error {
2020
}
2121

2222
func (s *PidsGroup) Set(path string, r *configs.Resources) error {
23-
if r.PidsLimit != 0 {
24-
// "max" is the fallback value.
25-
limit := "max"
26-
27-
if r.PidsLimit > 0 {
28-
limit = strconv.FormatInt(r.PidsLimit, 10)
29-
}
23+
if r.PidsLimit == nil {
24+
return nil
25+
}
26+
// "max" is the fallback value.
27+
limit := "max"
3028

31-
if err := cgroups.WriteFile(path, "pids.max", limit); err != nil {
32-
return err
33-
}
29+
if *r.PidsLimit > 0 {
30+
limit = strconv.FormatInt(*r.PidsLimit, 10)
3431
}
3532

36-
return nil
33+
return cgroups.WriteFile(path, "pids.max", limit)
3734
}
3835

3936
func (s *PidsGroup) GetStats(path string, stats *cgroups.Stats) error {

libcontainer/cgroups/fs/pids_test.go

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ import (
99
"github.com/opencontainers/runc/libcontainer/configs"
1010
)
1111

12-
const (
13-
maxUnlimited = -1
14-
maxLimited = 1024
12+
var (
13+
maxUnlimited int64 = -1
14+
maxZero int64 = 0
15+
maxLimited int64 = 1024
1516
)
1617

1718
func TestPidsSetMax(t *testing.T) {
@@ -22,7 +23,7 @@ func TestPidsSetMax(t *testing.T) {
2223
})
2324

2425
r := &configs.Resources{
25-
PidsLimit: maxLimited,
26+
PidsLimit: &maxLimited,
2627
}
2728
pids := &PidsGroup{}
2829
if err := pids.Set(path, r); err != nil {
@@ -33,20 +34,45 @@ func TestPidsSetMax(t *testing.T) {
3334
if err != nil {
3435
t.Fatal(err)
3536
}
36-
if value != maxLimited {
37+
// Only done for comparison
38+
if value != uint64(maxLimited) {
3739
t.Fatalf("Expected %d, got %d for setting pids.max - limited", maxLimited, value)
3840
}
3941
}
4042

43+
func TestPidsSetUnlimitedWhenZero(t *testing.T) {
44+
path := tempDir(t, "pids")
45+
46+
writeFileContents(t, path, map[string]string{
47+
"pids.max": "max",
48+
})
49+
50+
r := &configs.Resources{
51+
PidsLimit: &maxZero,
52+
}
53+
pids := &PidsGroup{}
54+
if err := pids.Set(path, r); err != nil {
55+
t.Fatal(err)
56+
}
57+
58+
value, err := fscommon.GetCgroupParamString(path, "pids.max")
59+
if err != nil {
60+
t.Fatal(err)
61+
}
62+
if value != "max" {
63+
t.Fatalf("Expected %s, got %s for setting pids.max - unlimited", "max", value)
64+
}
65+
}
66+
4167
func TestPidsSetUnlimited(t *testing.T) {
4268
path := tempDir(t, "pids")
4369

4470
writeFileContents(t, path, map[string]string{
45-
"pids.max": strconv.Itoa(maxLimited),
71+
"pids.max": strconv.FormatInt(maxLimited, 10),
4672
})
4773

4874
r := &configs.Resources{
49-
PidsLimit: maxUnlimited,
75+
PidsLimit: &maxUnlimited,
5076
}
5177
pids := &PidsGroup{}
5278
if err := pids.Set(path, r); err != nil {
@@ -67,7 +93,7 @@ func TestPidsStats(t *testing.T) {
6793

6894
writeFileContents(t, path, map[string]string{
6995
"pids.current": strconv.Itoa(1337),
70-
"pids.max": strconv.Itoa(maxLimited),
96+
"pids.max": strconv.FormatInt(maxLimited, 10),
7197
})
7298

7399
pids := &PidsGroup{}
@@ -80,7 +106,7 @@ func TestPidsStats(t *testing.T) {
80106
t.Fatalf("Expected %d, got %d for pids.current", 1337, stats.PidsStats.Current)
81107
}
82108

83-
if stats.PidsStats.Limit != maxLimited {
109+
if stats.PidsStats.Limit != uint64(maxLimited) {
84110
t.Fatalf("Expected %d, got %d for pids.max", maxLimited, stats.PidsStats.Limit)
85111
}
86112
}

libcontainer/cgroups/fs2/create.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func needAnyControllers(r *configs.Resources) (bool, error) {
3939
return ok
4040
}
4141

42-
if isPidsSet(r) && have("pids") {
42+
if r.PidsLimit != nil && have("pids") {
4343
return true, nil
4444
}
4545
if isMemorySet(r) && have("memory") {

libcontainer/cgroups/fs2/pids.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,11 @@ import (
1313
"github.com/opencontainers/runc/libcontainer/configs"
1414
)
1515

16-
func isPidsSet(r *configs.Resources) bool {
17-
return r.PidsLimit != 0
18-
}
19-
2016
func setPids(dirPath string, r *configs.Resources) error {
21-
if !isPidsSet(r) {
17+
if r.PidsLimit == nil {
2218
return nil
2319
}
24-
if val := numToStr(r.PidsLimit); val != "" {
20+
if val := numToStr(*r.PidsLimit); val != "" {
2521
if err := cgroups.WriteFile(dirPath, "pids.max", val); err != nil {
2622
return err
2723
}

libcontainer/cgroups/systemd/v1.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,9 @@ func genV1ResourcesProperties(r *configs.Resources, cm *dbusConnManager) ([]syst
9898
newProp("BlockIOWeight", uint64(r.BlkioWeight)))
9999
}
100100

101-
if r.PidsLimit > 0 || r.PidsLimit == -1 {
101+
if r.PidsLimit != nil && (*r.PidsLimit > 0 || *r.PidsLimit == -1) {
102102
properties = append(properties,
103-
newProp("TasksMax", uint64(r.PidsLimit)))
103+
newProp("TasksMax", uint64(*r.PidsLimit)))
104104
}
105105

106106
err = addCpuset(cm, &properties, r.CpusetCpus, r.CpusetMems)

libcontainer/cgroups/systemd/v2.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,9 +257,9 @@ func genV2ResourcesProperties(dirPath string, r *configs.Resources, cm *dbusConn
257257

258258
addCpuQuota(cm, &properties, r.CpuQuota, r.CpuPeriod)
259259

260-
if r.PidsLimit > 0 || r.PidsLimit == -1 {
260+
if r.PidsLimit != nil && (*r.PidsLimit > 0 || *r.PidsLimit == -1) {
261261
properties = append(properties,
262-
newProp("TasksMax", uint64(r.PidsLimit)))
262+
newProp("TasksMax", uint64(*r.PidsLimit)))
263263
}
264264

265265
err = addCpuset(cm, &properties, r.CpusetCpus, r.CpusetMems)

libcontainer/configs/cgroup_linux.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ type Resources struct {
8888
CPUIdle *int64 `json:"cpu_idle,omitempty"`
8989

9090
// Process limit; set <= `0' to disable limit.
91-
PidsLimit int64 `json:"pids_limit"`
91+
PidsLimit *int64 `json:"pids_limit"`
9292

9393
// Specifies per cgroup weight, range is from 10 to 1000.
9494
BlkioWeight uint16 `json:"blkio_weight"`

libcontainer/integration/exec_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -535,14 +535,15 @@ func testPids(t *testing.T, systemd bool) {
535535
}
536536

537537
config := newTemplateConfig(t, &tParam{systemd: systemd})
538-
config.Cgroups.Resources.PidsLimit = -1
538+
l := int64(-1)
539+
config.Cgroups.Resources.PidsLimit = &l
539540

540541
// Running multiple processes, expecting it to succeed with no pids limit.
541542
_ = runContainerOk(t, config, "/bin/sh", "-c", "/bin/true | /bin/true | /bin/true | /bin/true")
542543

543544
// Enforce a permissive limit. This needs to be fairly hand-wavey due to the
544545
// issues with running Go binaries with pids restrictions (see below).
545-
config.Cgroups.Resources.PidsLimit = 64
546+
*config.Cgroups.Resources.PidsLimit = 64
546547
_ = runContainerOk(t, config, "/bin/sh", "-c", `
547548
/bin/true | /bin/true | /bin/true | /bin/true | /bin/true | /bin/true | bin/true | /bin/true |
548549
/bin/true | /bin/true | /bin/true | /bin/true | /bin/true | /bin/true | bin/true | /bin/true |
@@ -551,7 +552,7 @@ func testPids(t *testing.T, systemd bool) {
551552

552553
// Enforce a restrictive limit. 64 * /bin/true + 1 * shell should cause
553554
// this to fail reliably.
554-
config.Cgroups.Resources.PidsLimit = 64
555+
*config.Cgroups.Resources.PidsLimit = 64
555556
out, _, err := runContainer(t, config, "/bin/sh", "-c", `
556557
/bin/true | /bin/true | /bin/true | /bin/true | /bin/true | /bin/true | bin/true | /bin/true |
557558
/bin/true | /bin/true | /bin/true | /bin/true | /bin/true | /bin/true | bin/true | /bin/true |

libcontainer/specconv/spec_linux.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -768,7 +768,8 @@ func CreateCgroupConfig(opts *CreateOpts, defaultDevs []*devices.Device) (*confi
768768
c.Resources.CPUIdle = r.CPU.Idle
769769
}
770770
if r.Pids != nil {
771-
c.Resources.PidsLimit = r.Pids.Limit
771+
l := r.Pids.Limit
772+
c.Resources.PidsLimit = &l
772773
}
773774
if r.BlockIO != nil {
774775
if r.BlockIO.Weight != nil {

update.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,8 +310,9 @@ other options are ignored.
310310
config.Cgroups.Resources.MemoryReservation = *r.Memory.Reservation
311311
config.Cgroups.Resources.MemorySwap = *r.Memory.Swap
312312
config.Cgroups.Resources.MemoryCheckBeforeUpdate = *r.Memory.CheckBeforeUpdate
313-
config.Cgroups.Resources.PidsLimit = r.Pids.Limit
314313
config.Cgroups.Resources.Unified = r.Unified
314+
l := r.Pids.Limit
315+
config.Cgroups.Resources.PidsLimit = &l
315316

316317
// Update Intel RDT
317318
l3CacheSchema := context.String("l3-cache-schema")

0 commit comments

Comments
 (0)