diff --git a/libcontainer/setns_init_linux.go b/libcontainer/setns_init_linux.go index ba48604d988..f3f1c4bbe22 100644 --- a/libcontainer/setns_init_linux.go +++ b/libcontainer/setns_init_linux.go @@ -49,6 +49,11 @@ func (l *linuxSetnsInit) Init() error { } } } + + if err := utils.CleanRlimitNoFileCache(); err != nil { + return err + } + if l.config.CreateConsole { if err := setupConsole(l.consoleSocket, l.config, false); err != nil { return err diff --git a/libcontainer/standard_init_linux.go b/libcontainer/standard_init_linux.go index 4447032cf59..81d8f89939c 100644 --- a/libcontainer/standard_init_linux.go +++ b/libcontainer/standard_init_linux.go @@ -77,6 +77,10 @@ func (l *linuxStandardInit) Init() error { } } + if err := utils.CleanRlimitNoFileCache(); err != nil { + return err + } + if err := setupNetwork(l.config); err != nil { return err } diff --git a/libcontainer/utils/utils.go b/libcontainer/utils/utils.go index 1b523d8ac54..bd95fe408fd 100644 --- a/libcontainer/utils/utils.go +++ b/libcontainer/utils/utils.go @@ -7,6 +7,7 @@ import ( "os" "path/filepath" "strings" + "syscall" "unsafe" "golang.org/x/sys/unix" @@ -129,3 +130,13 @@ func Annotations(labels []string) (bundle string, userAnnotations map[string]str } return } + +// Clean the cache of RLIMIT_NOFILE in go runtime +// https://github.com/golang/go/commit/f5eef58e4381259cbd84b3f2074c79607fb5c821#diff-ec665e9789f8cf5cd1828ad7fa9f0ff4ebc1f5b5dd0fc82a296da5c07da7ece6 +func CleanRlimitNoFileCache() error { + rlimit := syscall.Rlimit{} + if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rlimit); err != nil { + return err + } + return syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rlimit) +} diff --git a/tests/integration/resources.bats b/tests/integration/resources.bats new file mode 100644 index 00000000000..279697f3e44 --- /dev/null +++ b/tests/integration/resources.bats @@ -0,0 +1,22 @@ +#!/usr/bin/env bats + +load helpers + +function setup() { + setup_busybox + update_config '.process.args = ["/bin/sh", "-c", "ulimit -n"]' +} + +function teardown() { + teardown_bundle +} + +@test "runc run with RLIMIT_NOFILE" { + update_config '.process.capabilities.bounding = ["CAP_RESOURCE"]' + update_config '.process.rlimits = [{"type": "RLIMIT_NOFILE", "hard": 10000, "soft": 10000}]' + + runc run test_hello + [ "$status" -eq 0 ] + + [[ "${output}" == *"10000"* ]] +}