diff --git a/core/commands/swarm.go b/core/commands/swarm.go index b82ca519a03..a213db6f74f 100644 --- a/core/commands/swarm.go +++ b/core/commands/swarm.go @@ -394,7 +394,7 @@ For permanent limits set Swarm.ResourceMgr.Limits in the $IPFS_PATH/config file. } if node.ResourceManager == nil { - return fmt.Errorf("no resource manager available, make sure the daemon is running") + return fmt.Errorf("no resource manager available: make sure the daemon is running with Swarm.ResourceMgr.Enabled in the config") } scope := req.Arguments[0] diff --git a/core/node/groups.go b/core/node/groups.go index 48ee175a33c..992c9ab446a 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "os" "time" blockstore "github.com/ipfs/go-ipfs-blockstore" @@ -140,12 +141,22 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config) fx.Option { "If you want to continue running a circuit v1 relay, please use the standalone relay daemon: https://github.com/libp2p/go-libp2p-relay-daemon (with RelayV1.Enabled: true)") } + // Swarm.ResourceMgr + enableResourceMgr := cfg.Swarm.ResourceMgr.Enabled.WithDefault(false) + /// ENV overrides Config (if present) + switch os.Getenv("IPFS_RCMGR") { + case "0", "false": + enableResourceMgr = false + case "1", "true": + enableResourceMgr = true + } + // Gather all the options opts := fx.Options( BaseLibP2P, // Services (resource management) - fx.Provide(libp2p.ResourceManager(cfg.Swarm.ResourceMgr)), + maybeProvide(libp2p.ResourceManager(cfg.Swarm.ResourceMgr), enableResourceMgr), fx.Provide(libp2p.AddrFilters(cfg.Swarm.AddrFilters)), fx.Provide(libp2p.AddrsFactory(cfg.Addresses.Announce, cfg.Addresses.AppendAnnounce, cfg.Addresses.NoAnnounce)), diff --git a/core/node/libp2p/rcmgr.go b/core/node/libp2p/rcmgr.go index c4af75ae142..c6ab94ec489 100644 --- a/core/node/libp2p/rcmgr.go +++ b/core/node/libp2p/rcmgr.go @@ -26,66 +26,48 @@ func ResourceManager(cfg cfg.ResourceMgr) func(fx.Lifecycle, repo.Repo) (network var manager network.ResourceManager var opts Libp2pOpts - // Config Swarm.ResourceMgr.Enabled decides if we run a real manager - enabled := cfg.Enabled.WithDefault(false) - - /// ENV overrides Config (if present) - // TODO: document IPFS_RCMGR and IPFS_DEBUG_RCMGR in docs/environment-variables.md - switch os.Getenv("IPFS_RCMGR") { - case "0", "false": - enabled = false - case "1", "true": - enabled = true + log.Debug("libp2p resource manager is enabled") + + // Try defaults from limit.json if provided + // (a convention to make libp2p team life easier) + // TODO: look in current dir and in IPFS_PATH + _, err := os.Stat(NetLimitDefaultFilename) + if !errors.Is(err, os.ErrNotExist) { + limitFile, err := os.Open(NetLimitDefaultFilename) + if err != nil { + return nil, opts, fmt.Errorf("error opening limit JSON file %s: %w", + NetLimitDefaultFilename, err) + } + defer limitFile.Close() //nolint:errcheck + limiter, err = rcmgr.NewDefaultLimiterFromJSON(limitFile) + if err != nil { + return nil, opts, fmt.Errorf("error parsing limit file: %w", err) + } + + } else { + // Use defaults from go-libp2p + log.Debug("limit file %s not found, creating a default resource manager", NetLimitDefaultFilename) + limiter = rcmgr.NewDefaultLimiter() } - if enabled { - log.Debug("libp2p resource manager is enabled") - - // Try defaults from limit.json if provided - // (a convention to make libp2p team life easier) - // TODO: look in current dir and in IPFS_PATH - _, err := os.Stat(NetLimitDefaultFilename) - if !errors.Is(err, os.ErrNotExist) { - limitFile, err := os.Open(NetLimitDefaultFilename) - if err != nil { - return nil, opts, fmt.Errorf("error opening limit JSON file %s: %w", - NetLimitDefaultFilename, err) - } - defer limitFile.Close() //nolint:errcheck - limiter, err = rcmgr.NewDefaultLimiterFromJSON(limitFile) - if err != nil { - return nil, opts, fmt.Errorf("error parsing limit file: %w", err) - } - - } else { - // Use defaults from go-libp2p - log.Debug("limit file %s not found, creating a default resource manager", NetLimitDefaultFilename) - limiter = rcmgr.NewDefaultLimiter() - } + libp2p.SetDefaultServiceLimits(limiter) - libp2p.SetDefaultServiceLimits(limiter) + var ropts []rcmgr.Option + if os.Getenv("IPFS_DEBUG_RCMGR") != "" { + ropts = append(ropts, rcmgr.WithTrace("rcmgr.json.gz")) + } - var ropts []rcmgr.Option - if os.Getenv("IPFS_DEBUG_RCMGR") != "" { - ropts = append(ropts, rcmgr.WithTrace("rcmgr.json.gz")) - } + manager, err = rcmgr.NewResourceManager(limiter, ropts...) + if err != nil { + return nil, opts, fmt.Errorf("error creating resource manager: %w", err) + } - manager, err = rcmgr.NewResourceManager(limiter, ropts...) + // Apply user-defined Swarm.ResourceMgr.Limits + for scope, userLimit := range cfg.Limits { + err := NetSetLimit(manager, scope, userLimit) if err != nil { - return nil, opts, fmt.Errorf("error creating resource manager: %w", err) + return nil, opts, fmt.Errorf("error while applying Swarm.ResourceMgr.Limits for scope %q: %w", scope, err) } - - // Apply user-defined Swarm.ResourceMgr.Limits - for scope, userLimit := range cfg.Limits { - err := NetSetLimit(manager, scope, userLimit) - if err != nil { - return nil, opts, fmt.Errorf("error while applying Swarm.ResourceMgr.Limits for scope %q: %w", scope, err) - } - } - - } else { - log.Debug("libp2p resource manager is disabled") - manager = network.NullResourceManager } opts.Opts = append(opts.Opts, libp2p.ResourceManager(manager))