[#1121] node: Change mode of shard components

Signed-off-by: Alexander Chuprov <a.chuprov@yadro.com>
This commit is contained in:
Alexander Chuprov 2024-06-04 16:28:47 +03:00 committed by Evgenii Stratonikov
parent 6f2187a420
commit 806236da78
47 changed files with 194 additions and 100 deletions

View file

@ -8,6 +8,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/testutil" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/testutil"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger/test" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger/test"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -23,7 +24,7 @@ func TestBlobovniczaTree_Concurrency(t *testing.T) {
WithBlobovniczaShallowWidth(10), WithBlobovniczaShallowWidth(10),
WithBlobovniczaShallowDepth(1), WithBlobovniczaShallowDepth(1),
WithRootPath(t.TempDir())) WithRootPath(t.TempDir()))
require.NoError(t, st.Open(false)) require.NoError(t, st.Open(mode.ComponentReadWrite))
require.NoError(t, st.Init()) require.NoError(t, st.Init())
defer func() { defer func() {
require.NoError(t, st.Close()) require.NoError(t, st.Close())

View file

@ -8,6 +8,7 @@ import (
"strings" "strings"
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs" "git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util"
"go.uber.org/zap" "go.uber.org/zap"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
@ -16,9 +17,9 @@ import (
var errFailedToChangeExtensionReadOnly = errors.New("failed to change blobovnicza extension: read only mode") var errFailedToChangeExtensionReadOnly = errors.New("failed to change blobovnicza extension: read only mode")
// Open opens blobovnicza tree. // Open opens blobovnicza tree.
func (b *Blobovniczas) Open(readOnly bool) error { func (b *Blobovniczas) Open(mode mode.ComponentMode) error {
b.readOnly = readOnly b.readOnly = mode.ReadOnly()
b.metrics.SetMode(readOnly) b.metrics.SetMode(mode)
b.metrics.SetRebuildStatus(rebuildStatusNotStarted) b.metrics.SetRebuildStatus(rebuildStatusNotStarted)
b.openManagers() b.openManagers()
return nil return nil

View file

@ -11,6 +11,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobovnicza" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobovnicza"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/internal/blobstortest" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/internal/blobstortest"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -54,7 +55,7 @@ func openAndCloseTestTree(t *testing.T, depth, width uint64, path string) {
WithBlobovniczaShallowWidth(width), WithBlobovniczaShallowWidth(width),
WithRootPath(path), WithRootPath(path),
) )
require.NoError(t, blz.Open(false)) require.NoError(t, blz.Open(mode.ComponentReadWrite))
require.NoError(t, blz.Init()) require.NoError(t, blz.Init())
require.NoError(t, blz.Close()) require.NoError(t, blz.Close())
} }
@ -85,7 +86,7 @@ func TestObjectsAvailableAfterDepthAndWidthEdit(t *testing.T) {
WithRootPath(rootDir), WithRootPath(rootDir),
) )
require.NoError(t, blz.Open(false)) require.NoError(t, blz.Open(mode.ComponentReadWrite))
require.NoError(t, blz.Init()) require.NoError(t, blz.Init())
obj35 := blobstortest.NewObject(10 * 1024) obj35 := blobstortest.NewObject(10 * 1024)
@ -123,7 +124,7 @@ func TestObjectsAvailableAfterDepthAndWidthEdit(t *testing.T) {
WithRootPath(rootDir), WithRootPath(rootDir),
) )
require.NoError(t, blz.Open(false)) require.NoError(t, blz.Open(mode.ComponentReadWrite))
require.NoError(t, blz.Init()) require.NoError(t, blz.Init())
gRes, err = blz.Get(context.Background(), common.GetPrm{ gRes, err = blz.Get(context.Background(), common.GetPrm{
@ -160,7 +161,7 @@ func TestObjectsAvailableAfterDepthAndWidthEdit(t *testing.T) {
WithBlobovniczaShallowWidth(5), WithBlobovniczaShallowWidth(5),
WithRootPath(rootDir), WithRootPath(rootDir),
) )
require.NoError(t, blz.Open(false)) require.NoError(t, blz.Open(mode.ComponentReadWrite))
require.NoError(t, blz.Init()) require.NoError(t, blz.Init())
gRes, err = blz.Get(context.Background(), common.GetPrm{ gRes, err = blz.Get(context.Background(), common.GetPrm{

View file

@ -10,6 +10,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/internal/blobstortest" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/internal/blobstortest"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger/test" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger/test"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -24,7 +25,7 @@ func TestExistsInvalidStorageID(t *testing.T) {
WithBlobovniczaShallowDepth(2), WithBlobovniczaShallowDepth(2),
WithRootPath(dir), WithRootPath(dir),
WithBlobovniczaSize(1<<20)) WithBlobovniczaSize(1<<20))
require.NoError(t, b.Open(false)) require.NoError(t, b.Open(mode.ComponentReadWrite))
require.NoError(t, b.Init()) require.NoError(t, b.Init())
defer func() { require.NoError(t, b.Close()) }() defer func() { require.NoError(t, b.Close()) }()

View file

@ -4,6 +4,7 @@ import (
"context" "context"
"testing" "testing"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test" oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -18,7 +19,7 @@ func TestIterateSortedLeavesAndDBPathsAreSame(t *testing.T) {
WithRootPath(t.TempDir()), WithRootPath(t.TempDir()),
) )
blz.createDBInAdvance = true blz.createDBInAdvance = true
require.NoError(t, blz.Open(false)) require.NoError(t, blz.Open(mode.ComponentReadWrite))
require.NoError(t, blz.Init()) require.NoError(t, blz.Init())
defer func() { defer func() {
require.NoError(t, blz.Close()) require.NoError(t, blz.Close())

View file

@ -4,6 +4,7 @@ import (
"time" "time"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobovnicza" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobovnicza"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
) )
const ( const (
@ -18,7 +19,7 @@ type Metrics interface {
SetParentID(parentID string) SetParentID(parentID string)
SetMode(readOnly bool) SetMode(mode.ComponentMode)
Close() Close()
SetRebuildStatus(status string) SetRebuildStatus(status string)
@ -37,7 +38,7 @@ type Metrics interface {
type noopMetrics struct{} type noopMetrics struct{}
func (m *noopMetrics) SetParentID(string) {} func (m *noopMetrics) SetParentID(string) {}
func (m *noopMetrics) SetMode(bool) {} func (m *noopMetrics) SetMode(mode.ComponentMode) {}
func (m *noopMetrics) Close() {} func (m *noopMetrics) Close() {}
func (m *noopMetrics) SetRebuildStatus(string) {} func (m *noopMetrics) SetRebuildStatus(string) {}
func (m *noopMetrics) SetRebuildPercent(uint32) {} func (m *noopMetrics) SetRebuildPercent(uint32) {}

View file

@ -11,6 +11,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobovnicza" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobovnicza"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/internal/blobstortest" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/internal/blobstortest"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger/test" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger/test"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object" objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
@ -138,7 +139,7 @@ func testRebuildFailoverValidate(t *testing.T, dir string, obj *objectSDK.Object
WithBlobovniczaSize(100*1024*1024), WithBlobovniczaSize(100*1024*1024),
WithWaitBeforeDropDB(0), WithWaitBeforeDropDB(0),
WithOpenedCacheSize(1000)) WithOpenedCacheSize(1000))
require.NoError(t, b.Open(false)) require.NoError(t, b.Open(mode.ComponentReadWrite))
require.NoError(t, b.Init()) require.NoError(t, b.Init())
var dPrm common.DeletePrm var dPrm common.DeletePrm

View file

@ -8,6 +8,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/internal/blobstortest" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/internal/blobstortest"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger/test" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger/test"
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id" oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -53,7 +54,7 @@ func TestBlobovniczaTreeRebuildLargeObject(t *testing.T) {
WithWaitBeforeDropDB(0), WithWaitBeforeDropDB(0),
WithOpenedCacheSize(1000), WithOpenedCacheSize(1000),
WithMoveBatchSize(3)) WithMoveBatchSize(3))
require.NoError(t, b.Open(false)) require.NoError(t, b.Open(mode.ComponentReadWrite))
require.NoError(t, b.Init()) require.NoError(t, b.Init())
obj := blobstortest.NewObject(64 * 1024) // 64KB object obj := blobstortest.NewObject(64 * 1024) // 64KB object
@ -81,7 +82,7 @@ func TestBlobovniczaTreeRebuildLargeObject(t *testing.T) {
WithWaitBeforeDropDB(0), WithWaitBeforeDropDB(0),
WithOpenedCacheSize(1000), WithOpenedCacheSize(1000),
WithMoveBatchSize(3)) WithMoveBatchSize(3))
require.NoError(t, b.Open(false)) require.NoError(t, b.Open(mode.ComponentReadWrite))
require.NoError(t, b.Init()) require.NoError(t, b.Init())
metaStub := &storageIDUpdateStub{ metaStub := &storageIDUpdateStub{
@ -120,7 +121,7 @@ func testBlobovniczaTreeRebuildHelper(t *testing.T, sourceDepth, sourceWidth, ta
WithWaitBeforeDropDB(0), WithWaitBeforeDropDB(0),
WithOpenedCacheSize(1000), WithOpenedCacheSize(1000),
WithMoveBatchSize(3)) WithMoveBatchSize(3))
require.NoError(t, b.Open(false)) require.NoError(t, b.Open(mode.ComponentReadWrite))
require.NoError(t, b.Init()) require.NoError(t, b.Init())
eg, egCtx := errgroup.WithContext(context.Background()) eg, egCtx := errgroup.WithContext(context.Background())
@ -161,7 +162,7 @@ func testBlobovniczaTreeRebuildHelper(t *testing.T, sourceDepth, sourceWidth, ta
WithWaitBeforeDropDB(0), WithWaitBeforeDropDB(0),
WithOpenedCacheSize(1000), WithOpenedCacheSize(1000),
WithMoveBatchSize(50)) WithMoveBatchSize(50))
require.NoError(t, b.Open(false)) require.NoError(t, b.Open(mode.ComponentReadWrite))
require.NoError(t, b.Init()) require.NoError(t, b.Init())
for addr, storageID := range storageIDs { for addr, storageID := range storageIDs {

View file

@ -4,12 +4,13 @@ import (
"context" "context"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/compression" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/compression"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
) )
// Storage represents key-value object storage. // Storage represents key-value object storage.
// It is used as a building block for a blobstor of a shard. // It is used as a building block for a blobstor of a shard.
type Storage interface { type Storage interface {
Open(readOnly bool) error Open(mode mode.ComponentMode) error
Init() error Init() error
Close() error Close() error

View file

@ -27,15 +27,14 @@ func (b *BlobStor) Open(ctx context.Context, mode mode.Mode) error {
return nil return nil
} }
func (b *BlobStor) openBlobStor(ctx context.Context, mode mode.Mode) error { func (b *BlobStor) openBlobStor(ctx context.Context, mod mode.Mode) error {
readOnly := mode.ReadOnly()
for i := range b.storage { for i := range b.storage {
select { select {
case <-ctx.Done(): case <-ctx.Done():
return ctx.Err() return ctx.Err()
default: default:
} }
err := b.storage[i].Storage.Open(readOnly) err := b.storage[i].Storage.Open(mode.ConvertToComponentMode(mod))
if err != nil { if err != nil {
return err return err
} }

View file

@ -1,13 +1,14 @@
package fstree package fstree
import ( import (
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util"
) )
// Open implements common.Storage. // Open implements common.Storage.
func (t *FSTree) Open(ro bool) error { func (t *FSTree) Open(mode mode.ComponentMode) error {
t.readOnly = ro t.readOnly = mode.ReadOnly()
t.metrics.SetMode(ro) t.metrics.SetMode(mode)
return nil return nil
} }

View file

@ -6,6 +6,7 @@ import (
"testing" "testing"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr"
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object" objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test" oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
@ -43,7 +44,7 @@ func TestObjectCounter(t *testing.T) {
WithDepth(2), WithDepth(2),
WithDirNameLen(2), WithDirNameLen(2),
WithFileCounter(counter)) WithFileCounter(counter))
require.NoError(t, fst.Open(false)) require.NoError(t, fst.Open(mode.ComponentReadWrite))
require.NoError(t, fst.Init()) require.NoError(t, fst.Init())
counterValue := counter.Value() counterValue := counter.Value()

View file

@ -1,11 +1,15 @@
package fstree package fstree
import "time" import (
"time"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
)
type Metrics interface { type Metrics interface {
SetParentID(parentID string) SetParentID(parentID string)
SetMode(readOnly bool) SetMode(mode mode.ComponentMode)
Close() Close()
Iterate(d time.Duration, success bool) Iterate(d time.Duration, success bool)
@ -20,7 +24,7 @@ type Metrics interface {
type noopMetrics struct{} type noopMetrics struct{}
func (m *noopMetrics) SetParentID(string) {} func (m *noopMetrics) SetParentID(string) {}
func (m *noopMetrics) SetMode(bool) {} func (m *noopMetrics) SetMode(mode.ComponentMode) {}
func (m *noopMetrics) Close() {} func (m *noopMetrics) Close() {}
func (m *noopMetrics) Iterate(time.Duration, bool) {} func (m *noopMetrics) Iterate(time.Duration, bool) {}
func (m *noopMetrics) Delete(time.Duration, bool) {} func (m *noopMetrics) Delete(time.Duration, bool) {}

View file

@ -7,6 +7,7 @@ import (
objectCore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object" objectCore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -14,13 +15,13 @@ import (
// cons must return a storage which is NOT opened. // cons must return a storage which is NOT opened.
func TestControl(t *testing.T, cons Constructor, min, max uint64) { func TestControl(t *testing.T, cons Constructor, min, max uint64) {
s := cons(t) s := cons(t)
require.NoError(t, s.Open(false)) require.NoError(t, s.Open(mode.ComponentReadWrite))
require.NoError(t, s.Init()) require.NoError(t, s.Init())
objects := prepare(t, 10, s, min, max) objects := prepare(t, 10, s, min, max)
require.NoError(t, s.Close()) require.NoError(t, s.Close())
require.NoError(t, s.Open(true)) require.NoError(t, s.Open(mode.ComponentReadOnly))
for i := range objects { for i := range objects {
var prm common.GetPrm var prm common.GetPrm
prm.Address = objects[i].addr prm.Address = objects[i].addr

View file

@ -5,6 +5,7 @@ import (
"testing" "testing"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test" oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -12,7 +13,7 @@ import (
func TestDelete(t *testing.T, cons Constructor, min, max uint64) { func TestDelete(t *testing.T, cons Constructor, min, max uint64) {
s := cons(t) s := cons(t)
require.NoError(t, s.Open(false)) require.NoError(t, s.Open(mode.ComponentReadWrite))
require.NoError(t, s.Init()) require.NoError(t, s.Init())
defer func() { require.NoError(t, s.Close()) }() defer func() { require.NoError(t, s.Close()) }()

View file

@ -5,13 +5,14 @@ import (
"testing" "testing"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test" oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestExists(t *testing.T, cons Constructor, min, max uint64) { func TestExists(t *testing.T, cons Constructor, min, max uint64) {
s := cons(t) s := cons(t)
require.NoError(t, s.Open(false)) require.NoError(t, s.Open(mode.ComponentReadWrite))
require.NoError(t, s.Init()) require.NoError(t, s.Init())
defer func() { require.NoError(t, s.Close()) }() defer func() { require.NoError(t, s.Close()) }()

View file

@ -5,6 +5,7 @@ import (
"testing" "testing"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test" oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -12,7 +13,7 @@ import (
func TestGet(t *testing.T, cons Constructor, min, max uint64) { func TestGet(t *testing.T, cons Constructor, min, max uint64) {
s := cons(t) s := cons(t)
require.NoError(t, s.Open(false)) require.NoError(t, s.Open(mode.ComponentReadWrite))
require.NoError(t, s.Init()) require.NoError(t, s.Init())
defer func() { require.NoError(t, s.Close()) }() defer func() { require.NoError(t, s.Close()) }()

View file

@ -6,6 +6,7 @@ import (
"testing" "testing"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status" apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test" oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
@ -14,7 +15,7 @@ import (
func TestGetRange(t *testing.T, cons Constructor, min, max uint64) { func TestGetRange(t *testing.T, cons Constructor, min, max uint64) {
s := cons(t) s := cons(t)
require.NoError(t, s.Open(false)) require.NoError(t, s.Open(mode.ComponentReadWrite))
require.NoError(t, s.Init()) require.NoError(t, s.Init())
defer func() { require.NoError(t, s.Close()) }() defer func() { require.NoError(t, s.Close()) }()

View file

@ -6,12 +6,13 @@ import (
"testing" "testing"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestIterate(t *testing.T, cons Constructor, min, max uint64) { func TestIterate(t *testing.T, cons Constructor, min, max uint64) {
s := cons(t) s := cons(t)
require.NoError(t, s.Open(false)) require.NoError(t, s.Open(mode.ComponentReadWrite))
require.NoError(t, s.Init()) require.NoError(t, s.Init())
defer func() { require.NoError(t, s.Close()) }() defer func() { require.NoError(t, s.Close()) }()

View file

@ -1,9 +1,12 @@
package memstore package memstore
import "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/compression" import (
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/compression"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
)
func (s *memstoreImpl) Open(readOnly bool) error { func (s *memstoreImpl) Open(mod mode.ComponentMode) error {
s.readOnly = readOnly s.readOnly = mod.ReadOnly()
return nil return nil
} }

View file

@ -7,6 +7,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/internal/blobstortest" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/internal/blobstortest"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger/test" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger/test"
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object" objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -18,7 +19,7 @@ func TestSimpleLifecycle(t *testing.T) {
WithLogger(test.NewLogger(t)), WithLogger(test.NewLogger(t)),
) )
defer func() { require.NoError(t, s.Close()) }() defer func() { require.NoError(t, s.Close()) }()
require.NoError(t, s.Open(false)) require.NoError(t, s.Open(mode.ComponentReadWrite))
require.NoError(t, s.Init()) require.NoError(t, s.Init())
obj := blobstortest.NewObject(1024) obj := blobstortest.NewObject(1024)

View file

@ -10,6 +10,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/fstree" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/fstree"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/memstore" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/memstore"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/testutil" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/testutil"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
) )
@ -22,7 +23,7 @@ type storage struct {
func (s storage) open(b *testing.B) common.Storage { func (s storage) open(b *testing.B) common.Storage {
st := s.create(b.TempDir()) st := s.create(b.TempDir())
require.NoError(b, st.Open(false)) require.NoError(b, st.Open(mode.ComponentReadWrite))
require.NoError(b, st.Init()) require.NoError(b, st.Init())
return st return st

View file

@ -3,12 +3,13 @@ package teststore
import ( import (
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/compression" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/compression"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
) )
type cfg struct { type cfg struct {
st common.Storage st common.Storage
overrides struct { overrides struct {
Open func(readOnly bool) error Open func(mode mode.ComponentMode) error
Init func() error Init func() error
Close func() error Close func() error
@ -35,9 +36,9 @@ func WithSubstorage(st common.Storage) Option {
} }
} }
func WithOpen(f func(bool) error) Option { return func(c *cfg) { c.overrides.Open = f } } func WithOpen(f func(mode.ComponentMode) error) Option { return func(c *cfg) { c.overrides.Open = f } }
func WithInit(f func() error) Option { return func(c *cfg) { c.overrides.Init = f } } func WithInit(f func() error) Option { return func(c *cfg) { c.overrides.Init = f } }
func WithClose(f func() error) Option { return func(c *cfg) { c.overrides.Close = f } } func WithClose(f func() error) Option { return func(c *cfg) { c.overrides.Close = f } }
func WithType(f func() string) Option { return func(c *cfg) { c.overrides.Type = f } } func WithType(f func() string) Option { return func(c *cfg) { c.overrides.Type = f } }
func WithPath(f func() string) Option { return func(c *cfg) { c.overrides.Path = f } } func WithPath(f func() string) Option { return func(c *cfg) { c.overrides.Path = f } }

View file

@ -20,6 +20,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/compression" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/compression"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
) )
// TestStore is a common.Storage implementation for testing/mocking purposes. // TestStore is a common.Storage implementation for testing/mocking purposes.
@ -50,16 +51,16 @@ func (s *TestStore) SetOption(opt Option) {
opt(s.cfg) opt(s.cfg)
} }
func (s *TestStore) Open(readOnly bool) error { func (s *TestStore) Open(mod mode.ComponentMode) error {
s.mu.RLock() s.mu.RLock()
defer s.mu.RUnlock() defer s.mu.RUnlock()
switch { switch {
case s.overrides.Open != nil: case s.overrides.Open != nil:
return s.overrides.Open(readOnly) return s.overrides.Open(mod)
case s.st != nil: case s.st != nil:
return s.st.Open(readOnly) return s.st.Open(mod)
default: default:
panic(fmt.Sprintf("unexpected storage call: Open(%v)", readOnly)) panic(fmt.Sprintf("unexpected storage call: Open(%v)", mod.String()))
} }
} }

View file

@ -74,7 +74,7 @@ func TestInitializationFailure(t *testing.T) {
openFileMetabase: os.OpenFile, openFileMetabase: os.OpenFile,
openFilePilorama: os.OpenFile, openFilePilorama: os.OpenFile,
}) })
largeFileStorage.SetOption(teststore.WithOpen(func(ro bool) error { largeFileStorage.SetOption(teststore.WithOpen(func(primitiveMode mode.ComponentMode) error {
return teststore.ErrDiskExploded return teststore.ErrDiskExploded
})) }))
beforeReload := func() { beforeReload := func() {

View file

@ -171,8 +171,8 @@ func (m *writeCacheMetrics) SetEstimateSize(db, fstree uint64) {
m.metrics.SetEstimateSize(m.shardID, m.path, writecache.StorageTypeFSTree.String(), fstree) m.metrics.SetEstimateSize(m.shardID, m.path, writecache.StorageTypeFSTree.String(), fstree)
} }
func (m *writeCacheMetrics) SetMode(mode mode.Mode) { func (m *writeCacheMetrics) SetMode(mod mode.ComponentMode) {
m.metrics.SetMode(m.shardID, mode.String()) m.metrics.SetMode(m.shardID, mod.String())
} }
func (m *writeCacheMetrics) SetActualCounters(db, fstree uint64) { func (m *writeCacheMetrics) SetActualCounters(db, fstree uint64) {

View file

@ -38,16 +38,16 @@ var (
) )
// Open boltDB instance for metabase. // Open boltDB instance for metabase.
func (db *DB) Open(_ context.Context, mode mode.Mode) error { func (db *DB) Open(_ context.Context, m mode.Mode) error {
db.modeMtx.Lock() db.modeMtx.Lock()
defer db.modeMtx.Unlock() defer db.modeMtx.Unlock()
db.mode = mode db.mode = m
db.metrics.SetMode(mode) db.metrics.SetMode(mode.ConvertToComponentModeDegraded(m))
if mode.NoMetabase() { if m.NoMetabase() {
return nil return nil
} }
return db.openDB(mode) return db.openDB(m)
} }
func (db *DB) openDB(mode mode.Mode) error { func (db *DB) openDB(mode mode.Mode) error {
@ -239,15 +239,15 @@ func (db *DB) Reload(opts ...Option) (bool, error) {
return false, err return false, err
} }
db.mode = mode.Degraded db.mode = mode.Disabled
db.metrics.SetMode(mode.Degraded) db.metrics.SetMode(mode.ComponentDisabled)
db.info.Path = c.info.Path db.info.Path = c.info.Path
if err := db.openBolt(); err != nil { if err := db.openBolt(); err != nil {
return false, metaerr.Wrap(fmt.Errorf("%w: %v", ErrDegradedMode, err)) return false, metaerr.Wrap(fmt.Errorf("%w: %v", ErrDegradedMode, err))
} }
db.mode = mode.ReadWrite db.mode = mode.ReadWrite
db.metrics.SetMode(mode.ReadWrite) db.metrics.SetMode(mode.ComponentReadWrite)
return true, nil return true, nil
} }

View file

@ -9,7 +9,7 @@ import (
type Metrics interface { type Metrics interface {
SetParentID(parentID string) SetParentID(parentID string)
SetMode(m mode.Mode) SetMode(m mode.ComponentMode)
Close() Close()
AddMethodDuration(method string, d time.Duration, success bool) AddMethodDuration(method string, d time.Duration, success bool)
@ -18,6 +18,6 @@ type Metrics interface {
type noopMetrics struct{} type noopMetrics struct{}
func (m *noopMetrics) SetParentID(string) {} func (m *noopMetrics) SetParentID(string) {}
func (m *noopMetrics) SetMode(mode.Mode) {} func (m *noopMetrics) SetMode(mode.ComponentMode) {}
func (m *noopMetrics) Close() {} func (m *noopMetrics) Close() {}
func (m *noopMetrics) AddMethodDuration(string, time.Duration, bool) {} func (m *noopMetrics) AddMethodDuration(string, time.Duration, bool) {}

View file

@ -35,6 +35,6 @@ func (db *DB) SetMode(m mode.Mode) error {
} }
db.mode = m db.mode = m
db.metrics.SetMode(m) db.metrics.SetMode(mode.ConvertToComponentModeDegraded(m))
return nil return nil
} }

View file

@ -69,7 +69,7 @@ func (db *DB) SetShardID(id []byte, mode metamode.Mode) error {
err := db.writeShardID(id) err := db.writeShardID(id)
if err == nil { if err == nil {
db.metrics.SetMode(mode) db.metrics.SetMode(metamode.ConvertToComponentModeDegraded(mode))
} }
if cErr := db.close(); cErr != nil { if cErr := db.close(); cErr != nil {

View file

@ -5,6 +5,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobovnicza" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobovnicza"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/blobovniczatree" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/blobovniczatree"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
metrics_impl "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/metrics" metrics_impl "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/metrics"
) )
@ -34,8 +35,8 @@ func (m *blobovniczaTreeMetrics) SetParentID(parentID string) {
m.shardID = parentID m.shardID = parentID
} }
func (m *blobovniczaTreeMetrics) SetMode(readOnly bool) { func (m *blobovniczaTreeMetrics) SetMode(mod mode.ComponentMode) {
m.m.SetBlobobvnizcaTreeMode(m.shardID, m.path, readOnly) m.m.SetBlobobvnizcaTreeMode(m.shardID, m.path, mod)
} }
func (m *blobovniczaTreeMetrics) Close() { func (m *blobovniczaTreeMetrics) Close() {

View file

@ -4,6 +4,7 @@ import (
"time" "time"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/fstree" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/fstree"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
metrics_impl "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/metrics" metrics_impl "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/metrics"
) )
@ -25,8 +26,8 @@ func (m *fstreeMetrics) SetParentID(parentID string) {
m.shardID = parentID m.shardID = parentID
} }
func (m *fstreeMetrics) SetMode(readOnly bool) { func (m *fstreeMetrics) SetMode(mod mode.ComponentMode) {
m.m.SetMode(m.shardID, m.path, readOnly) m.m.SetMode(m.shardID, m.path, mod)
} }
func (m *fstreeMetrics) Close() { func (m *fstreeMetrics) Close() {

View file

@ -26,7 +26,7 @@ func (m *metabaseMetrics) SetParentID(parentID string) {
m.shardID = parentID m.shardID = parentID
} }
func (m *metabaseMetrics) SetMode(mode mode.Mode) { func (m *metabaseMetrics) SetMode(mode mode.ComponentMode) {
m.m.SetMode(m.shardID, m.path, mode.String()) m.m.SetMode(m.shardID, m.path, mode.String())
} }

View file

@ -24,8 +24,8 @@ func (m *piloramaMetrics) SetParentID(id string) {
m.shardID = id m.shardID = id
} }
func (m *piloramaMetrics) SetMode(mode mode.Mode) { func (m *piloramaMetrics) SetMode(mod mode.ComponentMode) {
m.m.SetMode(m.shardID, mode) m.m.SetMode(m.shardID, mod)
} }
func (m *piloramaMetrics) Close() { func (m *piloramaMetrics) Close() {

View file

@ -109,7 +109,7 @@ func (t *boltForest) SetMode(m mode.Mode) error {
} }
t.mode = m t.mode = m
t.metrics.SetMode(m) t.metrics.SetMode(mode.ConvertToComponentModeDegraded(m))
return nil return nil
} }
@ -123,8 +123,8 @@ func (t *boltForest) Open(_ context.Context, mode mode.Mode) error {
return t.openBolt(mode) return t.openBolt(mode)
} }
func (t *boltForest) openBolt(mode mode.Mode) error { func (t *boltForest) openBolt(m mode.Mode) error {
readOnly := mode.ReadOnly() readOnly := m.ReadOnly()
err := util.MkdirAllX(filepath.Dir(t.path), t.perm) err := util.MkdirAllX(filepath.Dir(t.path), t.perm)
if err != nil { if err != nil {
return metaerr.Wrap(fmt.Errorf("can't create dir %s for the pilorama: %w", t.path, err)) return metaerr.Wrap(fmt.Errorf("can't create dir %s for the pilorama: %w", t.path, err))
@ -143,7 +143,7 @@ func (t *boltForest) openBolt(mode mode.Mode) error {
t.db.MaxBatchSize = t.maxBatchSize t.db.MaxBatchSize = t.maxBatchSize
t.db.MaxBatchDelay = t.maxBatchDelay t.db.MaxBatchDelay = t.maxBatchDelay
t.metrics.SetMode(mode) t.metrics.SetMode(mode.ConvertToComponentModeDegraded(m))
return nil return nil
} }

View file

@ -9,7 +9,7 @@ import (
type Metrics interface { type Metrics interface {
SetParentID(id string) SetParentID(id string)
SetMode(m mode.Mode) SetMode(m mode.ComponentMode)
Close() Close()
AddMethodDuration(method string, d time.Duration, success bool) AddMethodDuration(method string, d time.Duration, success bool)
@ -18,6 +18,6 @@ type Metrics interface {
type noopMetrics struct{} type noopMetrics struct{}
func (m *noopMetrics) SetParentID(string) {} func (m *noopMetrics) SetParentID(string) {}
func (m *noopMetrics) SetMode(mode.Mode) {} func (m *noopMetrics) SetMode(mode.ComponentMode) {}
func (m *noopMetrics) Close() {} func (m *noopMetrics) Close() {}
func (m *noopMetrics) AddMethodDuration(string, time.Duration, bool) {} func (m *noopMetrics) AddMethodDuration(string, time.Duration, bool) {}

View file

@ -37,7 +37,7 @@ func (s *Shard) handleMetabaseFailure(stage string, err error) error {
err = s.SetMode(mode.DegradedReadOnly) err = s.SetMode(mode.DegradedReadOnly)
if err != nil { if err != nil {
return fmt.Errorf("could not switch to mode %s", mode.DegradedReadOnly) return fmt.Errorf("could not switch to mode %s", mode.Mode(mode.DegradedReadOnly))
} }
return nil return nil
} }

View file

@ -29,6 +29,22 @@ const (
DegradedReadOnly Mode = Degraded | ReadOnly DegradedReadOnly Mode = Degraded | ReadOnly
) )
// ComponentMode represents basic operation modes for shared components, including READ, READ_WRITE, and DISABLED.
type ComponentMode uint32
const (
// ComponentReadWrite is a Mode value for component that is available
// for read and write operations. Default component mode.
ComponentReadWrite ComponentMode = 0
// ComponentReadOnly is a Mode value for component that does not
// accept write operation but is readable.
ComponentReadOnly ComponentMode = 0b001
// ComponentDisabled mode is a mode where a component is disabled.
ComponentDisabled ComponentMode = math.MaxUint32
)
func (m Mode) String() string { func (m Mode) String() string {
switch m { switch m {
default: default:
@ -46,6 +62,19 @@ func (m Mode) String() string {
} }
} }
func (m ComponentMode) String() string {
switch m {
default:
return "UNDEFINED"
case ComponentReadWrite:
return "READ_WRITE"
case ComponentReadOnly:
return "READ_ONLY"
case ComponentDisabled:
return "CLOSED"
}
}
// NoMetabase returns true iff m is operating without the metabase. // NoMetabase returns true iff m is operating without the metabase.
func (m Mode) NoMetabase() bool { func (m Mode) NoMetabase() bool {
return m&Degraded != 0 return m&Degraded != 0
@ -56,6 +85,39 @@ func (m Mode) ReadOnly() bool {
return m&ReadOnly != 0 return m&ReadOnly != 0
} }
// ReadOnly returns true iff m prohibits modifying operations with shard.
func (m ComponentMode) ReadOnly() bool {
return m&ComponentReadOnly != 0
}
func (m Mode) Disabled() bool { func (m Mode) Disabled() bool {
return m == Disabled return m == Disabled
} }
func (m ComponentMode) Disabled() bool {
return m == ComponentDisabled
}
// ConvertToComponentModeDegraded converts a ShardMode to a corresponding ComponentMode.
// Disables the component if the node is in degraded mode. Used in Metabase, Writecache, Pilorama.
func ConvertToComponentModeDegraded(m Mode) ComponentMode {
if m.NoMetabase() || m.Disabled() {
return ComponentDisabled
}
if m.ReadOnly() {
return ComponentReadOnly
}
return ComponentReadWrite
}
// ConvertToComponentMode converts a ShardMode to a corresponding ComponentMode.
// Ignores the degraded mode of the node. Used in Blobstore.
func ConvertToComponentMode(m Mode) ComponentMode {
if m.Disabled() {
return ComponentDisabled
}
if m.ReadOnly() {
return ComponentReadOnly
}
return ComponentReadWrite
}

View file

@ -95,14 +95,14 @@ func (c *cache) DumpInfo() Info {
} }
// Open opens and initializes database. Reads object counters from the ObjectCounters instance. // Open opens and initializes database. Reads object counters from the ObjectCounters instance.
func (c *cache) Open(_ context.Context, mode mode.Mode) error { func (c *cache) Open(_ context.Context, mod mode.Mode) error {
c.modeMtx.Lock() c.modeMtx.Lock()
defer c.modeMtx.Unlock() defer c.modeMtx.Unlock()
c.mode = mode c.mode = mod
if mode.NoMetabase() { if mod.NoMetabase() {
return nil return nil
} }
err := c.openStore(mode.ReadOnly()) err := c.openStore(mode.ConvertToComponentModeDegraded(mod))
if err != nil { if err != nil {
return metaerr.Wrap(err) return metaerr.Wrap(err)
} }
@ -112,7 +112,7 @@ func (c *cache) Open(_ context.Context, mode mode.Mode) error {
// Init runs necessary services. // Init runs necessary services.
func (c *cache) Init() error { func (c *cache) Init() error {
c.metrics.SetMode(c.mode) c.metrics.SetMode(mode.ConvertToComponentModeDegraded(c.mode))
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
c.cancel = cancel c.cancel = cancel
c.runFlushLoop(ctx) c.runFlushLoop(ctx)

View file

@ -294,7 +294,7 @@ func (c *cache) Flush(ctx context.Context, ignoreErrors, seal bool) error {
if err := c.setMode(ctx, m, ignoreErrors); err != nil { if err := c.setMode(ctx, m, ignoreErrors); err != nil {
return err return err
} }
c.metrics.SetMode(m) c.metrics.SetMode(mode.ConvertToComponentModeDegraded(m))
} }
return nil return nil
} }

View file

@ -27,7 +27,7 @@ type Metrics interface {
Evict(st StorageType) Evict(st StorageType)
SetEstimateSize(db, fstree uint64) SetEstimateSize(db, fstree uint64)
SetMode(m mode.Mode) SetMode(m mode.ComponentMode)
SetActualCounters(db, fstree uint64) SetActualCounters(db, fstree uint64)
SetPath(path string) SetPath(path string)
Close() Close()
@ -49,7 +49,7 @@ func (metricsStub) Put(time.Duration, bool, StorageType) {}
func (metricsStub) SetEstimateSize(uint64, uint64) {} func (metricsStub) SetEstimateSize(uint64, uint64) {}
func (metricsStub) SetMode(mode.Mode) {} func (metricsStub) SetMode(mode.ComponentMode) {}
func (metricsStub) SetActualCounters(uint64, uint64) {} func (metricsStub) SetActualCounters(uint64, uint64) {}

View file

@ -27,7 +27,7 @@ func (c *cache) SetMode(m mode.Mode) error {
err := c.setMode(ctx, m, true) err := c.setMode(ctx, m, true)
if err == nil { if err == nil {
c.metrics.SetMode(m) c.metrics.SetMode(mode.ConvertToComponentModeDegraded(m))
} }
return err return err
} }
@ -63,7 +63,7 @@ func (c *cache) setMode(ctx context.Context, m mode.Mode, ignoreErrors bool) err
return nil return nil
} }
if err = c.openStore(m.ReadOnly()); err != nil { if err = c.openStore(mode.ConvertToComponentModeDegraded(m)); err != nil {
return err return err
} }

View file

@ -22,7 +22,7 @@ func (c *cache) Seal(ctx context.Context, ignoreErrors bool) error {
// flush will be done by setMode // flush will be done by setMode
err := c.setMode(ctx, mode.DegradedReadOnly, ignoreErrors) err := c.setMode(ctx, mode.DegradedReadOnly, ignoreErrors)
if err == nil { if err == nil {
c.metrics.SetMode(mode.DegradedReadOnly) c.metrics.SetMode(mode.ComponentDisabled)
} }
return err return err
} }

View file

@ -10,6 +10,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/fstree" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/fstree"
storagelog "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/log" storagelog "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/log"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id" oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
@ -25,13 +26,13 @@ type store struct {
const dbName = "small.bolt" const dbName = "small.bolt"
func (c *cache) openStore(readOnly bool) error { func (c *cache) openStore(mod mode.ComponentMode) error {
err := util.MkdirAllX(c.path, os.ModePerm) err := util.MkdirAllX(c.path, os.ModePerm)
if err != nil { if err != nil {
return err return err
} }
c.db, err = OpenDB(c.path, readOnly, c.openFile) c.db, err = OpenDB(c.path, mod.ReadOnly(), c.openFile)
if err != nil { if err != nil {
return fmt.Errorf("could not open database: %w", err) return fmt.Errorf("could not open database: %w", err)
} }
@ -39,7 +40,7 @@ func (c *cache) openStore(readOnly bool) error {
c.db.MaxBatchSize = c.maxBatchSize c.db.MaxBatchSize = c.maxBatchSize
c.db.MaxBatchDelay = c.maxBatchDelay c.db.MaxBatchDelay = c.maxBatchDelay
if !readOnly { if !mod.ReadOnly() {
err = c.db.Update(func(tx *bbolt.Tx) error { err = c.db.Update(func(tx *bbolt.Tx) error {
_, err := tx.CreateBucketIfNotExists(defaultBucket) _, err := tx.CreateBucketIfNotExists(defaultBucket)
return err return err
@ -57,7 +58,7 @@ func (c *cache) openStore(readOnly bool) error {
fstree.WithNoSync(c.noSync), fstree.WithNoSync(c.noSync),
fstree.WithFileCounter(&c.objCounters), fstree.WithFileCounter(&c.objCounters),
) )
if err := c.fsTree.Open(readOnly); err != nil { if err := c.fsTree.Open(mod); err != nil {
return fmt.Errorf("could not open FSTree: %w", err) return fmt.Errorf("could not open FSTree: %w", err)
} }
if err := c.fsTree.Init(); err != nil { if err := c.fsTree.Init(); err != nil {

View file

@ -4,12 +4,13 @@ import (
"strconv" "strconv"
"time" "time"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
"git.frostfs.info/TrueCloudLab/frostfs-observability/metrics" "git.frostfs.info/TrueCloudLab/frostfs-observability/metrics"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
type BlobobvnizcaMetrics interface { type BlobobvnizcaMetrics interface {
SetBlobobvnizcaTreeMode(shardID, path string, readOnly bool) SetBlobobvnizcaTreeMode(shardID, path string, mode mode.ComponentMode)
CloseBlobobvnizcaTree(shardID, path string) CloseBlobobvnizcaTree(shardID, path string)
BlobobvnizcaTreeMethodDuration(shardID, path string, method string, d time.Duration, success bool, withStorageID NullBool) BlobobvnizcaTreeMethodDuration(shardID, path string, method string, d time.Duration, success bool, withStorageID NullBool)
AddBlobobvnizcaTreePut(shardID, path string, size int) AddBlobobvnizcaTreePut(shardID, path string, size int)
@ -98,8 +99,8 @@ func newBlobovnicza() *blobovnicza {
} }
} }
func (b *blobovnicza) SetBlobobvnizcaTreeMode(shardID, path string, readOnly bool) { func (b *blobovnicza) SetBlobobvnizcaTreeMode(shardID, path string, mod mode.ComponentMode) {
b.treeMode.SetMode(shardID, path, modeFromBool(readOnly)) b.treeMode.SetMode(shardID, path, mod.String())
} }
func (b *blobovnicza) CloseBlobobvnizcaTree(shardID, path string) { func (b *blobovnicza) CloseBlobobvnizcaTree(shardID, path string) {

View file

@ -4,12 +4,13 @@ import (
"strconv" "strconv"
"time" "time"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
"git.frostfs.info/TrueCloudLab/frostfs-observability/metrics" "git.frostfs.info/TrueCloudLab/frostfs-observability/metrics"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
type FSTreeMetrics interface { type FSTreeMetrics interface {
SetMode(shardID, path string, readOnly bool) SetMode(shardID, path string, mode mode.ComponentMode)
Close(shardID, path string) Close(shardID, path string)
MethodDuration(shardID, path string, method string, d time.Duration, success bool) MethodDuration(shardID, path string, method string, d time.Duration, success bool)
@ -48,8 +49,8 @@ func newFSTreeMetrics() *fstreeMetrics {
} }
} }
func (m *fstreeMetrics) SetMode(shardID, path string, readOnly bool) { func (m *fstreeMetrics) SetMode(shardID, path string, mod mode.ComponentMode) {
m.mode.SetMode(shardID, path, modeFromBool(readOnly)) m.mode.SetMode(shardID, path, mod.String())
} }
func (m *fstreeMetrics) Close(shardID, path string) { func (m *fstreeMetrics) Close(shardID, path string) {

View file

@ -10,7 +10,7 @@ import (
) )
type PiloramaMetrics interface { type PiloramaMetrics interface {
SetMode(shardID string, m mode.Mode) SetMode(shardID string, m mode.ComponentMode)
Close(shardID string) Close(shardID string)
AddMethodDuration(shardID string, method string, d time.Duration, success bool) AddMethodDuration(shardID string, method string, d time.Duration, success bool)
@ -33,7 +33,7 @@ type piloramaMetrics struct {
reqDuration *prometheus.HistogramVec reqDuration *prometheus.HistogramVec
} }
func (m *piloramaMetrics) SetMode(shardID string, mode mode.Mode) { func (m *piloramaMetrics) SetMode(shardID string, mode mode.ComponentMode) {
m.mode.SetMode(shardID, mode.String()) m.mode.SetMode(shardID, mode.String())
} }