github.com/MetalBlockchain/metalgo@v1.11.9/utils/ulimit/ulimit_unix.go (about) 1 // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. 2 // See the file LICENSE for licensing terms. 3 4 //go:build linux || netbsd || openbsd 5 // +build linux netbsd openbsd 6 7 package ulimit 8 9 import ( 10 "fmt" 11 "syscall" 12 13 "go.uber.org/zap" 14 15 "github.com/MetalBlockchain/metalgo/utils/logging" 16 ) 17 18 const DefaultFDLimit = 32 * 1024 19 20 // Set attempts to bump the Rlimit which has a soft (Cur) and a hard (Max) value. 21 // The soft limit is what is used by the kernel to report EMFILE errors. The hard 22 // limit is a secondary limit which the process can be bumped to without additional 23 // privileges. Bumping the Max limit further would require superuser privileges. 24 // If the current Max is below our recommendation we will warn on start. 25 // see: http://0pointer.net/blog/file-descriptor-limits.html 26 func Set(max uint64, log logging.Logger) error { 27 var rLimit syscall.Rlimit 28 err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit) 29 if err != nil { 30 return fmt.Errorf("error getting rlimit: %w", err) 31 } 32 33 if max > rLimit.Max { 34 return fmt.Errorf("error fd-limit: (%d) greater than max: (%d)", max, rLimit.Max) 35 } 36 37 rLimit.Cur = max 38 39 // set new limit 40 if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit); err != nil { 41 return fmt.Errorf("error setting fd-limit: %w", err) 42 } 43 44 // verify limit 45 if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit); err != nil { 46 return fmt.Errorf("error getting rlimit: %w", err) 47 } 48 49 if rLimit.Cur < DefaultFDLimit { 50 log.Warn("fd-limit is less than recommended and could result in reduced performance", 51 zap.Uint64("limit", rLimit.Cur), 52 zap.Uint64("recommendedLimit", DefaultFDLimit), 53 ) 54 } 55 56 return nil 57 }