From e515dd458267b8cbaa05d09b0cf55ec07f8dcf5b Mon Sep 17 00:00:00 2001 From: Dmitrii Stepanov Date: Wed, 23 Oct 2024 10:39:19 +0300 Subject: [PATCH] [#1444] config: Fix data race on morph component init It could be called for every shard on metabase resync concurrently and it is possible to get state with initialized client but not initialized contract hashes. Signed-off-by: Dmitrii Stepanov --- cmd/frostfs-node/accounting.go | 4 +--- cmd/frostfs-node/config.go | 8 ++++---- cmd/frostfs-node/morph.go | 8 +++++++- cmd/frostfs-node/netmap.go | 4 +--- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/cmd/frostfs-node/accounting.go b/cmd/frostfs-node/accounting.go index ec737f8a..1d065c22 100644 --- a/cmd/frostfs-node/accounting.go +++ b/cmd/frostfs-node/accounting.go @@ -13,9 +13,7 @@ import ( ) func initAccountingService(ctx context.Context, c *cfg) { - if c.cfgMorph.client == nil { - initMorphComponents(ctx, c) - } + c.initMorphComponents(ctx) balanceMorphWrapper, err := balance.NewFromMorph(c.cfgMorph.client, c.cfgAccounting.scriptHash, 0) fatalOnErr(err) diff --git a/cmd/frostfs-node/config.go b/cmd/frostfs-node/config.go index 9d2b7721..cf7e0da7 100644 --- a/cmd/frostfs-node/config.go +++ b/cmd/frostfs-node/config.go @@ -575,6 +575,9 @@ func (c *cfgGRPC) dropConnection(endpoint string) { } type cfgMorph struct { + initialized bool + guard sync.Mutex + client *client.Client notaryEnabled bool @@ -1455,10 +1458,7 @@ func (c *cfg) createTombstoneSource() *tombstone.ExpirationChecker { func (c *cfg) createContainerInfoProvider(ctx context.Context) container.InfoProvider { return container.NewInfoProvider(func() (container.Source, error) { - // threadsafe: called on init or on sighup when morph initialized - if c.cfgMorph.client == nil { - initMorphComponents(ctx, c) - } + c.initMorphComponents(ctx) cc, err := containerClient.NewFromMorph(c.cfgMorph.client, c.cfgContainer.scriptHash, 0, containerClient.TryNotary()) if err != nil { return nil, err diff --git a/cmd/frostfs-node/morph.go b/cmd/frostfs-node/morph.go index 197e5037..e8520905 100644 --- a/cmd/frostfs-node/morph.go +++ b/cmd/frostfs-node/morph.go @@ -28,7 +28,12 @@ const ( notaryDepositRetriesAmount = 300 ) -func initMorphComponents(ctx context.Context, c *cfg) { +func (c *cfg) initMorphComponents(ctx context.Context) { + c.cfgMorph.guard.Lock() + defer c.cfgMorph.guard.Unlock() + if c.cfgMorph.initialized { + return + } initMorphClient(ctx, c) lookupScriptHashesInNNS(c) // smart contract auto negotiation @@ -70,6 +75,7 @@ func initMorphComponents(ctx context.Context, c *cfg) { c.netMapSource = netmapSource c.cfgNetmap.wrapper = wrap + c.cfgMorph.initialized = true } func initMorphClient(ctx context.Context, c *cfg) { diff --git a/cmd/frostfs-node/netmap.go b/cmd/frostfs-node/netmap.go index 5e4585f8..0e057176 100644 --- a/cmd/frostfs-node/netmap.go +++ b/cmd/frostfs-node/netmap.go @@ -143,9 +143,7 @@ func initNetmapService(ctx context.Context, c *cfg) { parseAttributes(c) c.cfgNodeInfo.localInfo.SetStatus(netmapSDK.Offline) - if c.cfgMorph.client == nil { - initMorphComponents(ctx, c) - } + c.initMorphComponents(ctx) initNetmapState(c)