Skip to content

Commit 18e5a12

Browse files
authored
Fix distconf automatic box management (merge from main #15429) (#15447)
1 parent 3a3c392 commit 18e5a12

File tree

2 files changed

+142
-44
lines changed

2 files changed

+142
-44
lines changed

ydb/core/mind/bscontroller/bsc.cpp

Lines changed: 141 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,76 @@ void TBlobStorageController::Handle(TEvents::TEvUndelivered::TPtr ev) {
197197
}
198198
}
199199

200+
bool TBlobStorageController::HostConfigEquals(const THostConfigInfo& left, const NKikimrBlobStorage::TDefineHostConfig& right) const {
201+
if (left.Name != right.GetName()) {
202+
return false;
203+
}
204+
205+
THashMap<TStringBuf, const THostConfigInfo::TDriveInfo*> driveMap;
206+
for (const auto& [key, info] : left.Drives) {
207+
driveMap.emplace(key.Path, &info);
208+
}
209+
210+
TMaybe<TString> defaultPDiskConfig;
211+
if (right.HasDefaultHostPDiskConfig()) {
212+
const bool success = right.GetDefaultHostPDiskConfig().SerializeToString(&defaultPDiskConfig.ConstructInPlace());
213+
Y_ABORT_UNLESS(success);
214+
}
215+
216+
auto checkDrive = [&](const auto& drive) {
217+
const auto it = driveMap.find(drive.GetPath());
218+
if (it == driveMap.end()) {
219+
return false;
220+
}
221+
222+
if (drive.GetType() != it->second->Type ||
223+
drive.GetSharedWithOs() != it->second->SharedWithOs ||
224+
drive.GetReadCentric() != it->second->ReadCentric ||
225+
drive.GetKind() != it->second->Kind) {
226+
return false;
227+
}
228+
229+
TMaybe<TString> pdiskConfig;
230+
if (drive.HasPDiskConfig()) {
231+
const bool success = drive.GetPDiskConfig().SerializeToString(&pdiskConfig.ConstructInPlace());
232+
Y_ABORT_UNLESS(success);
233+
} else {
234+
pdiskConfig = defaultPDiskConfig;
235+
}
236+
237+
if (pdiskConfig != it->second->PDiskConfig) {
238+
return false;
239+
}
240+
241+
driveMap.erase(it);
242+
return true;
243+
};
244+
245+
for (const auto& drive : right.GetDrive()) {
246+
if (!checkDrive(drive)) {
247+
return false;
248+
}
249+
}
250+
251+
auto addDrives = [&](const auto& field, NKikimrBlobStorage::EPDiskType type) {
252+
NKikimrBlobStorage::THostConfigDrive drive;
253+
drive.SetType(type);
254+
for (const auto& path : field) {
255+
if (drive.SetPath(path); !checkDrive(drive)) {
256+
return false;
257+
}
258+
}
259+
return true;
260+
};
261+
if (!addDrives(right.GetRot(), NKikimrBlobStorage::EPDiskType::ROT) ||
262+
!addDrives(right.GetSsd(), NKikimrBlobStorage::EPDiskType::SSD) ||
263+
!addDrives(right.GetNvme(), NKikimrBlobStorage::EPDiskType::NVME)) {
264+
return false;
265+
}
266+
267+
return driveMap.empty();
268+
}
269+
200270
void TBlobStorageController::ApplyStorageConfig(bool ignoreDistconf) {
201271
if (!StorageConfig.HasBlobStorageConfig()) {
202272
return;
@@ -211,74 +281,101 @@ void TBlobStorageController::ApplyStorageConfig(bool ignoreDistconf) {
211281
return; // not expected to be managed by BSC
212282
}
213283

284+
ui64 expectedBoxId;
214285
std::optional<ui64> generation;
286+
bool needToDefineBox = true;
215287
if (!Boxes.empty()) {
216288
const auto& [boxId, box] = *Boxes.begin();
217289

218-
THashSet<THostConfigId> unusedHostConfigs;
219-
for (const auto& [hostConfigId, _] : HostConfigs) {
220-
unusedHostConfigs.insert(hostConfigId);
290+
expectedBoxId = boxId;
291+
generation = box.Generation.GetOrElse(1);
292+
needToDefineBox = false;
293+
294+
// put all existing hosts of a singular box into the set
295+
THashSet<std::tuple<TString, ui32, ui64, TMaybe<ui32>>> hosts;
296+
for (const auto& [key, value] : box.Hosts) {
297+
hosts.emplace(key.Fqdn, key.IcPort, value.HostConfigId, value.EnforcedNodeId);
221298
}
222-
for (const auto& [_, host] : box.Hosts) {
223-
if (!HostConfigs.contains(host.HostConfigId)) {
224-
return;
299+
300+
// drop matching entries from the new set
301+
for (const auto& host : bsConfig.GetDefineBox().GetHost()) {
302+
const auto& resolved = HostRecords->GetHostId(host.GetEnforcedNodeId());
303+
Y_ABORT_UNLESS(resolved);
304+
const auto& [fqdn, port] = *resolved;
305+
306+
if (!hosts.erase(std::make_tuple(fqdn, port, host.GetHostConfigId(), Nothing()))) {
307+
needToDefineBox = true;
308+
break;
225309
}
226-
unusedHostConfigs.erase(host.HostConfigId);
227310
}
228311

229-
if (!unusedHostConfigs.empty()) {
230-
return;
312+
if (!hosts.empty()) {
313+
needToDefineBox = true;
231314
}
232-
233-
generation = box.Generation.GetOrElse(0);
234315
}
235316

236317
auto ev = std::make_unique<TEvBlobStorage::TEvControllerConfigRequest>();
237318
auto& r = ev->Record;
238319
auto *request = r.MutableRequest();
239320
for (const auto& hostConfig : bsConfig.GetDefineHostConfig()) {
321+
const auto it = HostConfigs.find(hostConfig.GetHostConfigId());
322+
if (it != HostConfigs.end() && HostConfigEquals(it->second, hostConfig)) {
323+
continue;
324+
}
325+
326+
auto *cmd = request->AddCommand();
327+
auto *defineHostConfig = cmd->MutableDefineHostConfig();
328+
defineHostConfig->CopyFrom(hostConfig);
329+
if (it != HostConfigs.end()) {
330+
defineHostConfig->SetItemConfigGeneration(it->second.Generation.GetOrElse(1));
331+
}
332+
}
333+
334+
if (needToDefineBox) {
240335
auto *cmd = request->AddCommand();
241-
cmd->MutableDefineHostConfig()->CopyFrom(hostConfig);
242-
}
243-
auto *cmd = request->AddCommand();
244-
auto *defineBox = cmd->MutableDefineBox();
245-
defineBox->CopyFrom(bsConfig.GetDefineBox());
246-
defineBox->SetBoxId(1);
247-
for (auto& host : *defineBox->MutableHost()) {
248-
const ui32 nodeId = host.GetEnforcedNodeId();
249-
host.ClearEnforcedNodeId();
250-
auto *key = host.MutableKey();
251-
const auto& resolved = HostRecords->GetHostId(nodeId);
252-
Y_ABORT_UNLESS(resolved);
253-
const auto& [fqdn, port] = *resolved;
254-
key->SetFqdn(fqdn);
255-
key->SetIcPort(port);
256-
}
257-
if (generation) {
258-
defineBox->SetItemConfigGeneration(*generation);
259-
}
260-
261-
THashSet<THostConfigId> unusedHostConfigs;
262-
for (const auto& [hostConfigId, _] : HostConfigs) {
263-
unusedHostConfigs.insert(hostConfigId);
264-
}
265-
for (const auto& host : defineBox->GetHost()) {
266-
unusedHostConfigs.erase(host.GetHostConfigId());
267-
}
268-
for (const THostConfigId hostConfigId : unusedHostConfigs) {
336+
auto *defineBox = cmd->MutableDefineBox();
337+
defineBox->CopyFrom(bsConfig.GetDefineBox());
338+
defineBox->SetBoxId(expectedBoxId);
339+
for (auto& host : *defineBox->MutableHost()) {
340+
const ui32 nodeId = host.GetEnforcedNodeId();
341+
host.ClearEnforcedNodeId();
342+
auto *key = host.MutableKey();
343+
const auto& resolved = HostRecords->GetHostId(nodeId);
344+
Y_ABORT_UNLESS(resolved);
345+
const auto& [fqdn, port] = *resolved;
346+
key->SetFqdn(fqdn);
347+
key->SetIcPort(port);
348+
}
349+
if (generation) {
350+
defineBox->SetItemConfigGeneration(*generation);
351+
}
352+
}
353+
354+
THashMap<THostConfigId, ui64> unusedHostConfigs;
355+
for (const auto& [hostConfigId, value] : HostConfigs) {
356+
unusedHostConfigs.emplace(hostConfigId, value.Generation.GetOrElse(1));
357+
}
358+
for (const auto& hostConfig : bsConfig.GetDefineHostConfig()) {
359+
unusedHostConfigs.erase(hostConfig.GetHostConfigId());
360+
}
361+
for (const auto& [hostConfigId, generation] : unusedHostConfigs) {
269362
auto *cmd = request->AddCommand();
270363
auto *del = cmd->MutableDeleteHostConfig();
271364
del->SetHostConfigId(hostConfigId);
272-
del->SetItemConfigGeneration(HostConfigs[hostConfigId].Generation.GetOrElse(0));
365+
del->SetItemConfigGeneration(generation);
273366
}
274367

275-
STLOG(PRI_DEBUG, BS_CONTROLLER, BSC14, "ApplyStorageConfig", (Request, r));
276-
277-
Send(SelfId(), ev.release());
368+
if (request->CommandSize()) {
369+
STLOG(PRI_DEBUG, BS_CONTROLLER, BSC14, "ApplyStorageConfig", (Request, r));
370+
Send(SelfId(), ev.release());
371+
}
278372
}
279373

280374
void TBlobStorageController::Handle(TEvBlobStorage::TEvControllerConfigResponse::TPtr ev) {
281-
STLOG(PRI_DEBUG, BS_CONTROLLER, BSC15, "TEvControllerConfigResponse", (Response, ev->Get()->Record));
375+
auto& record = ev->Get()->Record;
376+
auto& response = record.GetResponse();
377+
STLOG(response.GetSuccess() ? PRI_DEBUG : PRI_ERROR, BS_CONTROLLER, BSC15, "TEvControllerConfigResponse",
378+
(Response, response));
282379
}
283380

284381
void TBlobStorageController::Handle(TEvBlobStorage::TEvControllerUpdateGroupStat::TPtr& ev) {

ydb/core/mind/bscontroller/impl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1790,6 +1790,7 @@ class TBlobStorageController : public TActor<TBlobStorageController>, public TTa
17901790

17911791
void Handle(TEvNodeWardenStorageConfig::TPtr ev);
17921792
void Handle(TEvents::TEvUndelivered::TPtr ev);
1793+
bool HostConfigEquals(const THostConfigInfo& left, const NKikimrBlobStorage::TDefineHostConfig& right) const;
17931794
void ApplyStorageConfig(bool ignoreDistconf = false);
17941795
void Handle(TEvBlobStorage::TEvControllerConfigResponse::TPtr ev);
17951796

0 commit comments

Comments
 (0)