diff --git a/cmd/ipfs/util/ulimit.go b/cmd/ipfs/util/ulimit.go index 6500d6b7cca..d92579b2b30 100644 --- a/cmd/ipfs/util/ulimit.go +++ b/cmd/ipfs/util/ulimit.go @@ -1,6 +1,7 @@ package util import ( + "errors" "fmt" "os" "strconv" @@ -20,25 +21,26 @@ var ( setLimit func(uint64, uint64) error ) -// minimum file descriptor limit before we complain -const minFds = 2048 +// maxFds is the maximum number of file descriptors that go-ipfs +// can use. The default value is 2048. This can be overwritten by the +// IPFS_FD_MAX env variable +var maxFds = uint64(2048) -// default max file descriptor limit. -const maxFds = 8192 - -// userMaxFDs returns the value of IPFS_FD_MAX -func userMaxFDs() uint64 { +// setMaxFds sets the maxFds value from IPFS_FD_MAX +// env variable if it's present on the system +func setMaxFds() { // check if the IPFS_FD_MAX is set up and if it does // not have a valid fds number notify the user if val := os.Getenv("IPFS_FD_MAX"); val != "" { + fds, err := strconv.ParseUint(val, 10, 64) if err != nil { log.Errorf("bad value for IPFS_FD_MAX: %s", err) - return 0 + return } - return fds + + maxFds = fds } - return 0 } // ManageFdLimit raise the current max file descriptor count @@ -48,12 +50,7 @@ func ManageFdLimit() (changed bool, newLimit uint64, err error) { return false, 0, nil } - targetLimit := uint64(maxFds) - userLimit := userMaxFDs() - if userLimit > 0 { - targetLimit = userLimit - } - + setMaxFds() soft, hard, err := getLimit() if err != nil { return false, 0, err @@ -68,47 +65,23 @@ func ManageFdLimit() (changed bool, newLimit uint64, err error) { // the hard limit acts as a ceiling for the soft limit // an unprivileged process may only set it's soft limit to a // alue in the range from 0 up to the hard limit - err = setLimit(targetLimit, targetLimit) - switch err { - case nil: - newLimit = targetLimit - case syscall.EPERM: - // lower limit if necessary. - if targetLimit > hard { - targetLimit = hard + if err = setLimit(maxFds, maxFds); err != nil { + if err != syscall.EPERM { + return false, 0, fmt.Errorf("error setting: ulimit: %s", err) } // the process does not have permission so we should only // set the soft value - err = setLimit(targetLimit, hard) - if err != nil { - err = fmt.Errorf("error setting ulimit wihout hard limit: %s", err) - break - } - newLimit = targetLimit - - // Warn on lowered limit. - - if newLimit < userLimit { - err = fmt.Errorf( - "failed to raise ulimit to IPFS_FD_MAX (%d): set to %d", - userLimit, - newLimit, + if maxFds > hard { + return false, 0, errors.New( + "cannot set rlimit, IPFS_FD_MAX is larger than the hard limit", ) - break } - if userLimit == 0 && newLimit < minFds { - err = fmt.Errorf( - "failed to raise ulimit to minimum %d: set to %d", - minFds, - newLimit, - ) - break + if err = setLimit(maxFds, hard); err != nil { + return false, 0, fmt.Errorf("error setting ulimit wihout hard limit: %s", err) } - default: - err = fmt.Errorf("error setting: ulimit: %s", err) } - return newLimit > 0, newLimit, err + return true, maxFds, nil }