envoy: preserve Go's max file limit for Envoy (#5102)

Go raises the "max open files" soft limit to match the hard limit for
itself, but has special logic to reset the original soft limit before
forking a child process. This logic does not apply if the file limit is
set explicitly. Add a pair of Getrlimit / Setrlimit calls so that we
(1) preserve the default Go limit behavior for ourselves, and
(2) keep these same limits when launching Envoy.
This commit is contained in:
Kenneth Jenkins 2024-05-03 17:15:59 -07:00 committed by GitHub
parent 1a5b8b606f
commit b1feff5d56
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -16,6 +16,7 @@ import (
"strconv"
"strings"
"sync"
"syscall"
"time"
"github.com/cenkalti/backoff/v4"
@ -57,6 +58,10 @@ type Server struct {
// NewServer creates a new server with traffic routed by envoy.
func NewServer(ctx context.Context, src config.Source, builder *envoyconfig.Builder) (*Server, error) {
if err := preserveRlimitNofile(); err != nil {
log.Debug(ctx).Err(err).Msg("couldn't preserve RLIMIT_NOFILE before starting Envoy")
}
envoyPath, err := Extract()
if err != nil {
return nil, fmt.Errorf("extracting envoy: %w", err)
@ -300,3 +305,17 @@ func (srv *Server) monitorProcess(ctx context.Context, pid int32) {
}
}
}
func preserveRlimitNofile() error {
// Go raises the "max open files" soft limit to match the hard limit for
// itself, but has special logic to reset the original soft limit before
// forking a child process. This logic does not apply if the file limit is
// set explicitly. This pair of Getrlimit / Setrlimit calls is intended to
// (1) preserve the default Go limit behavior for ourselves, and
// (2) keep these same limits when launching Envoy.
var lim syscall.Rlimit
if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &lim); err != nil {
return err
}
return syscall.Setrlimit(syscall.RLIMIT_NOFILE, &lim)
}