diff --git a/libcontainer/setns_init_linux.go b/libcontainer/setns_init_linux.go index ba48604d988..5262d41343b 100644 --- a/libcontainer/setns_init_linux.go +++ b/libcontainer/setns_init_linux.go @@ -5,6 +5,7 @@ import ( "fmt" "os" "os/exec" + "syscall" "github.com/opencontainers/selinux/go-selinux" "github.com/sirupsen/logrus" @@ -49,6 +50,17 @@ func (l *linuxSetnsInit) Init() error { } } } + + // Set RLIMIT_NOFILE again to clean the cache in go runtime + // The problem originates from https://github.com/golang/go/commit/f5eef58e4381259cbd84b3f2074c79607fb5c821 + rlimit := syscall.Rlimit{} + if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rlimit); err != nil { + return err + } + if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rlimit); 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..b99f38497b9 100644 --- a/libcontainer/standard_init_linux.go +++ b/libcontainer/standard_init_linux.go @@ -5,11 +5,7 @@ import ( "fmt" "os" "os/exec" - - "github.com/opencontainers/runtime-spec/specs-go" - "github.com/opencontainers/selinux/go-selinux" - "github.com/sirupsen/logrus" - "golang.org/x/sys/unix" + "syscall" "github.com/opencontainers/runc/libcontainer/apparmor" "github.com/opencontainers/runc/libcontainer/configs" @@ -17,6 +13,10 @@ import ( "github.com/opencontainers/runc/libcontainer/seccomp" "github.com/opencontainers/runc/libcontainer/system" "github.com/opencontainers/runc/libcontainer/utils" + "github.com/opencontainers/runtime-spec/specs-go" + "github.com/opencontainers/selinux/go-selinux" + "github.com/sirupsen/logrus" + "golang.org/x/sys/unix" ) type linuxStandardInit struct { @@ -77,6 +77,16 @@ func (l *linuxStandardInit) Init() error { } } + // Set RLIMIT_NOFILE again to clean the cache in go runtime + // The problem originates from https://github.com/golang/go/commit/f5eef58e4381259cbd84b3f2074c79607fb5c821 + rlimit := syscall.Rlimit{} + if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rlimit); err != nil { + return err + } + if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rlimit); err != nil { + return err + } + if err := setupNetwork(l.config); err != nil { return err } diff --git a/tests/integration/resources.bats b/tests/integration/resources.bats new file mode 100644 index 00000000000..8d035c3a0ef --- /dev/null +++ b/tests/integration/resources.bats @@ -0,0 +1,22 @@ +#!/usr/bin/env bats + +load helpers + +function setup() { + setup_busybox +} + +function teardown() { + teardown_bundle +} + +@test "runc run with RLIMIT_NOFILE" { + update_config '.process.args = ["/bin/sh", "-c", "ulimit -n"]' + update_config '.process.capabilities.bounding = ["CAP_SYS_RESOURCE"]' + update_config '.process.rlimits = [{"type": "RLIMIT_NOFILE", "hard": 10000, "soft": 10000}]' + + runc run test_hello + [ "$status" -eq 0 ] + + [[ "${output}" == "10000" ]] +}