summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Rutkovsky <[email protected]>2025-09-26 07:58:38 +0300
committerGitHub <[email protected]>2025-09-26 07:58:38 +0300
commitd7cd65635ff05f602b8eb7c6e2a42217057dd2c6 (patch)
treef08dbfc2c5e8791b29ee639df88821eb60f21c51
parentbaebf65595da05b59f09d476cd49dcfb6c0c7dc0 (diff)
Allow changing static PDisk configs through distconf (#25733)
-rw-r--r--ydb/core/blobstorage/nodewarden/distconf_invoke_storage_config.cpp1
-rw-r--r--ydb/core/blobstorage/nodewarden/node_warden_impl.cpp27
-rw-r--r--ydb/core/mind/bscontroller/bsc.cpp27
-rw-r--r--ydb/core/mind/bscontroller/config.h30
-rw-r--r--ydb/core/mind/bscontroller/config_cmd.cpp7
-rw-r--r--ydb/core/mind/bscontroller/impl.h16
-rw-r--r--ydb/core/protos/blobstorage.proto2
-rw-r--r--ydb/core/protos/blobstorage_config.proto4
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 {