mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-21 10:27:46 +08:00
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: 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
115 lines
2.5 KiB
Go
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
|
|
}
|