diff options
author | Alexander Rutkovsky <[email protected]> | 2025-09-26 07:58:38 +0300 |
---|---|---|
committer | GitHub <[email protected]> | 2025-09-26 07:58:38 +0300 |
commit | d7cd65635ff05f602b8eb7c6e2a42217057dd2c6 (patch) | |
tree | f08dbfc2c5e8791b29ee639df88821eb60f21c51 | |
parent | baebf65595da05b59f09d476cd49dcfb6c0c7dc0 (diff) |
Allow changing static PDisk configs through distconf (#25733)
-rw-r--r-- | ydb/core/blobstorage/nodewarden/distconf_invoke_storage_config.cpp | 1 | ||||
-rw-r--r-- | ydb/core/blobstorage/nodewarden/node_warden_impl.cpp | 27 | ||||
-rw-r--r-- | ydb/core/mind/bscontroller/bsc.cpp | 27 | ||||
-rw-r--r-- | ydb/core/mind/bscontroller/config.h | 30 | ||||
-rw-r--r-- | ydb/core/mind/bscontroller/config_cmd.cpp | 7 | ||||
-rw-r--r-- | ydb/core/mind/bscontroller/impl.h | 16 | ||||
-rw-r--r-- | ydb/core/protos/blobstorage.proto | 2 | ||||
-rw-r--r-- | ydb/core/protos/blobstorage_config.proto | 4 |
8 files changed, 86 insertions, 28 deletions
diff --git a/ydb/core/blobstorage/nodewarden/distconf_invoke_storage_config.cpp b/ydb/core/blobstorage/nodewarden/distconf_invoke_storage_config.cpp index a600e55aec7..54c15fdd950 100644 --- a/ydb/core/blobstorage/nodewarden/distconf_invoke_storage_config.cpp +++ b/ydb/core/blobstorage/nodewarden/distconf_invoke_storage_config.cpp @@ -476,6 +476,7 @@ namespace NKikimr::NStorage { case EControllerOp::OTHER: record.SetOperation(NKikimrBlobStorage::TEvControllerDistconfRequest::ValidateConfig); + record.MutableStorageConfig()->PackFrom(ProposedStorageConfig); break; case EControllerOp::UNSET: diff --git a/ydb/core/blobstorage/nodewarden/node_warden_impl.cpp b/ydb/core/blobstorage/nodewarden/node_warden_impl.cpp index 0b0d227b5bc..1611222de0e 100644 --- a/ydb/core/blobstorage/nodewarden/node_warden_impl.cpp +++ b/ydb/core/blobstorage/nodewarden/node_warden_impl.cpp @@ -1395,6 +1395,10 @@ bool NKikimr::NStorage::DeriveStorageConfig(const NKikimrConfig::TAppConfig& app const auto& bsFrom = appConfig.GetBlobStorageConfig(); auto *bsTo = config->MutableBlobStorageConfig(); + const auto hasStaticGroupInfo = [](const NKikimrBlobStorage::TNodeWardenServiceSet& ss) { + return ss.PDisksSize() && ss.VDisksSize() && ss.GroupsSize(); + }; + if (bsFrom.HasServiceSet()) { const auto& ssFrom = bsFrom.GetServiceSet(); auto *ssTo = bsTo->MutableServiceSet(); @@ -1411,10 +1415,6 @@ bool NKikimr::NStorage::DeriveStorageConfig(const NKikimrConfig::TAppConfig& app ssTo->ClearReplBrokerConfig(); } - const auto hasStaticGroupInfo = [](const NKikimrBlobStorage::TNodeWardenServiceSet& ss) { - return ss.PDisksSize() && ss.VDisksSize() && ss.GroupsSize(); - }; - // update static group information unless distconf is enabled if (!hasStaticGroupInfo(ssFrom) && config->GetSelfManagementConfig().GetEnabled()) { // distconf enabled, keep it as is @@ -1548,6 +1548,25 @@ bool NKikimr::NStorage::DeriveStorageConfig(const NKikimrConfig::TAppConfig& app bsTo->ClearBscSettings(); } + // copy PDiskConfig from DefineHostConfig/DefineBox if this section is managed automatically + if (!hasStaticGroupInfo(bsFrom.GetServiceSet()) && config->GetSelfManagementConfig().GetEnabled()) { + THashMap<std::tuple<ui32, TString>, NKikimrBlobStorage::TPDiskConfig> pdiskConfigs; + auto callback = [&](const auto& node, const auto& drive) { + if (drive.HasPDiskConfig()) { + pdiskConfigs.emplace(std::make_tuple(node.GetNodeId(), drive.GetPath()), drive.GetPDiskConfig()); + } + }; + EnumerateConfigDrives(*config, 0, callback, nullptr, true); + for (auto& pdisk : *bsTo->MutableServiceSet()->MutablePDisks()) { + const auto key = std::make_tuple(pdisk.GetNodeID(), pdisk.GetPath()); + if (const auto it = pdiskConfigs.find(key); it != pdiskConfigs.end()) { + pdisk.MutablePDiskConfig()->CopyFrom(it->second); + } else { + pdisk.ClearPDiskConfig(); + } + } + } + // copy nameservice-related things if (!appConfig.HasNameserviceConfig()) { *errorReason = "origin config missing mandatory NameserviceConfig section"; diff --git a/ydb/core/mind/bscontroller/bsc.cpp b/ydb/core/mind/bscontroller/bsc.cpp index 79bba7309d6..87f7db35df8 100644 --- a/ydb/core/mind/bscontroller/bsc.cpp +++ b/ydb/core/mind/bscontroller/bsc.cpp @@ -593,6 +593,8 @@ std::unique_ptr<TEvBlobStorage::TEvControllerConfigRequest> TBlobStorageControll request->SetRollback(true); } + request->MutableStorageConfig()->PackFrom(storageConfig); + if (request->CommandSize()) { return ev; } @@ -757,21 +759,24 @@ void TBlobStorageController::Handle(TEvBlobStorage::TEvControllerDistconfRequest break; } - const TString& effectiveConfig = storageYaml ? *storageYaml : *mainYaml; NKikimrBlobStorage::TStorageConfig storageConfig; - - try { - NKikimrConfig::TAppConfig appConfig = NYaml::Parse(effectiveConfig); - TString errorReason; - if (!NKikimr::NStorage::DeriveStorageConfig(appConfig, &storageConfig, &errorReason)) { + if (record.HasStorageConfig()) { + record.GetStorageConfig().UnpackTo(&storageConfig); + } else { + const TString& effectiveConfig = storageYaml ? *storageYaml : *mainYaml; + try { + NKikimrConfig::TAppConfig appConfig = NYaml::Parse(effectiveConfig); + TString errorReason; + if (!NKikimr::NStorage::DeriveStorageConfig(appConfig, &storageConfig, &errorReason)) { + rr.SetStatus(NKikimrBlobStorage::TEvControllerDistconfResponse::Error); + rr.SetErrorReason("failed to derive storage config: " + errorReason); + break; + } + } catch (const std::exception& ex) { rr.SetStatus(NKikimrBlobStorage::TEvControllerDistconfResponse::Error); - rr.SetErrorReason("failed to derive storage config: " + errorReason); + rr.SetErrorReason(TStringBuilder() << "failed to parse YAML: " << ex.what()); break; } - } catch (const std::exception& ex) { - rr.SetStatus(NKikimrBlobStorage::TEvControllerDistconfResponse::Error); - rr.SetErrorReason(TStringBuilder() << "failed to parse YAML: " << ex.what()); - break; } const ui64 cookie = NextValidationCookie++; diff --git a/ydb/core/mind/bscontroller/config.h b/ydb/core/mind/bscontroller/config.h index 1fc5343a27e..c579216e2ec 100644 --- a/ydb/core/mind/bscontroller/config.h +++ b/ydb/core/mind/bscontroller/config.h @@ -128,6 +128,9 @@ namespace NKikimr { const ui32 DefaultMaxSlots; // static pdisk/vdisk states + std::map<TVSlotId, TStaticVSlotInfo> NewStaticVSlots; + std::map<TPDiskId, TStaticPDiskInfo> NewStaticPDisks; + std::map<TGroupId, TStaticGroupInfo> NewStaticGroups; std::map<TVSlotId, TStaticVSlotInfo>& StaticVSlots; std::map<TPDiskId, TStaticPDiskInfo>& StaticPDisks; std::map<TGroupId, TStaticGroupInfo>& StaticGroups; @@ -147,7 +150,7 @@ namespace NKikimr { public: TConfigState(TBlobStorageController &controller, const THostRecordMap &hostRecords, TInstant timestamp, - TMonotonic mono) + TMonotonic mono, const NKikimrBlobStorage::TStorageConfig *storageConfig = nullptr) : Self(controller) , HostConfigs(&controller.HostConfigs) , Boxes(&controller.Boxes) @@ -168,14 +171,33 @@ namespace NKikimr { , Mono(mono) , DonorMode(controller.DonorMode) , DefaultMaxSlots(controller.DefaultMaxSlots) - , StaticVSlots(controller.StaticVSlots) - , StaticPDisks(controller.StaticPDisks) - , StaticGroups(controller.StaticGroups) + , StaticVSlots(storageConfig && storageConfig->HasBlobStorageConfig() ? NewStaticVSlots : controller.StaticVSlots) + , StaticPDisks(storageConfig && storageConfig->HasBlobStorageConfig() ? NewStaticPDisks : controller.StaticPDisks) + , StaticGroups(storageConfig && storageConfig->HasBlobStorageConfig() ? NewStaticGroups : controller.StaticGroups) , SerialManagementStage(&controller.SerialManagementStage) , StoragePoolStat(*controller.StoragePoolStat) , BridgeInfo(controller.BridgeInfo) { Y_ABORT_UNLESS(HostRecords); + if (storageConfig && storageConfig->HasBlobStorageConfig()) { + const auto& bsConfig = storageConfig->GetBlobStorageConfig(); + const auto& ss = bsConfig.GetServiceSet(); + for (const auto& pdisk : ss.GetPDisks()) { + const TPDiskId pdiskId(pdisk.GetNodeID(), pdisk.GetPDiskID()); + NewStaticPDisks.try_emplace(pdiskId, pdisk, controller.StaticPDisks); + } + for (const auto& vslot : ss.GetVDisks()) { + const auto& location = vslot.GetVDiskLocation(); + const TPDiskId pdiskId(location.GetNodeID(), location.GetPDiskID()); + const TVSlotId vslotId(pdiskId, location.GetVDiskSlotID()); + NewStaticVSlots.try_emplace(vslotId, vslot, controller.StaticVSlots, Mono); + ++StaticPDisks.at(pdiskId).StaticSlotUsage; + } + for (const auto& group : ss.GetGroups()) { + const auto groupId = TGroupId::FromProto(&group, &NKikimrBlobStorage::TGroupInfo::GetGroupID); + NewStaticGroups.try_emplace(groupId, group, controller.StaticGroups); + } + } } void Commit() { diff --git a/ydb/core/mind/bscontroller/config_cmd.cpp b/ydb/core/mind/bscontroller/config_cmd.cpp index dcaca16ae97..3fa20538d5e 100644 --- a/ydb/core/mind/bscontroller/config_cmd.cpp +++ b/ydb/core/mind/bscontroller/config_cmd.cpp @@ -185,7 +185,12 @@ namespace NKikimr::NBsController { } const auto& hostRecords = EnforceHostRecords ? *EnforceHostRecords : Self->HostRecords; - State.emplace(*Self, hostRecords, TActivationContext::Now(), TActivationContext::Monotonic()); + std::optional<NKikimrBlobStorage::TStorageConfig> storageConfig; + if (Cmd.HasStorageConfig() && Self->SelfManagementEnabled) { + Cmd.GetStorageConfig().UnpackTo(&storageConfig.emplace()); + } + State.emplace(*Self, hostRecords, TActivationContext::Now(), TActivationContext::Monotonic(), + storageConfig ? &storageConfig.value() : nullptr); State->CheckConsistency(); TString m; diff --git a/ydb/core/mind/bscontroller/impl.h b/ydb/core/mind/bscontroller/impl.h index e2a3e535d9e..96e129d4200 100644 --- a/ydb/core/mind/bscontroller/impl.h +++ b/ydb/core/mind/bscontroller/impl.h @@ -2420,7 +2420,7 @@ public: TGroupInfo::TGroupStatus Status; bool LayoutCorrect = true; - TStaticGroupInfo(const NKikimrBlobStorage::TGroupInfo& group, std::map<TGroupId, TStaticGroupInfo>& prev) { + TStaticGroupInfo(const NKikimrBlobStorage::TGroupInfo& group, const std::map<TGroupId, TStaticGroupInfo>& prev) { TStringStream err; Info = TBlobStorageGroupInfo::Parse(group, nullptr, &err); Y_VERIFY_DEBUG_S(Info, "failed to parse static group, error# " << err.Str()); @@ -2428,7 +2428,7 @@ public: return; } if (const auto it = prev.find(Info->GroupID); it != prev.end()) { - TStaticGroupInfo& item = it->second; + const TStaticGroupInfo& item = it->second; Status = item.Status; LayoutCorrect = item.LayoutCorrect; } @@ -2456,15 +2456,15 @@ public: bool MetricsDirty = false; TStaticVSlotInfo(const NKikimrBlobStorage::TNodeWardenServiceSet::TVDisk& vdisk, - std::map<TVSlotId, TStaticVSlotInfo>& prev, TMonotonic mono) + const std::map<TVSlotId, TStaticVSlotInfo>& prev, TMonotonic mono) : VDiskId(VDiskIDFromVDiskID(vdisk.GetVDiskID())) , VDiskKind(vdisk.GetVDiskKind()) { const auto& loc = vdisk.GetVDiskLocation(); const TVSlotId vslotId(loc.GetNodeID(), loc.GetPDiskID(), loc.GetVDiskSlotID()); if (const auto it = prev.find(vslotId); it != prev.end()) { - TStaticVSlotInfo& item = it->second; - VDiskMetrics = std::move(item.VDiskMetrics); + const TStaticVSlotInfo& item = it->second; + VDiskMetrics = item.VDiskMetrics; VDiskStatus = item.VDiskStatus; VDiskStatusTimestamp = item.VDiskStatusTimestamp; ReadySince = item.ReadySince; @@ -2493,7 +2493,7 @@ public: std::optional<NKikimrBlobStorage::TPDiskMetrics> PDiskMetrics; TStaticPDiskInfo(const NKikimrBlobStorage::TNodeWardenServiceSet::TPDisk& pdisk, - std::map<TPDiskId, TStaticPDiskInfo>& prev) + const std::map<TPDiskId, TStaticPDiskInfo>& prev) : NodeId(pdisk.GetNodeID()) , PDiskId(pdisk.GetPDiskID()) , Path(pdisk.GetPath()) @@ -2511,8 +2511,8 @@ public: const TPDiskId pdiskId(NodeId, PDiskId); if (const auto it = prev.find(pdiskId); it != prev.end()) { - TStaticPDiskInfo& item = it->second; - PDiskMetrics = std::move(item.PDiskMetrics); + const TStaticPDiskInfo& item = it->second; + PDiskMetrics = item.PDiskMetrics; } } diff --git a/ydb/core/protos/blobstorage.proto b/ydb/core/protos/blobstorage.proto index b5e0de82e78..d5ee5d0928a 100644 --- a/ydb/core/protos/blobstorage.proto +++ b/ydb/core/protos/blobstorage.proto @@ -8,6 +8,7 @@ import "ydb/core/protos/blobstorage_config.proto"; import "ydb/core/protos/blobstorage_disk.proto"; import "ydb/core/protos/blobstorage_disk_color.proto"; import "ydb/core/protos/node_whiteboard.proto"; +import "google/protobuf/any.proto"; package NKikimrBlobStorage; option java_package = "ru.yandex.kikimr.proto"; @@ -1563,6 +1564,7 @@ message TEvControllerDistconfRequest { optional uint64 ExpectedStorageConfigVersion = 5; optional string PeerName = 6; optional bytes UserToken = 7; + optional google.protobuf.Any StorageConfig = 8; // TStorageConfig with this request that is going to be applied after operation } message TEvControllerDistconfResponse { diff --git a/ydb/core/protos/blobstorage_config.proto b/ydb/core/protos/blobstorage_config.proto index b5cde682217..030651ec3d7 100644 --- a/ydb/core/protos/blobstorage_config.proto +++ b/ydb/core/protos/blobstorage_config.proto @@ -7,6 +7,7 @@ import "ydb/core/protos/blobstorage_disk_color.proto"; import "ydb/core/protos/blobstorage_pdisk_config.proto"; import "ydb/core/protos/blob_depot_config.proto"; import "ydb/library/actors/protos/interconnect.proto"; +import "google/protobuf/any.proto"; package NKikimrBlobStorage; @@ -686,6 +687,9 @@ message TConfigRequest { // requesting user identifier string UserSID = 13; + + // current TStorageConfig against which we are processing this request + google.protobuf.Any StorageConfig = 14; } enum ETriStateBool { |