Skip to content

Commit 3a45f1a

Browse files
committed
config: switch PidsLimit to *int64
Previously we would treat a value of "0" as meaning "no-op", which lead to quite a bit of confusion. The runtime-spec has been updated to make the "pids.limit" value a pointer, and explicitly state that: * Values >= 0 should be treated as normal values; and * -1 indicates "max". In practice this means we should switch PidsLimit to an *int64. Luckily, this is actually backwards-compatible with our previous JSON -- an old value of "0" would be omitted from the output, which will now be parsed as "nil". The handling by our cgroup code would be identical but the latter now correctly reflects the guidance by the runtime-spec. Signed-off-by: Aleksa Sarai <[email protected]>
1 parent 6a793b6 commit 3a45f1a

File tree

7 files changed

+67
-15
lines changed

7 files changed

+67
-15
lines changed

config_linux.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ type Resources struct {
9090
// Cgroup's SCHED_IDLE value.
9191
CPUIdle *int64 `json:"cpu_idle,omitempty"`
9292

93-
// Process limit; set <= `0' to disable limit.
94-
PidsLimit int64 `json:"pids_limit,omitempty"`
93+
// Process limit; set < `0' to disable limit. `nil` means "keep current limit".
94+
PidsLimit *int64 `json:"pids_limit,omitempty"`
9595

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

devices/systemd_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import (
1313
"github.com/opencontainers/cgroups/systemd"
1414
)
1515

16+
func toPtr[T any](v T) *T { return &v }
17+
1618
// TestPodSkipDevicesUpdate checks that updating a pod having SkipDevices: true
1719
// does not result in spurious "permission denied" errors in a container
1820
// running under the pod. The test is somewhat similar in nature to the
@@ -32,7 +34,7 @@ func TestPodSkipDevicesUpdate(t *testing.T) {
3234
Parent: "system.slice",
3335
Name: podName,
3436
Resources: &cgroups.Resources{
35-
PidsLimit: 42,
37+
PidsLimit: toPtr[int64](42),
3638
Memory: 32 * 1024 * 1024,
3739
SkipDevices: true,
3840
},
@@ -96,7 +98,7 @@ func TestPodSkipDevicesUpdate(t *testing.T) {
9698

9799
// Now update the pod a few times.
98100
for range 42 {
99-
podConfig.Resources.PidsLimit++
101+
(*podConfig.Resources.PidsLimit)++
100102
podConfig.Resources.Memory += 1024 * 1024
101103
if err := pm.Set(podConfig.Resources); err != nil {
102104
t.Fatal(err)

fs/pids.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ func (s *PidsGroup) Apply(path string, _ *cgroups.Resources, pid int) error {
1919
}
2020

2121
func (s *PidsGroup) Set(path string, r *cgroups.Resources) error {
22-
if r.PidsLimit != 0 {
22+
if r.PidsLimit != nil {
2323
// "max" is the fallback value.
2424
limit := "max"
2525

26-
if r.PidsLimit > 0 {
27-
limit = strconv.FormatInt(r.PidsLimit, 10)
26+
if val := *r.PidsLimit; val >= 0 {
27+
limit = strconv.FormatInt(val, 10)
2828
}
2929

3030
if err := cgroups.WriteFile(path, "pids.max", limit); err != nil {

fs/pids_test.go

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ const (
1313
maxLimited = 1024
1414
)
1515

16+
func toPtr[T any](v T) *T { return &v }
17+
1618
func TestPidsSetMax(t *testing.T) {
1719
path := tempDir(t, "pids")
1820

@@ -21,7 +23,7 @@ func TestPidsSetMax(t *testing.T) {
2123
})
2224

2325
r := &cgroups.Resources{
24-
PidsLimit: maxLimited,
26+
PidsLimit: toPtr[int64](maxLimited),
2527
}
2628
pids := &PidsGroup{}
2729
if err := pids.Set(path, r); err != nil {
@@ -37,6 +39,54 @@ func TestPidsSetMax(t *testing.T) {
3739
}
3840
}
3941

42+
func TestPidsSetZero(t *testing.T) {
43+
path := tempDir(t, "pids")
44+
45+
writeFileContents(t, path, map[string]string{
46+
"pids.max": "max",
47+
})
48+
49+
r := &cgroups.Resources{
50+
PidsLimit: toPtr[int64](0),
51+
}
52+
pids := &PidsGroup{}
53+
if err := pids.Set(path, r); err != nil {
54+
t.Fatal(err)
55+
}
56+
57+
value, err := fscommon.GetCgroupParamUint(path, "pids.max")
58+
if err != nil {
59+
t.Fatal(err)
60+
}
61+
if value != 0 {
62+
t.Fatalf("Expected 0, got %d for setting pids.max = 0", value)
63+
}
64+
}
65+
66+
func TestPidsUnset(t *testing.T) {
67+
path := tempDir(t, "pids")
68+
69+
writeFileContents(t, path, map[string]string{
70+
"pids.max": "12345",
71+
})
72+
73+
r := &cgroups.Resources{
74+
PidsLimit: nil,
75+
}
76+
pids := &PidsGroup{}
77+
if err := pids.Set(path, r); err != nil {
78+
t.Fatal(err)
79+
}
80+
81+
value, err := fscommon.GetCgroupParamUint(path, "pids.max")
82+
if err != nil {
83+
t.Fatal(err)
84+
}
85+
if value != 12345 {
86+
t.Fatalf("Expected 12345, got %d for not setting pids.max", value)
87+
}
88+
}
89+
4090
func TestPidsSetUnlimited(t *testing.T) {
4191
path := tempDir(t, "pids")
4292

@@ -45,7 +95,7 @@ func TestPidsSetUnlimited(t *testing.T) {
4595
})
4696

4797
r := &cgroups.Resources{
48-
PidsLimit: maxUnlimited,
98+
PidsLimit: toPtr[int64](maxUnlimited),
4999
}
50100
pids := &PidsGroup{}
51101
if err := pids.Set(path, r); err != nil {

fs2/pids.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ import (
1313
)
1414

1515
func isPidsSet(r *cgroups.Resources) bool {
16-
return r.PidsLimit != 0
16+
return r.PidsLimit != nil
1717
}
1818

1919
func setPids(dirPath string, r *cgroups.Resources) error {
2020
if !isPidsSet(r) {
2121
return nil
2222
}
23-
if val := numToStr(r.PidsLimit); val != "" {
23+
if val := numToStr(*r.PidsLimit); val != "" {
2424
if err := cgroups.WriteFile(dirPath, "pids.max", val); err != nil {
2525
return err
2626
}

systemd/v1.go

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

100-
if r.PidsLimit > 0 || r.PidsLimit == -1 {
100+
if r.PidsLimit != nil {
101101
properties = append(properties,
102-
newProp("TasksMax", uint64(r.PidsLimit)))
102+
newProp("TasksMax", uint64(*r.PidsLimit)))
103103
}
104104

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

systemd/v2.go

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

257257
addCPUQuota(cm, &properties, &r.CpuQuota, r.CpuPeriod)
258258

259-
if r.PidsLimit > 0 || r.PidsLimit == -1 {
259+
if r.PidsLimit != nil {
260260
properties = append(properties,
261-
newProp("TasksMax", uint64(r.PidsLimit)))
261+
newProp("TasksMax", uint64(*r.PidsLimit)))
262262
}
263263

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

0 commit comments

Comments
 (0)