Skip to content

Commit fa72652

Browse files
ls-gggcoolli
authored and
coolli
committed
libcontainer:clean cached rlimit nofile in go runtime
As reported in issue opencontainers#4195, the new version of go runtime will cache rlimit-nofile. before executing exec, the rlimit-nofile of the process will be updated with the cache. in runc, this will cause the rlimit-nofile set by the parent process for the container to become invalid. this can be solved by clearing the cache. Signed-off-by: ls-ggg <[email protected]>
1 parent d0f803e commit fa72652

File tree

3 files changed

+48
-0
lines changed

3 files changed

+48
-0
lines changed

libcontainer/setns_init_linux.go

+14
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,20 @@ func (l *linuxSetnsInit) Init() error {
4949
}
5050
}
5151
}
52+
53+
// Set RLIMIT_NOFILE again to refresh the cache in go runtime
54+
// The problem originates from https://github.com/golang/go/commit/f5eef58e4381259cbd84b3f2074c79607fb5c821
55+
for _, rlimit := range l.config.Rlimits {
56+
if rlimit.Type == unix.RLIMIT_NOFILE {
57+
if err := unix.Setrlimit(rlimit.Type, &unix.Rlimit{
58+
Cur: rlimit.Soft,
59+
Max: rlimit.Hard,
60+
}); err != nil {
61+
return fmt.Errorf("failed to re-apply nofile rlimit: %w", err)
62+
}
63+
}
64+
}
65+
5266
if l.config.CreateConsole {
5367
if err := setupConsole(l.consoleSocket, l.config, false); err != nil {
5468
return err

libcontainer/standard_init_linux.go

+12
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,18 @@ func (l *linuxStandardInit) Init() error {
7676
}
7777
}
7878
}
79+
// Set RLIMIT_NOFILE again to refresh the cache in go runtime
80+
// The problem originates from https://github.com/golang/go/commit/f5eef58e4381259cbd84b3f2074c79607fb5c821
81+
for _, rlimit := range l.config.Rlimits {
82+
if rlimit.Type == unix.RLIMIT_NOFILE {
83+
if err := unix.Setrlimit(rlimit.Type, &unix.Rlimit{
84+
Cur: rlimit.Soft,
85+
Max: rlimit.Hard,
86+
}); err != nil {
87+
return fmt.Errorf("failed to re-apply nofile rlimit: %w", err)
88+
}
89+
}
90+
}
7991

8092
if err := setupNetwork(l.config); err != nil {
8193
return err

tests/integration/resources.bats

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/env bats
2+
3+
load helpers
4+
5+
function setup() {
6+
setup_busybox
7+
}
8+
9+
function teardown() {
10+
teardown_bundle
11+
}
12+
13+
@test "runc run with RLIMIT_NOFILE" {
14+
update_config '.process.args = ["/bin/sh", "-c", "ulimit -n"]'
15+
update_config '.process.capabilities.bounding = ["CAP_SYS_RESOURCE"]'
16+
update_config '.process.rlimits = [{"type": "RLIMIT_NOFILE", "hard": 10000, "soft": 10000}]'
17+
18+
runc run test_hello
19+
[ "$status" -eq 0 ]
20+
21+
[[ "${output}" == "10000" ]]
22+
}

0 commit comments

Comments
 (0)