Skip to content

Commit d5f8f4e

Browse files
authored
Fix bug in distconf drive enumeration code (#4873)
1 parent 9192edc commit d5f8f4e

File tree

2 files changed

+36
-38
lines changed

2 files changed

+36
-38
lines changed

ydb/core/blobstorage/nodewarden/distconf_fsm.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -299,13 +299,12 @@ namespace NKikimr::NStorage {
299299
switch (task.Request.GetRequestCase()) {
300300
case TEvScatter::kCollectConfigs: {
301301
std::vector<TString> drives;
302-
EnumerateConfigDrives(*StorageConfig, 0, [&](const auto& /*node*/, const auto& drive) {
302+
auto callback = [&](const auto& /*node*/, const auto& drive) {
303303
drives.push_back(drive.GetPath());
304-
});
304+
};
305+
EnumerateConfigDrives(*StorageConfig, SelfId().NodeId(), callback);
305306
if (ProposedStorageConfig) {
306-
EnumerateConfigDrives(*ProposedStorageConfig, 0, [&](const auto& /*node*/, const auto& drive) {
307-
drives.push_back(drive.GetPath());
308-
});
307+
EnumerateConfigDrives(*ProposedStorageConfig, SelfId().NodeId(), callback);
309308
}
310309
std::sort(drives.begin(), drives.end());
311310
drives.erase(std::unique(drives.begin(), drives.end()), drives.end());
@@ -342,8 +341,6 @@ namespace NKikimr::NStorage {
342341
}
343342

344343
PersistConfig([this, cookie](TEvPrivate::TEvStorageConfigStored& msg) {
345-
STLOG(PRI_DEBUG, BS_NODE, NWDC45, "ProposeStorageConfig TEvStorageConfigStored", (Cookie, cookie));
346-
347344
Y_ABORT_UNLESS(ProposedStorageConfigCookieUsage);
348345
Y_ABORT_UNLESS(cookie == ProposedStorageConfigCookie);
349346
--ProposedStorageConfigCookieUsage;
@@ -362,6 +359,11 @@ namespace NKikimr::NStorage {
362359
}
363360
}
364361
}
362+
STLOG(PRI_DEBUG, BS_NODE, NWDC48, "ProposeStorageConfig TEvStorageConfigStored",
363+
(Cookie, cookie), (Status, *status));
364+
} else {
365+
STLOG(PRI_DEBUG, BS_NODE, NWDC45, "ProposeStorageConfig TEvStorageConfigStored no scatter task",
366+
(Cookie, cookie));
365367
}
366368

367369
FinishAsyncOperation(cookie);

ydb/core/blobstorage/nodewarden/distconf_persistent_storage.cpp

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -86,15 +86,12 @@ namespace NKikimr::NStorage {
8686
}
8787

8888
std::vector<TString> drives;
89+
auto processDrive = [&](const auto& /*node*/, const auto& drive) { drives.push_back(drive.GetPath()); };
8990
if (item.Record.HasCommittedStorageConfig()) {
90-
EnumerateConfigDrives(item.Record.GetCommittedStorageConfig(), 0, [&](const auto& /*node*/, const auto& drive) {
91-
drives.push_back(drive.GetPath());
92-
});
91+
EnumerateConfigDrives(item.Record.GetCommittedStorageConfig(), SelfId().NodeId(), processDrive);
9392
}
9493
if (item.Record.HasProposedStorageConfig()) {
95-
EnumerateConfigDrives(item.Record.GetProposedStorageConfig(), 0, [&](const auto& /*node*/, const auto& drive) {
96-
drives.push_back(drive.GetPath());
97-
});
94+
EnumerateConfigDrives(item.Record.GetProposedStorageConfig(), SelfId().NodeId(), processDrive);
9895
}
9996
std::sort(drives.begin(), drives.end());
10097
drives.erase(std::unique(drives.begin(), drives.end()), drives.end());
@@ -224,19 +221,19 @@ namespace NKikimr::NStorage {
224221

225222
namespace NKikimr {
226223

224+
static const TString VaultLockFile = "/Berkanavt/kikimr/state/storage.lock";
227225
static const TString VaultPath = "/Berkanavt/kikimr/state/storage.txt";
226+
static TMutex VaultMutex;
228227

229-
static bool ReadVault(TFile& file, NKikimrBlobStorage::TStorageFileContent& vault) {
230-
TString buffer;
231-
try {
232-
buffer = TFileInput(file).ReadAll();
233-
} catch (...) {
234-
return false;
235-
}
236-
if (!buffer) {
228+
static bool ReadVault(NKikimrBlobStorage::TStorageFileContent& vault) {
229+
if (TFileHandle fh(VaultPath, OpenExisting | RdOnly); !fh.IsOpen()) {
230+
return true;
231+
} else if (TString buffer = TString::Uninitialized(fh.GetLength())) {
232+
return fh.Read(buffer.Detach(), buffer.size()) == (i32)buffer.size() &&
233+
google::protobuf::util::JsonStringToMessage(buffer, &vault).ok();
234+
} else {
237235
return true;
238236
}
239-
return google::protobuf::util::JsonStringToMessage(buffer, &vault).ok();
240237
}
241238

242239
static bool WriteVault(NKikimrBlobStorage::TStorageFileContent& vault) {
@@ -245,30 +242,29 @@ namespace NKikimr {
245242
Y_ABORT_UNLESS(success);
246243

247244
const TString tempPath = VaultPath + ".tmp";
248-
TFileHandle fh1(tempPath, OpenAlways);
249-
if (!fh1.IsOpen() || fh1.Write(buffer.data(), buffer.size()) != (i32)buffer.size()) {
245+
if (TFileHandle fh(tempPath, CreateAlways | WrOnly); !fh.IsOpen()) {
250246
return false;
251-
}
252-
253-
if (!NFs::Rename(tempPath, VaultPath)) {
247+
} else if (fh.Flock(LOCK_EX | LOCK_NB)) {
248+
Y_DEBUG_ABORT("unexpected lock race");
249+
return false;
250+
} else if (fh.Write(buffer.data(), buffer.size()) != (i32)buffer.size()) {
251+
return false;
252+
} else if (!NFs::Rename(tempPath, VaultPath)) {
254253
return false;
255254
}
256-
257255
return true;
258256
}
259257

260258
NPDisk::EPDiskMetadataOutcome ReadPDiskMetadata(const TString& path, const NPDisk::TMainKey& key, TRcBuf& metadata,
261259
std::optional<ui64> *pdiskGuid) {
262-
TFileHandle fh(VaultPath, OpenExisting | RdWr);
263-
if (!fh.IsOpen()) {
264-
return NPDisk::EPDiskMetadataOutcome::NO_METADATA;
265-
} else if (fh.Flock(LOCK_SH)) {
260+
TGuard<TMutex> guard(VaultMutex);
261+
TFileHandle lock(VaultLockFile, OpenAlways);
262+
if (!lock.IsOpen() || flock(lock, LOCK_EX) == -1) {
266263
return NPDisk::EPDiskMetadataOutcome::ERROR;
267264
}
268-
TFile file(fh.Release());
269265

270266
NKikimrBlobStorage::TStorageFileContent vault;
271-
if (!ReadVault(file, vault)) {
267+
if (!ReadVault(vault)) {
272268
return NPDisk::EPDiskMetadataOutcome::ERROR;
273269
}
274270

@@ -323,14 +319,14 @@ namespace NKikimr {
323319

324320
NPDisk::EPDiskMetadataOutcome WritePDiskMetadata(const TString& path, const NPDisk::TMainKey& key, TRcBuf&& metadata,
325321
std::optional<ui64> *pdiskGuid) {
326-
TFileHandle fh(VaultPath, OpenAlways);
327-
if (!fh.IsOpen() || fh.Flock(LOCK_EX)) {
322+
TGuard<TMutex> guard(VaultMutex);
323+
TFileHandle lock(VaultLockFile, OpenAlways);
324+
if (!lock.IsOpen() || flock(lock, LOCK_EX) == -1) {
328325
return NPDisk::EPDiskMetadataOutcome::ERROR;
329326
}
330-
TFile file(fh.Release());
331327

332328
NKikimrBlobStorage::TStorageFileContent vault;
333-
if (!ReadVault(file, vault)) {
329+
if (!ReadVault(vault)) {
334330
return NPDisk::EPDiskMetadataOutcome::ERROR;
335331
}
336332

0 commit comments

Comments
 (0)