kubo/cmd/ipfs/util/ulimit.go
Andrew Gillis 20d9660a64
Some checks are pending
CodeQL / codeql (push) Waiting to run
Docker Build / docker-build (push) Waiting to run
Gateway Conformance / gateway-conformance (push) Waiting to run
Gateway Conformance / gateway-conformance-libp2p-experiment (push) Waiting to run
Go Build / go-build (push) Waiting to run
Go Check / go-check (push) Waiting to run
Go Lint / go-lint (push) Waiting to run
Go Test / go-test (push) Waiting to run
Interop / interop-prep (push) Waiting to run
Interop / helia-interop (push) Blocked by required conditions
Interop / ipfs-webui (push) Blocked by required conditions
Sharness / sharness-test (push) Waiting to run
Spell Check / spellcheck (push) Waiting to run
chore: use go-log/v2 (#10801)
* chore: update to go-log/v2

go-log v2 has been out for quite a while now and it is time to deprecate v1.

Replace all use of go-log with go-log/v2
Makes /api/v0/log/tail useful over HTTP
Updates dependencies that have moved to go-lov/v2
Removes support for ContextWithLoggable as this is not needed for tracing-like functionality
- Replaces: PR #8765
- Closes issue #8753
- Closes issue #9245
- Closes issue #10809

Other fixes:
* update go-ipfs-cmds
* update http logs test
* fix test
* Read/send one line of log data at a time
* Update -log-level docs
2025-05-19 13:04:05 -07:00

115 lines
2.5 KiB
Go

package util
import (
"fmt"
"os"
"strconv"
"syscall"
logging "github.com/ipfs/go-log/v2"
)
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
)
// minimum file descriptor limit before we complain.
const minFds = 2048
// default max file descriptor limit.
const maxFds = 8192
// userMaxFDs returns the value of IPFS_FD_MAX.
func userMaxFDs() uint64 {
// 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 fds
}
return 0
}
// 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
}
targetLimit := uint64(maxFds)
userLimit := userMaxFDs()
if userLimit > 0 {
targetLimit = userLimit
}
soft, hard, err := getLimit()
if err != nil {
return false, 0, err
}
if targetLimit <= 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 its soft limit to a
// value 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
}
// 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 without hard limit: %w", 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,
)
break
}
if userLimit == 0 && newLimit < minFds {
err = fmt.Errorf(
"failed to raise ulimit to minimum %d: set to %d",
minFds,
newLimit,
)
break
}
default:
err = fmt.Errorf("error setting: ulimit: %w", err)
}
return newLimit > 0, newLimit, err
}