Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- The deprecated `libcontainer/userns` package has been removed; use
`github.com/moby/sys/userns` instead.

### Breaking ###
- The handling of `pids.limit` has been updated to match the newer guidance
from the OCI runtime specification. In particular, now a maximum limit value
of `0` will be treated as an actual limit (due to limitations with systemd,
it will be treated the same as a limit value of `1`). We only expect users
that explicitly set `pids.limit` to `0` will see a behaviour change.
(opencontainers/cgroups#48, #4949)

### Fixed ###
- cgroups: provide iocost statistics for cgroupv2. (opencontainers/cgroups#43)
- cgroups: retry DBus connection when it fails with EAGAIN.
(opencontainers/cgroups#45)
- cgroups: improve `cpuacct.usage_all` resilience when parsing data from
patched kernels (such as the Tencent kernels). (opencontainers/cgroups#46,
opencontainers/cgroups#50)

## [1.4.0-rc.1] - 2025-09-05

> おめェもボスになったんだろぉ?
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ require (
github.com/moby/sys/user v0.4.0
github.com/moby/sys/userns v0.1.0
github.com/mrunalp/fileutils v0.5.1
github.com/opencontainers/cgroups v0.0.5
github.com/opencontainers/runtime-spec v1.2.2-0.20250818071321-383cadbf08c0
github.com/opencontainers/cgroups v0.0.6
github.com/opencontainers/runtime-spec v1.3.0
github.com/opencontainers/selinux v1.13.0
github.com/seccomp/libseccomp-golang v0.11.1
github.com/sirupsen/logrus v1.9.3
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g
github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28=
github.com/mrunalp/fileutils v0.5.1 h1:F+S7ZlNKnrwHfSwdlgNSkKo67ReVf8o9fel6C3dkm/Q=
github.com/mrunalp/fileutils v0.5.1/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
github.com/opencontainers/cgroups v0.0.5 h1:DRITAqcOnY0uSBzIpt1RYWLjh5DPDiqUs4fY6Y0ktls=
github.com/opencontainers/cgroups v0.0.5/go.mod h1:oWVzJsKK0gG9SCRBfTpnn16WcGEqDI8PAcpMGbqWxcs=
github.com/opencontainers/runtime-spec v1.2.2-0.20250818071321-383cadbf08c0 h1:RLn0YfUWkiqPGtgUANvJrcjIkCHGRl3jcz/c557M28M=
github.com/opencontainers/runtime-spec v1.2.2-0.20250818071321-383cadbf08c0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/cgroups v0.0.6 h1:tfZFWTIIGaUUFImTyuTg+Mr5x8XRiSdZESgEBW7UxuI=
github.com/opencontainers/cgroups v0.0.6/go.mod h1:oWVzJsKK0gG9SCRBfTpnn16WcGEqDI8PAcpMGbqWxcs=
github.com/opencontainers/runtime-spec v1.3.0 h1:YZupQUdctfhpZy3TM39nN9Ika5CBWT5diQ8ibYCRkxg=
github.com/opencontainers/runtime-spec v1.3.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/selinux v1.13.0 h1:Zza88GWezyT7RLql12URvoxsbLfjFx988+LGaWfbL84=
github.com/opencontainers/selinux v1.13.0/go.mod h1:XxWTed+A/s5NNq4GmYScVy+9jzXhGBVEOAyucdRUY8s=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
Expand Down
8 changes: 5 additions & 3 deletions libcontainer/integration/exec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -526,20 +526,22 @@ func TestPidsSystemd(t *testing.T) {
testPids(t, true)
}

func mkPtr[T any](v T) *T { return &v }

func testPids(t *testing.T, systemd bool) {
if testing.Short() {
return
}

config := newTemplateConfig(t, &tParam{systemd: systemd})
config.Cgroups.Resources.PidsLimit = -1
config.Cgroups.Resources.PidsLimit = mkPtr[int64](-1)

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

// Enforce a permissive limit. This needs to be fairly hand-wavey due to the
// issues with running Go binaries with pids restrictions (see below).
config.Cgroups.Resources.PidsLimit = 64
config.Cgroups.Resources.PidsLimit = mkPtr[int64](64)
runContainerOk(t, config, "/bin/sh", "-c", `
/bin/true | /bin/true | /bin/true | /bin/true | /bin/true | /bin/true | bin/true | /bin/true |
/bin/true | /bin/true | /bin/true | /bin/true | /bin/true | /bin/true | bin/true | /bin/true |
Expand All @@ -548,7 +550,7 @@ func testPids(t *testing.T, systemd bool) {

// Enforce a restrictive limit. 64 * /bin/true + 1 * shell should cause
// this to fail reliably.
config.Cgroups.Resources.PidsLimit = 64
config.Cgroups.Resources.PidsLimit = mkPtr[int64](64)
out, _, err := runContainer(t, config, "/bin/sh", "-c", `
/bin/true | /bin/true | /bin/true | /bin/true | /bin/true | /bin/true | bin/true | /bin/true |
/bin/true | /bin/true | /bin/true | /bin/true | /bin/true | /bin/true | bin/true | /bin/true |
Expand Down
3 changes: 2 additions & 1 deletion man/runc-update.8.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ stdin. If this option is used, all other options are ignored.
(i.e. use unlimited swap).

**--pids-limit** _num_
: Set the maximum number of processes allowed in the container.
: Set the maximum number of processes allowed in the container. Use **-1** to
unset the limit.

**--l3-cache-schema** _value_
: Set the value for Intel RDT/CAT L3 cache schema.
Expand Down
31 changes: 31 additions & 0 deletions tests/integration/cgroups.bats
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,37 @@ convert_hugetlb_size() {
done
}

# https://github.com/opencontainers/runc/issues/4014.
@test "runc run (pids.limit=0 means 1)" {
[ $EUID -ne 0 ] && requires rootless_cgroup
requires cgroups_pids

set_cgroups_path
update_config '.linux.resources.pids.limit = 0'

runc run -d --console-socket "$CONSOLE_SOCKET" test_pids
[ "$status" -eq 0 ]
# systemd doesn't support TasksMax=0 so runc will silently remap it to 1
# (for consistency, we do this for systemd *and* cgroupfs).
check_cgroup_value "pids.max" "1"
check_systemd_value "TasksMax" "1"
}

# https://github.com/opencontainers/runc/issues/4014.
@test "runc run (pids.limit=-1 means unlimited)" {
[ $EUID -ne 0 ] && requires rootless_cgroup
requires cgroups_pids

set_cgroups_path
update_config '.linux.resources.pids.limit = -1'

runc run -d --console-socket "$CONSOLE_SOCKET" test_pids
[ "$status" -eq 0 ]
check_cgroup_value "pids.max" "max"
# systemd < v227 shows UINT64_MAX instead of "infinity".
check_systemd_value "TasksMax" "infinity" "18446744073709551615"
}

@test "runc run (cgroup v2 resources.unified only)" {
requires root cgroups_v2

Expand Down
31 changes: 31 additions & 0 deletions tests/integration/update.bats
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,37 @@ EOF
check_cpu_shares 100
}

@test "update pids.limit" {
[ $EUID -ne 0 ] && requires rootless_cgroup
requires cgroups_pids

runc run -d --console-socket "$CONSOLE_SOCKET" test_update
[ "$status" -eq 0 ]

check_cgroup_value "pids.max" 20
check_systemd_value "TasksMax" 20

runc update test_update --pids-limit 12345
[ "$status" -eq 0 ]

check_cgroup_value "pids.max" "12345"
check_systemd_value "TasksMax" "12345"

runc update test_update --pids-limit -1
[ "$status" -eq 0 ]

check_cgroup_value "pids.max" "max"
# systemd < v227 shows UINT64_MAX instead of "infinity".
check_systemd_value "TasksMax" "infinity" "18446744073709551615"

runc update test_update --pids-limit 0
[ "$status" -eq 0 ]

# systemd doesn't support TasksMax=0 so runc will silently remap it to 1.
check_cgroup_value "pids.max" "1"
check_systemd_value "TasksMax" "1"
}

@test "cpu burst" {
[ $EUID -ne 0 ] && requires rootless_cgroup
requires cgroups_cpu_burst
Expand Down
21 changes: 10 additions & 11 deletions update.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@ import (
"github.com/urfave/cli"
)

func i64Ptr(i int64) *int64 { return &i }
func u64Ptr(i uint64) *uint64 { return &i }
func u16Ptr(i uint16) *uint16 { return &i }
func boolPtr(b bool) *bool { return &b }
func mkPtr[T any](v T) *T { return &v }

var updateCommand = cli.Command{
Name: "update",
Expand Down Expand Up @@ -147,9 +144,9 @@ other options are ignored.
}

r := specs.LinuxResources{
// nil and u64Ptr(0) are not interchangeable
// nil and mkPtr(0) are not interchangeable
Memory: &specs.LinuxMemory{
CheckBeforeUpdate: boolPtr(false), // constant
CheckBeforeUpdate: mkPtr(false), // constant
},
CPU: &specs.LinuxCPU{},
BlockIO: &specs.LinuxBlockIO{},
Expand Down Expand Up @@ -179,7 +176,7 @@ other options are ignored.
}
} else {
if val := context.Int("blkio-weight"); val != 0 {
r.BlockIO.Weight = u16Ptr(uint16(val))
r.BlockIO.Weight = mkPtr(uint16(val))
}
if val := context.String("cpuset-cpus"); val != "" {
r.CPU.Cpus = val
Expand All @@ -192,7 +189,7 @@ other options are ignored.
if err != nil {
return fmt.Errorf("invalid value for cpu-idle: %w", err)
}
r.CPU.Idle = i64Ptr(idle)
r.CPU.Idle = mkPtr(idle)
}

for _, pair := range []struct {
Expand Down Expand Up @@ -252,17 +249,19 @@ other options are ignored.
}
}

r.Pids.Limit = int64(context.Int("pids-limit"))
if context.IsSet("pids-limit") {
r.Pids.Limit = mkPtr(int64(context.Int("pids-limit")))
}
}

// Fix up values
if r.Memory.Limit != nil && *r.Memory.Limit == -1 && r.Memory.Swap == nil {
// To avoid error "unable to set swap limit without memory limit"
r.Memory.Swap = i64Ptr(0)
r.Memory.Swap = mkPtr[int64](0)
}
if r.CPU.Idle != nil && r.CPU.Shares == nil {
// To avoid error "failed to write \"4\": write /sys/fs/cgroup/runc-cgroups-integration-test/test-cgroup-7341/cpu.weight: invalid argument"
r.CPU.Shares = u64Ptr(0)
r.CPU.Shares = mkPtr[uint64](0)
}

if (r.Memory.Kernel != nil) || (r.Memory.KernelTCP != nil) { //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility.
Expand Down
4 changes: 2 additions & 2 deletions vendor/github.com/opencontainers/cgroups/config_linux.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 8 additions & 4 deletions vendor/github.com/opencontainers/cgroups/fs/cpuacct.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 16 additions & 11 deletions vendor/github.com/opencontainers/cgroups/fs/pids.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 15 additions & 4 deletions vendor/github.com/opencontainers/cgroups/fs2/io.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 14 additions & 6 deletions vendor/github.com/opencontainers/cgroups/fs2/pids.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions vendor/github.com/opencontainers/cgroups/stats.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading