mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-21 10:27:46 +08:00
88 lines
2.1 KiB
Go
88 lines
2.1 KiB
Go
package util
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"strconv"
|
|
"syscall"
|
|
|
|
logging "github.com/ipfs/go-log"
|
|
)
|
|
|
|
var log = logging.Logger("ulimit")
|
|
|
|
var (
|
|
supportsFDManagement = false
|
|
|
|
// getlimit returns the soft and hard limits of file descriptors counts
|
|
getLimit func() (uint64, uint64, error)
|
|
// set limit sets the soft and hard limits of file descriptors counts
|
|
setLimit func(uint64, uint64) error
|
|
)
|
|
|
|
// 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)
|
|
|
|
// 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
|
|
}
|
|
|
|
maxFds = fds
|
|
}
|
|
}
|
|
|
|
// ManageFdLimit raise the current max file descriptor count
|
|
// of the process based on the IPFS_FD_MAX value
|
|
func ManageFdLimit() (changed bool, newLimit uint64, err error) {
|
|
if !supportsFDManagement {
|
|
return false, 0, nil
|
|
}
|
|
|
|
setMaxFds()
|
|
soft, hard, err := getLimit()
|
|
if err != nil {
|
|
return false, 0, err
|
|
}
|
|
|
|
if maxFds <= soft {
|
|
return false, 0, nil
|
|
}
|
|
|
|
// the soft limit is the value that the kernel enforces for the
|
|
// corresponding resource
|
|
// 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
|
|
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
|
|
if maxFds > hard {
|
|
return false, 0, errors.New(
|
|
"cannot set rlimit, IPFS_FD_MAX is larger than the hard limit",
|
|
)
|
|
}
|
|
|
|
if err = setLimit(maxFds, hard); err != nil {
|
|
return false, 0, fmt.Errorf("error setting ulimit wihout hard limit: %s", err)
|
|
}
|
|
}
|
|
|
|
return true, maxFds, nil
|
|
}
|