Skip to content

Commit

Permalink
Requested changes
Browse files Browse the repository at this point in the history
Signed-off-by: Antonio Navarro <antnavper@gmail.com>
  • Loading branch information
ajnavarro committed Nov 10, 2022
1 parent 3c40dfd commit 03614f4
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 39 deletions.
4 changes: 2 additions & 2 deletions config/swarm.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,8 @@ type ResourceMgr struct {
Enabled Flag `json:",omitempty"`
Limits *rcmgr.LimitConfig `json:",omitempty"`

MaxMemory int64 `json:",omitempty"`
MaxFileDescriptors int `json:",omitempty"`
MaxMemory OptionalString `json:",omitempty"`
MaxFileDescriptors OptionalInteger `json:",omitempty"`

// A list of multiaddrs that can bypass normal system limits (but are still
// limited by the allowlist scope). Convenience config around
Expand Down
21 changes: 13 additions & 8 deletions core/node/libp2p/rcmgr.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@ import (

"github.com/benbjohnson/clock"
logging "github.com/ipfs/go-log/v2"
config "github.com/ipfs/kubo/config"
"github.com/ipfs/kubo/core/node/helpers"
"github.com/ipfs/kubo/repo"

"github.com/libp2p/go-libp2p"
"github.com/libp2p/go-libp2p/core/network"
"github.com/libp2p/go-libp2p/core/peer"
Expand All @@ -21,8 +17,11 @@ import (
rcmgrObs "github.com/libp2p/go-libp2p/p2p/host/resource-manager/obs"
"github.com/multiformats/go-multiaddr"
"go.opencensus.io/stats/view"

"go.uber.org/fx"

config "github.com/ipfs/kubo/config"
"github.com/ipfs/kubo/core/node/helpers"
"github.com/ipfs/kubo/repo"
)

const NetLimitDefaultFilename = "limit.json"
Expand Down Expand Up @@ -53,7 +52,10 @@ func ResourceManager(cfg config.SwarmConfig) interface{} {
return nil, opts, fmt.Errorf("opening IPFS_PATH: %w", err)
}

limits := createDefaultLimitConfig(cfg)
limits, err := createDefaultLimitConfig(cfg)
if err != nil {
return nil, opts, err
}

if cfg.ResourceMgr.Limits != nil {
l := *cfg.ResourceMgr.Limits
Expand Down Expand Up @@ -259,7 +261,7 @@ func scopeToLimit(s *network.ScopeStat) *rcmgr.BaseLimit {
}
}

// compareLimits copares stat and limit.
// compareLimits compares stat and limit.
// If any of the stats value are equals or above the specified percentage,
// stat object is returned.
func compareLimits(stat, limit *rcmgr.BaseLimit, percentage int) *rcmgr.BaseLimit {
Expand Down Expand Up @@ -511,7 +513,10 @@ func NetResetLimit(mgr network.ResourceManager, repo repo.Repo, scope string) (r
return result, fmt.Errorf("reading config to reset limit: %w", err)
}

defaults := createDefaultLimitConfig(cfg.Swarm)
defaults, err := createDefaultLimitConfig(cfg.Swarm)
if err != nil {
return result, fmt.Errorf("creating default limit config: %w", err)
}

if cfg.Swarm.ResourceMgr.Limits == nil {
cfg.Swarm.ResourceMgr.Limits = &rcmgr.LimitConfig{}
Expand Down
30 changes: 16 additions & 14 deletions core/node/libp2p/rcmgr_defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package libp2p
import (
"math"

"github.com/ipfs/kubo/config"
"github.com/ipfs/kubo/core/node/libp2p/fd"
"github.com/dustin/go-humanize"
"github.com/libp2p/go-libp2p"
rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager"
"github.com/pbnjay/memory"

"github.com/ipfs/kubo/config"
"github.com/ipfs/kubo/core/node/libp2p/fd"
)

// We are doing some magic when parsing config files (we are using a map[string]interface{} to compare config files).
Expand Down Expand Up @@ -87,20 +89,20 @@ var noLimitIncrease = rcmgr.BaseLimitIncrease{
// maxMemory, maxFD, or maxConns with Swarm.HighWater.ConnMgr.
// 3. Power user - They specify all the limits they want set via Swarm.ResourceMgr.Limits
// and we don't do any defaults/overrides. We pass that config blindly into libp2p resource manager.
func createDefaultLimitConfig(cfg config.SwarmConfig) rcmgr.LimitConfig {

if cfg.ResourceMgr.MaxMemory == 0 {
cfg.ResourceMgr.MaxMemory = int64(memory.TotalMemory()) / 8
func createDefaultLimitConfig(cfg config.SwarmConfig) (rcmgr.LimitConfig, error) {
maxMemoryDefaultString := humanize.Bytes(uint64(memory.TotalMemory()) / 8)
maxMemoryString := cfg.ResourceMgr.MaxMemory.WithDefault(maxMemoryDefaultString)
maxMemory, err := humanize.ParseBytes(maxMemoryString)
if err != nil {
return rcmgr.LimitConfig{}, err
}

if cfg.ResourceMgr.MaxFileDescriptors == 0 {
cfg.ResourceMgr.MaxFileDescriptors = fd.GetNumFDs() / 2
}
numFD := cfg.ResourceMgr.MaxFileDescriptors.WithDefault(int64(fd.GetNumFDs()) / 2)

scalingLimitConfig := rcmgr.ScalingLimitConfig{
SystemBaseLimit: rcmgr.BaseLimit{
Memory: cfg.ResourceMgr.MaxMemory,
FD: cfg.ResourceMgr.MaxFileDescriptors,
Memory: int64(maxMemory),
FD: int(numFD),

// By default, we just limit connections on the inbound side.
// Note that the limit gets adjusted below if "cfg.ConnMgr.HighWater" is set.
Expand Down Expand Up @@ -165,7 +167,7 @@ func createDefaultLimitConfig(cfg config.SwarmConfig) rcmgr.LimitConfig {
// This doesn't protect us against intentional DoS attacks since an attacker can easily spin up multiple peers.
// We specify this limit against unintentional DoS attacks (e.g., a peer has a bug and is sending too much traffic intentionally).
// In that case we want to keep that peer's resource consumption contained.
// To keep this simple, we only constrain inbound connections and connections.
// To keep this simple, we only constrain inbound connections and streams.
PeerBaseLimit: rcmgr.BaseLimit{
Memory: bigEnough,
FD: bigEnough,
Expand Down Expand Up @@ -193,7 +195,7 @@ func createDefaultLimitConfig(cfg config.SwarmConfig) rcmgr.LimitConfig {
// Whatever limits libp2p has specifically tuned for its protocols/services we'll apply.
libp2p.SetDefaultServiceLimits(&scalingLimitConfig)

defaultLimitConfig := scalingLimitConfig.Scale(cfg.ResourceMgr.MaxMemory, cfg.ResourceMgr.MaxFileDescriptors)
defaultLimitConfig := scalingLimitConfig.Scale(int64(maxMemory), int(numFD))

// If a high water mark is set:
if cfg.ConnMgr.Type == "basic" {
Expand All @@ -202,5 +204,5 @@ func createDefaultLimitConfig(cfg config.SwarmConfig) rcmgr.LimitConfig {
log.Info("adjusted default resource manager System.Conns limits to match ConnMgr.HighWater value of %s", cfg.ConnMgr.HighWater)
}

return defaultLimitConfig
return defaultLimitConfig, nil
}
7 changes: 0 additions & 7 deletions core/node/libp2p/rcmgr_logging.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ type loggingResourceManager struct {

mut sync.Mutex
limitExceededErrs map[string]int
previousErrors bool
}

type loggingScope struct {
Expand Down Expand Up @@ -51,19 +50,13 @@ func (n *loggingResourceManager) start(ctx context.Context) {
n.limitExceededErrs = make(map[string]int)

for e, count := range errs {
n.previousErrors = true
n.logger.Errorf("Resource limits were exceeded %d times with error %q.", count, e)
}

if len(errs) != 0 {
n.logger.Errorf("Consider inspecting logs and raising the resource manager limits. Documentation: https://github.com/ipfs/kubo/blob/master/docs/config.md#swarmresourcemgr")
}

if len(errs) == 0 && n.previousErrors {
n.previousErrors = false
n.logger.Errorf("Resrouce limits are no longer being exceeded.")
}

n.mut.Unlock()
case <-ctx.Done():
return
Expand Down
14 changes: 8 additions & 6 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -1818,17 +1818,19 @@ Type: `flag`

#### `Swarm.ResourceMgr.MaxMemory`

Define the maximum amount of memory used by libp2p.
The maximum amount of memory that the libp2p resource manager will allow.

Default: `[TOTAL_MEMORY]/8`
Type: `integer64`
Default: `[TOTAL_SYSTEM_MEMORY]/8`
Type: `optionalBytes`

#### `Swarm.ResourceMgr.MaxFileDescriptors`

Define the maximum amount of file descriptors used by libp2p.
Define the maximum number of file descriptors that libp2p can use.

Default `[TOTAL_FILE_DESCRIPTORS]/2`
Type: `integer`
This param is ignored on Windows.

Default `[TOTAL_SYSTEM_FILE_DESCRIPTORS]/2`
Type: `optionalInteger`

#### `Swarm.ResourceMgr.Limits`

Expand Down
4 changes: 2 additions & 2 deletions test/sharness/t0139-swarm-rcmgr.sh
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,13 @@ test_expect_success 'connected: swarm stats all working properly' '
test_expect_success 'ResourceMgr enabled: swarm stats' '
ipfs swarm stats all --enc=json | tee json &&
jq -e .System.Memory < json &&
jq -e .System.FD < json &&
jq -e .System.Conns < json &&
jq -e .System.ConnsInbound < json &&
jq -e .System.ConnsOutbound < json &&
jq -e .System.FD < json &&
jq -e .System.Streams < json &&
jq -e .System.StreamsInbound < json &&
jq -e .System.StreamsOutbound < json &&
jq -e .System.Streams < json &&
jq -e .Transient.Memory < json
'

Expand Down

0 comments on commit 03614f4

Please sign in to comment.