diff --git a/cmd/neofs-node/config.go b/cmd/neofs-node/config.go index 17176a75..36b166a7 100644 --- a/cmd/neofs-node/config.go +++ b/cmd/neofs-node/config.go @@ -422,18 +422,22 @@ func initShardOptions(c *cfg) { metabaseCfg := sc.Metabase() gcCfg := sc.GC() - piloramaCfg := sc.Pilorama() - piloramaPath := piloramaCfg.Path() - if piloramaPath == "" { - piloramaPath = filepath.Join(blobStorCfg.Path(), "pilorama.db") - } + var piloramaOpts []pilorama.Option - piloramaOpts := []pilorama.Option{ - pilorama.WithPath(piloramaPath), - pilorama.WithPerm(piloramaCfg.Perm()), - pilorama.WithNoSync(piloramaCfg.NoSync()), - pilorama.WithMaxBatchSize(piloramaCfg.MaxBatchSize()), - pilorama.WithMaxBatchDelay(piloramaCfg.MaxBatchDelay())} + piloramaCfg := sc.Pilorama() + if config.BoolSafe(c.appCfg.Sub("tree"), "enabled") { + piloramaPath := piloramaCfg.Path() + if piloramaPath == "" { + piloramaPath = filepath.Join(blobStorCfg.Path(), "pilorama.db") + } + + piloramaOpts = []pilorama.Option{ + pilorama.WithPath(piloramaPath), + pilorama.WithPerm(piloramaCfg.Perm()), + pilorama.WithNoSync(piloramaCfg.NoSync()), + pilorama.WithMaxBatchSize(piloramaCfg.MaxBatchSize()), + pilorama.WithMaxBatchDelay(piloramaCfg.MaxBatchDelay())} + } metaPath := metabaseCfg.Path() metaPerm := metabaseCfg.BoltDB().Perm() diff --git a/cmd/neofs-node/tree.go b/cmd/neofs-node/tree.go index 4be5ac09..12385a4f 100644 --- a/cmd/neofs-node/tree.go +++ b/cmd/neofs-node/tree.go @@ -3,10 +3,16 @@ package main import ( "context" + "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config" "github.com/nspcc-dev/neofs-node/pkg/services/tree" ) func initTreeService(c *cfg) { + if !config.BoolSafe(c.appCfg.Sub("tree"), "enabled") { + c.log.Info("tree service is not enabled, skip initialization") + return + } + c.treeService = tree.New( tree.WithContainerSource(c.cfgObject.cnrSource), tree.WithNetmapSource(c.netMapSource), diff --git a/config/example/node.yaml b/config/example/node.yaml index 07836381..46f3a967 100644 --- a/config/example/node.yaml +++ b/config/example/node.yaml @@ -99,6 +99,9 @@ object: put: pool_size_remote: 100 # number of async workers for remote PUT operations +tree: + enable: false + storage: # note: shard configuration can be omitted for relay node (see `node.relay`) shard_pool_size: 15 # size of per-shard worker pools used for PUT operations diff --git a/pkg/local_object_storage/shard/control.go b/pkg/local_object_storage/shard/control.go index 1faf44aa..c4a1e5ef 100644 --- a/pkg/local_object_storage/shard/control.go +++ b/pkg/local_object_storage/shard/control.go @@ -15,7 +15,11 @@ import ( // Open opens all Shard's components. func (s *Shard) Open() error { components := []interface{ Open() error }{ - s.blobStor, s.metaBase, s.pilorama, + s.blobStor, s.metaBase, + } + + if s.pilorama != nil { + components = append(components, s.pilorama) } if s.hasWriteCache() { @@ -41,7 +45,11 @@ func (s *Shard) Init() error { } components := []func() error{ - s.blobStor.Init, fMetabase, s.pilorama.Init, + s.blobStor.Init, fMetabase, + } + + if s.pilorama != nil { + components = append(components, s.pilorama.Init) } if s.hasWriteCache() { @@ -154,7 +162,11 @@ func (s *Shard) Close() error { components = append(components, s.writeCache) } - components = append(components, s.pilorama, s.blobStor, s.metaBase) + if s.pilorama != nil { + components = append(components, s.pilorama) + } + + components = append(components, s.blobStor, s.metaBase) for _, component := range components { if err := component.Close(); err != nil { diff --git a/pkg/local_object_storage/shard/shard.go b/pkg/local_object_storage/shard/shard.go index 48d7cc61..28d03f19 100644 --- a/pkg/local_object_storage/shard/shard.go +++ b/pkg/local_object_storage/shard/shard.go @@ -109,7 +109,10 @@ func New(opts ...Option) *Shard { metaBase: mb, writeCache: writeCache, tsSource: c.tsSource, - pilorama: pilorama.NewBoltForest(c.piloramaOpts...), + } + + if s.piloramaOpts != nil { + s.pilorama = pilorama.NewBoltForest(c.piloramaOpts...) } s.fillInfo() @@ -263,5 +266,7 @@ func (s *Shard) fillInfo() { if s.cfg.useWriteCache { s.cfg.info.WriteCacheInfo = s.writeCache.DumpInfo() } - s.cfg.info.PiloramaInfo = s.pilorama.DumpInfo() + if s.pilorama != nil { + s.cfg.info.PiloramaInfo = s.pilorama.DumpInfo() + } } diff --git a/pkg/local_object_storage/shard/tree.go b/pkg/local_object_storage/shard/tree.go index 33f120a9..f42a7b2b 100644 --- a/pkg/local_object_storage/shard/tree.go +++ b/pkg/local_object_storage/shard/tree.go @@ -1,14 +1,22 @@ package shard import ( + "errors" + "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/pilorama" cidSDK "github.com/nspcc-dev/neofs-sdk-go/container/id" ) var _ pilorama.Forest = (*Shard)(nil) +// ErrPiloramaDisabled is returned when pilorama was disabled in the configuration. +var ErrPiloramaDisabled = errors.New("plorama is disabled") + // TreeMove implements the pilorama.Forest interface. func (s *Shard) TreeMove(d pilorama.CIDDescriptor, treeID string, m *pilorama.Move) (*pilorama.LogMove, error) { + if s.pilorama == nil { + return nil, ErrPiloramaDisabled + } if s.GetMode() != ModeReadWrite { return nil, ErrReadOnlyMode } @@ -17,6 +25,9 @@ func (s *Shard) TreeMove(d pilorama.CIDDescriptor, treeID string, m *pilorama.Mo // TreeAddByPath implements the pilorama.Forest interface. func (s *Shard) TreeAddByPath(d pilorama.CIDDescriptor, treeID string, attr string, path []string, meta []pilorama.KeyValue) ([]pilorama.LogMove, error) { + if s.pilorama == nil { + return nil, ErrPiloramaDisabled + } if s.GetMode() != ModeReadWrite { return nil, ErrReadOnlyMode } @@ -25,6 +36,9 @@ func (s *Shard) TreeAddByPath(d pilorama.CIDDescriptor, treeID string, attr stri // TreeApply implements the pilorama.Forest interface. func (s *Shard) TreeApply(d pilorama.CIDDescriptor, treeID string, m *pilorama.Move) error { + if s.pilorama == nil { + return ErrPiloramaDisabled + } if s.GetMode() != ModeReadWrite { return ErrReadOnlyMode } @@ -33,20 +47,32 @@ func (s *Shard) TreeApply(d pilorama.CIDDescriptor, treeID string, m *pilorama.M // TreeGetByPath implements the pilorama.Forest interface. func (s *Shard) TreeGetByPath(cid cidSDK.ID, treeID string, attr string, path []string, latest bool) ([]pilorama.Node, error) { + if s.pilorama == nil { + return nil, ErrPiloramaDisabled + } return s.pilorama.TreeGetByPath(cid, treeID, attr, path, latest) } // TreeGetMeta implements the pilorama.Forest interface. func (s *Shard) TreeGetMeta(cid cidSDK.ID, treeID string, nodeID pilorama.Node) (pilorama.Meta, uint64, error) { + if s.pilorama == nil { + return pilorama.Meta{}, 0, ErrPiloramaDisabled + } return s.pilorama.TreeGetMeta(cid, treeID, nodeID) } // TreeGetChildren implements the pilorama.Forest interface. func (s *Shard) TreeGetChildren(cid cidSDK.ID, treeID string, nodeID pilorama.Node) ([]uint64, error) { + if s.pilorama == nil { + return nil, ErrPiloramaDisabled + } return s.pilorama.TreeGetChildren(cid, treeID, nodeID) } // TreeGetOpLog implements the pilorama.Forest interface. func (s *Shard) TreeGetOpLog(cid cidSDK.ID, treeID string, height uint64) (pilorama.Move, error) { + if s.pilorama == nil { + return pilorama.Move{}, ErrPiloramaDisabled + } return s.pilorama.TreeGetOpLog(cid, treeID, height) }