diff --git a/cmd/neofs-cli/modules/control/shards_list.go b/cmd/neofs-cli/modules/control/shards_list.go index 4d4eef63a..879b712b0 100644 --- a/cmd/neofs-cli/modules/control/shards_list.go +++ b/cmd/neofs-cli/modules/control/shards_list.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/json" "fmt" + "strings" "github.com/mr-tron/base58" rawclient "github.com/nspcc-dev/neofs-api-go/v2/rpc/client" @@ -65,7 +66,7 @@ func prettyPrintShardsJSON(cmd *cobra.Command, ii []*control.ShardInfo) { "shard_id": base58.Encode(i.Shard_ID), "mode": shardModeToString(i.GetMode()), "metabase": i.GetMetabasePath(), - "blobstor": i.GetBlobstorPath(), + "blobstor": i.GetBlobstor(), "writecache": i.GetWritecachePath(), "error_count": i.GetErrorCount(), }) @@ -89,9 +90,16 @@ func prettyPrintShards(cmd *cobra.Command, ii []*control.ShardInfo) { return fmt.Sprintf("%s: %s\n", name, path) } + var sb strings.Builder + sb.WriteString("Blobstor:\n") + for j, info := range i.GetBlobstor() { + sb.WriteString(fmt.Sprintf("\tPath %d: %s\n\tType %d: %s\n", + j, info.GetPath(), j, info.GetType())) + } + cmd.Printf("Shard %s:\nMode: %s\n"+ pathPrinter("Metabase", i.GetMetabasePath())+ - pathPrinter("Blobstor", i.GetBlobstorPath())+ + sb.String()+ pathPrinter("Write-cache", i.GetWritecachePath())+ pathPrinter("Pilorama", i.GetPiloramaPath())+ fmt.Sprintf("Error count: %d\n", i.GetErrorCount()), diff --git a/pkg/local_object_storage/blobstor/blobstor.go b/pkg/local_object_storage/blobstor/blobstor.go index 4d8bd94f9..0480db0d2 100644 --- a/pkg/local_object_storage/blobstor/blobstor.go +++ b/pkg/local_object_storage/blobstor/blobstor.go @@ -5,7 +5,6 @@ import ( "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/common" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/compression" - "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/fstree" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard/mode" "github.com/nspcc-dev/neofs-node/pkg/util/logger" objectSDK "github.com/nspcc-dev/neofs-sdk-go/object" @@ -26,7 +25,16 @@ type BlobStor struct { mode mode.Mode } -type Info = fstree.Info +// Info contains information about blobstor. +type Info struct { + SubStorages []SubStorageInfo +} + +// SubStorageInfo contains information about blobstor storage component. +type SubStorageInfo struct { + Type string + Path string +} // Option represents BlobStor's constructor option. type Option func(*cfg) diff --git a/pkg/local_object_storage/blobstor/info.go b/pkg/local_object_storage/blobstor/info.go index 60a143ce1..e3e790ebc 100644 --- a/pkg/local_object_storage/blobstor/info.go +++ b/pkg/local_object_storage/blobstor/info.go @@ -1,13 +1,14 @@ package blobstor -import "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/fstree" - // DumpInfo returns information about blob stor. -func (b *BlobStor) DumpInfo() fstree.Info { +func (b *BlobStor) DumpInfo() Info { + sub := make([]SubStorageInfo, len(b.storage)) for i := range b.storage { - if b.storage[i].Storage.Type() == "fstree" { - return b.storage[i].Storage.(*fstree.FSTree).Info - } + sub[i].Path = b.storage[i].Storage.Path() + sub[i].Type = b.storage[i].Storage.Type() + } + + return Info{ + SubStorages: sub, } - return fstree.Info{} } diff --git a/pkg/local_object_storage/engine/error_test.go b/pkg/local_object_storage/engine/error_test.go index 2439d667b..ccbe8c04e 100644 --- a/pkg/local_object_storage/engine/error_test.go +++ b/pkg/local_object_storage/engine/error_test.go @@ -167,8 +167,8 @@ func TestBlobstorFailback(t *testing.T) { checkShardState(t, e, id[0], 0, mode.ReadWrite) require.NoError(t, e.Close()) - p1 := e.shards[id[0].String()].Shard.DumpInfo().BlobStorInfo.RootPath - p2 := e.shards[id[1].String()].Shard.DumpInfo().BlobStorInfo.RootPath + p1 := e.shards[id[0].String()].Shard.DumpInfo().BlobStorInfo.SubStorages[1].Path + p2 := e.shards[id[1].String()].Shard.DumpInfo().BlobStorInfo.SubStorages[1].Path tmp := filepath.Join(dir, "tmp") require.NoError(t, os.Rename(p1, tmp)) require.NoError(t, os.Rename(p2, p1)) diff --git a/pkg/local_object_storage/shard/control_test.go b/pkg/local_object_storage/shard/control_test.go index 01aa3f67f..eb9d2a3ff 100644 --- a/pkg/local_object_storage/shard/control_test.go +++ b/pkg/local_object_storage/shard/control_test.go @@ -82,13 +82,14 @@ func TestShardOpen(t *testing.T) { func TestRefillMetabaseCorrupted(t *testing.T) { dir := t.TempDir() + fsTree := fstree.New( + fstree.WithDirNameLen(2), + fstree.WithPath(filepath.Join(dir, "blob")), + fstree.WithDepth(1)) blobOpts := []blobstor.Option{ blobstor.WithStorages([]blobstor.SubStorage{ { - Storage: fstree.New( - fstree.WithDirNameLen(2), - fstree.WithPath(filepath.Join(dir, "blob")), - fstree.WithDepth(1)), + Storage: fsTree, }, }), } @@ -111,12 +112,7 @@ func TestRefillMetabaseCorrupted(t *testing.T) { require.NoError(t, sh.Close()) addr := object.AddressOf(obj) - fs := fstree.FSTree{ - DirNameLen: 2, - Depth: 1, - Info: sh.blobStor.DumpInfo(), - } - _, err = fs.Put(common.PutPrm{Address: addr, RawData: []byte("not an object")}) + _, err = fsTree.Put(common.PutPrm{Address: addr, RawData: []byte("not an object")}) require.NoError(t, err) sh = New( diff --git a/pkg/services/control/server/list_shards.go b/pkg/services/control/server/list_shards.go index 11a66dcd5..0e21d9028 100644 --- a/pkg/services/control/server/list_shards.go +++ b/pkg/services/control/server/list_shards.go @@ -3,6 +3,7 @@ package control import ( "context" + "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard/mode" "github.com/nspcc-dev/neofs-node/pkg/services/control" "google.golang.org/grpc/codes" @@ -30,7 +31,7 @@ func (s *Server) ListShards(_ context.Context, req *control.ListShardsRequest) ( si.SetID(*sh.ID) si.SetMetabasePath(sh.MetaBaseInfo.Path) - si.SetBlobstorPath(sh.BlobStorInfo.RootPath) + si.Blobstor = blobstorInfoToProto(sh.BlobStorInfo) si.SetWriteCachePath(sh.WriteCacheInfo.Path) si.SetPiloramaPath(sh.PiloramaInfo.Path) @@ -64,3 +65,14 @@ func (s *Server) ListShards(_ context.Context, req *control.ListShardsRequest) ( return resp, nil } + +func blobstorInfoToProto(info blobstor.Info) []*control.BlobstorInfo { + res := make([]*control.BlobstorInfo, len(info.SubStorages)) + for i := range info.SubStorages { + res[i] = &control.BlobstorInfo{ + Path: info.SubStorages[i].Path, + Type: info.SubStorages[i].Type, + } + } + return res +} diff --git a/pkg/services/control/service_test.go b/pkg/services/control/service_test.go index b64e67d7b..8c5f3279c 100644 --- a/pkg/services/control/service_test.go +++ b/pkg/services/control/service_test.go @@ -77,18 +77,21 @@ func equalListShardResponseBodies(b1, b2 *control.ListShardsResponse_Body) bool for i := range b1.Shards { if b1.Shards[i].GetMetabasePath() != b2.Shards[i].GetMetabasePath() || - b1.Shards[i].GetBlobstorPath() != b2.Shards[i].GetBlobstorPath() || b1.Shards[i].GetWritecachePath() != b2.Shards[i].GetWritecachePath() || b1.Shards[i].GetPiloramaPath() != b2.Shards[i].GetPiloramaPath() || !bytes.Equal(b1.Shards[i].GetShard_ID(), b2.Shards[i].GetShard_ID()) { return false } + + info1 := b1.Shards[i].GetBlobstor() + info2 := b2.Shards[i].GetBlobstor() + return compareBlobstorInfo(info1, info2) } for i := range b1.Shards { for j := i + 1; j < len(b1.Shards); j++ { if b1.Shards[i].GetMetabasePath() == b2.Shards[j].GetMetabasePath() || - b1.Shards[i].GetBlobstorPath() == b2.Shards[j].GetBlobstorPath() || + !compareBlobstorInfo(b1.Shards[i].Blobstor, b2.Shards[i].Blobstor) || b1.Shards[i].GetWritecachePath() == b2.Shards[j].GetWritecachePath() || bytes.Equal(b1.Shards[i].GetShard_ID(), b2.Shards[j].GetShard_ID()) { return false @@ -98,6 +101,18 @@ func equalListShardResponseBodies(b1, b2 *control.ListShardsResponse_Body) bool return true } +func compareBlobstorInfo(a, b []*control.BlobstorInfo) bool { + if len(a) != len(b) { + return false + } + for i := range a { + if a[i].Type != b[i].Type || + a[i].Path != b[i].Path { + return false + } + } + return true +} func generateListShardsResponseBody() *control.ListShardsResponse_Body { body := new(control.ListShardsResponse_Body) diff --git a/pkg/services/control/types.go b/pkg/services/control/types.go index 406a1896a..13bd87ed5 100644 --- a/pkg/services/control/types.go +++ b/pkg/services/control/types.go @@ -97,11 +97,6 @@ func (x *ShardInfo) SetMetabasePath(v string) { x.MetabasePath = v } -// SetBlobstorPath sets path to shard's blobstor. -func (x *ShardInfo) SetBlobstorPath(v string) { - x.BlobstorPath = v -} - // SetWriteCachePath sets path to shard's write-cache. func (x *ShardInfo) SetWriteCachePath(v string) { x.WritecachePath = v diff --git a/pkg/services/control/types.pb.go b/pkg/services/control/types.pb.go index 7056a225f..0f40deb50 100644 --- a/pkg/services/control/types.pb.go +++ b/pkg/services/control/types.pb.go @@ -400,8 +400,8 @@ type ShardInfo struct { Shard_ID []byte `protobuf:"bytes,1,opt,name=shard_ID,json=shardID,proto3" json:"shard_ID,omitempty"` // Path to shard's metabase. MetabasePath string `protobuf:"bytes,2,opt,name=metabase_path,json=metabasePath,proto3" json:"metabase_path,omitempty"` - // Path to shard's blobstor. - BlobstorPath string `protobuf:"bytes,3,opt,name=blobstor_path,json=blobstorPath,proto3" json:"blobstor_path,omitempty"` + // Shard's blobstor info. + Blobstor []*BlobstorInfo `protobuf:"bytes,3,rep,name=blobstor,proto3" json:"blobstor,omitempty"` // Path to shard's write-cache, empty if disabled. WritecachePath string `protobuf:"bytes,4,opt,name=writecache_path,json=writecachePath,proto3" json:"writecache_path,omitempty"` // Work mode of the shard. @@ -458,11 +458,11 @@ func (x *ShardInfo) GetMetabasePath() string { return "" } -func (x *ShardInfo) GetBlobstorPath() string { +func (x *ShardInfo) GetBlobstor() []*BlobstorInfo { if x != nil { - return x.BlobstorPath + return x.Blobstor } - return "" + return nil } func (x *ShardInfo) GetWritecachePath() string { @@ -493,6 +493,64 @@ func (x *ShardInfo) GetPiloramaPath() string { return "" } +// Blobstor component description. +type BlobstorInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Path to the root. + Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` + // Component type. + Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` +} + +func (x *BlobstorInfo) Reset() { + *x = BlobstorInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_services_control_types_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BlobstorInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BlobstorInfo) ProtoMessage() {} + +func (x *BlobstorInfo) ProtoReflect() protoreflect.Message { + mi := &file_pkg_services_control_types_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BlobstorInfo.ProtoReflect.Descriptor instead. +func (*BlobstorInfo) Descriptor() ([]byte, []int) { + return file_pkg_services_control_types_proto_rawDescGZIP(), []int{4} +} + +func (x *BlobstorInfo) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +func (x *BlobstorInfo) GetType() string { + if x != nil { + return x.Type + } + return "" +} + // Administrator-defined Attributes of the NeoFS Storage Node. // // `Attribute` is a Key-Value metadata pair. Key name must be a valid UTF-8 @@ -549,7 +607,7 @@ type NodeInfo_Attribute struct { func (x *NodeInfo_Attribute) Reset() { *x = NodeInfo_Attribute{} if protoimpl.UnsafeEnabled { - mi := &file_pkg_services_control_types_proto_msgTypes[4] + mi := &file_pkg_services_control_types_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -562,7 +620,7 @@ func (x *NodeInfo_Attribute) String() string { func (*NodeInfo_Attribute) ProtoMessage() {} func (x *NodeInfo_Attribute) ProtoReflect() protoreflect.Message { - mi := &file_pkg_services_control_types_proto_msgTypes[4] + mi := &file_pkg_services_control_types_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -629,44 +687,49 @@ var file_pkg_services_control_types_proto_rawDesc = []byte{ 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x27, 0x0a, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x22, - 0x86, 0x02, 0x0a, 0x09, 0x53, 0x68, 0x61, 0x72, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x19, 0x0a, + 0x94, 0x02, 0x0a, 0x09, 0x53, 0x68, 0x61, 0x72, 0x64, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x73, 0x68, 0x61, 0x72, 0x64, 0x49, 0x44, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x65, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0c, 0x6d, 0x65, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x23, 0x0a, - 0x0d, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x74, 0x6f, 0x72, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x74, 0x6f, 0x72, 0x50, 0x61, - 0x74, 0x68, 0x12, 0x27, 0x0a, 0x0f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x63, 0x61, 0x63, 0x68, 0x65, - 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x77, 0x72, 0x69, - 0x74, 0x65, 0x63, 0x61, 0x63, 0x68, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x26, 0x0a, 0x04, 0x6d, - 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, - 0x6f, 0x64, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x75, 0x6e, - 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, - 0x75, 0x6e, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x69, 0x6c, 0x6f, 0x72, 0x61, 0x6d, 0x61, 0x5f, - 0x70, 0x61, 0x74, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x69, 0x6c, 0x6f, - 0x72, 0x61, 0x6d, 0x61, 0x50, 0x61, 0x74, 0x68, 0x2a, 0x4e, 0x0a, 0x0c, 0x4e, 0x65, 0x74, 0x6d, - 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x54, 0x41, 0x54, - 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x49, 0x4e, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0a, - 0x0a, 0x06, 0x4f, 0x4e, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x4f, 0x46, - 0x46, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x41, 0x49, 0x4e, 0x54, - 0x45, 0x4e, 0x41, 0x4e, 0x43, 0x45, 0x10, 0x03, 0x2a, 0x57, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x6c, - 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1b, 0x0a, 0x17, 0x48, 0x45, 0x41, 0x4c, - 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x49, - 0x4e, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x54, 0x41, 0x52, 0x54, 0x49, 0x4e, - 0x47, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x45, 0x41, 0x44, 0x59, 0x10, 0x02, 0x12, 0x11, - 0x0a, 0x0d, 0x53, 0x48, 0x55, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x10, - 0x03, 0x2a, 0x6a, 0x0a, 0x09, 0x53, 0x68, 0x61, 0x72, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x18, - 0x0a, 0x14, 0x53, 0x48, 0x41, 0x52, 0x44, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x44, - 0x45, 0x46, 0x49, 0x4e, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x52, 0x45, 0x41, 0x44, - 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x52, 0x45, 0x41, 0x44, - 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x45, 0x47, 0x52, 0x41, - 0x44, 0x45, 0x44, 0x10, 0x03, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x45, 0x47, 0x52, 0x41, 0x44, 0x45, - 0x44, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x04, 0x42, 0x36, 0x5a, - 0x34, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6e, 0x73, 0x70, 0x63, - 0x63, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x6e, 0x65, 0x6f, 0x66, 0x73, 0x2d, 0x6e, 0x6f, 0x64, 0x65, - 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x0c, 0x6d, 0x65, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x31, 0x0a, + 0x08, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x74, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x15, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x73, 0x74, + 0x6f, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x74, 0x6f, 0x72, + 0x12, 0x27, 0x0a, 0x0f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x70, + 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x77, 0x72, 0x69, 0x74, 0x65, + 0x63, 0x61, 0x63, 0x68, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x26, 0x0a, 0x04, 0x6d, 0x6f, 0x64, + 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, + 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x69, 0x6c, 0x6f, 0x72, 0x61, 0x6d, 0x61, 0x5f, 0x70, 0x61, + 0x74, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x69, 0x6c, 0x6f, 0x72, 0x61, + 0x6d, 0x61, 0x50, 0x61, 0x74, 0x68, 0x22, 0x36, 0x0a, 0x0c, 0x42, 0x6c, 0x6f, 0x62, 0x73, 0x74, + 0x6f, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x2a, 0x4e, + 0x0a, 0x0c, 0x4e, 0x65, 0x74, 0x6d, 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, + 0x0a, 0x10, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x49, 0x4e, + 0x45, 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x4f, 0x4e, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x01, + 0x12, 0x0b, 0x0a, 0x07, 0x4f, 0x46, 0x46, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x02, 0x12, 0x0f, 0x0a, + 0x0b, 0x4d, 0x41, 0x49, 0x4e, 0x54, 0x45, 0x4e, 0x41, 0x4e, 0x43, 0x45, 0x10, 0x03, 0x2a, 0x57, + 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1b, + 0x0a, 0x17, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, + 0x55, 0x4e, 0x44, 0x45, 0x46, 0x49, 0x4e, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x53, + 0x54, 0x41, 0x52, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x45, 0x41, + 0x44, 0x59, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x48, 0x55, 0x54, 0x54, 0x49, 0x4e, 0x47, + 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x03, 0x2a, 0x6a, 0x0a, 0x09, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x53, 0x48, 0x41, 0x52, 0x44, 0x5f, 0x4d, 0x4f, + 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x46, 0x49, 0x4e, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0e, + 0x0a, 0x0a, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x01, 0x12, 0x0d, + 0x0a, 0x09, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x02, 0x12, 0x0c, 0x0a, + 0x08, 0x44, 0x45, 0x47, 0x52, 0x41, 0x44, 0x45, 0x44, 0x10, 0x03, 0x12, 0x16, 0x0a, 0x12, 0x44, + 0x45, 0x47, 0x52, 0x41, 0x44, 0x45, 0x44, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4f, 0x4e, 0x4c, + 0x59, 0x10, 0x04, 0x42, 0x36, 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x6e, 0x73, 0x70, 0x63, 0x63, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x6e, 0x65, 0x6f, 0x66, + 0x73, 0x2d, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( @@ -682,7 +745,7 @@ func file_pkg_services_control_types_proto_rawDescGZIP() []byte { } var file_pkg_services_control_types_proto_enumTypes = make([]protoimpl.EnumInfo, 3) -var file_pkg_services_control_types_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_pkg_services_control_types_proto_msgTypes = make([]protoimpl.MessageInfo, 6) var file_pkg_services_control_types_proto_goTypes = []interface{}{ (NetmapStatus)(0), // 0: control.NetmapStatus (HealthStatus)(0), // 1: control.HealthStatus @@ -691,18 +754,20 @@ var file_pkg_services_control_types_proto_goTypes = []interface{}{ (*NodeInfo)(nil), // 4: control.NodeInfo (*Netmap)(nil), // 5: control.Netmap (*ShardInfo)(nil), // 6: control.ShardInfo - (*NodeInfo_Attribute)(nil), // 7: control.NodeInfo.Attribute + (*BlobstorInfo)(nil), // 7: control.BlobstorInfo + (*NodeInfo_Attribute)(nil), // 8: control.NodeInfo.Attribute } var file_pkg_services_control_types_proto_depIdxs = []int32{ - 7, // 0: control.NodeInfo.attributes:type_name -> control.NodeInfo.Attribute + 8, // 0: control.NodeInfo.attributes:type_name -> control.NodeInfo.Attribute 0, // 1: control.NodeInfo.state:type_name -> control.NetmapStatus 4, // 2: control.Netmap.nodes:type_name -> control.NodeInfo - 2, // 3: control.ShardInfo.mode:type_name -> control.ShardMode - 4, // [4:4] is the sub-list for method output_type - 4, // [4:4] is the sub-list for method input_type - 4, // [4:4] is the sub-list for extension type_name - 4, // [4:4] is the sub-list for extension extendee - 0, // [0:4] is the sub-list for field type_name + 7, // 3: control.ShardInfo.blobstor:type_name -> control.BlobstorInfo + 2, // 4: control.ShardInfo.mode:type_name -> control.ShardMode + 5, // [5:5] is the sub-list for method output_type + 5, // [5:5] is the sub-list for method input_type + 5, // [5:5] is the sub-list for extension type_name + 5, // [5:5] is the sub-list for extension extendee + 0, // [0:5] is the sub-list for field type_name } func init() { file_pkg_services_control_types_proto_init() } @@ -760,6 +825,18 @@ func file_pkg_services_control_types_proto_init() { } } file_pkg_services_control_types_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BlobstorInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_services_control_types_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*NodeInfo_Attribute); i { case 0: return &v.state @@ -778,7 +855,7 @@ func file_pkg_services_control_types_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_pkg_services_control_types_proto_rawDesc, NumEnums: 3, - NumMessages: 5, + NumMessages: 6, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/services/control/types.proto b/pkg/services/control/types.proto index 0729e4ebb..1994e2448 100644 --- a/pkg/services/control/types.proto +++ b/pkg/services/control/types.proto @@ -128,8 +128,8 @@ message ShardInfo { // Path to shard's metabase. string metabase_path = 2 [json_name = "metabasePath"]; - // Path to shard's blobstor. - string blobstor_path = 3 [json_name = "blobstorPath"]; + // Shard's blobstor info. + repeated BlobstorInfo blobstor = 3 [json_name = "blobstor"]; // Path to shard's write-cache, empty if disabled. string writecache_path = 4 [json_name = "writecachePath"]; @@ -144,6 +144,14 @@ message ShardInfo { string pilorama_path = 7 [json_name = "piloramaPath"]; } +// Blobstor component description. +message BlobstorInfo { + // Path to the root. + string path = 1 [json_name = "path"]; + // Component type. + string type = 2 [json_name = "type"]; +} + // Work mode of the shard. enum ShardMode { // Undefined mode, default value. diff --git a/pkg/services/control/types_neofs.pb.go b/pkg/services/control/types_neofs.pb.go index 8dd46362e..148f1869c 100644 --- a/pkg/services/control/types_neofs.pb.go +++ b/pkg/services/control/types_neofs.pb.go @@ -144,7 +144,9 @@ func (x *Netmap) StableMarshal(buf []byte) []byte { func (x *ShardInfo) StableSize() (size int) { size += proto.BytesSize(1, x.Shard_ID) size += proto.StringSize(2, x.MetabasePath) - size += proto.StringSize(3, x.BlobstorPath) + for i := range x.Blobstor { + size += proto.NestedStructureSize(3, x.Blobstor[i]) + } size += proto.StringSize(4, x.WritecachePath) size += proto.EnumSize(5, int32(x.Mode)) size += proto.UInt32Size(6, x.ErrorCount) @@ -170,10 +172,42 @@ func (x *ShardInfo) StableMarshal(buf []byte) []byte { var offset int offset += proto.BytesMarshal(1, buf[offset:], x.Shard_ID) offset += proto.StringMarshal(2, buf[offset:], x.MetabasePath) - offset += proto.StringMarshal(3, buf[offset:], x.BlobstorPath) + for i := range x.Blobstor { + offset += proto.NestedStructureMarshal(3, buf[offset:], x.Blobstor[i]) + } offset += proto.StringMarshal(4, buf[offset:], x.WritecachePath) offset += proto.EnumMarshal(5, buf[offset:], int32(x.Mode)) offset += proto.UInt32Marshal(6, buf[offset:], x.ErrorCount) offset += proto.StringMarshal(7, buf[offset:], x.PiloramaPath) return buf } + +// StableSize returns the size of x in protobuf format. +// +// Structures with the same field values have the same binary size. +func (x *BlobstorInfo) StableSize() (size int) { + size += proto.StringSize(1, x.Path) + size += proto.StringSize(2, x.Type) + return size +} + +// StableMarshal marshals x in protobuf binary format with stable field order. +// +// If buffer length is less than x.StableSize(), new buffer is allocated. +// +// Returns any error encountered which did not allow writing the data completely. +// Otherwise, returns the buffer in which the data is written. +// +// Structures with the same field values have the same binary format. +func (x *BlobstorInfo) StableMarshal(buf []byte) []byte { + if x == nil { + return []byte{} + } + if buf == nil { + buf = make([]byte, x.StableSize()) + } + var offset int + offset += proto.StringMarshal(1, buf[offset:], x.Path) + offset += proto.StringMarshal(2, buf[offset:], x.Type) + return buf +} diff --git a/pkg/services/control/types_test.go b/pkg/services/control/types_test.go index 40a0d17a9..79b6da8e6 100644 --- a/pkg/services/control/types_test.go +++ b/pkg/services/control/types_test.go @@ -7,6 +7,8 @@ import ( "testing" "github.com/google/uuid" + "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/blobovniczatree" + "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/fstree" "github.com/nspcc-dev/neofs-node/pkg/services/control" ) @@ -138,7 +140,9 @@ func generateShardInfo(id int) *control.ShardInfo { si.SetID(bin) si.SetMode(control.ShardMode_READ_WRITE) si.SetMetabasePath(filepath.Join(path, "meta")) - si.SetBlobstorPath(filepath.Join(path, "blobstor")) + si.Blobstor = []*control.BlobstorInfo{ + {Type: fstree.Type, Path: filepath.Join(path, "fstree")}, + {Type: blobovniczatree.Type, Path: filepath.Join(path, "blobtree")}} si.SetWriteCachePath(filepath.Join(path, "writecache")) si.SetPiloramaPath(filepath.Join(path, "pilorama"))