diff options
author | serg-belyakov <serg-belyakov@yandex-team.com> | 2023-07-27 16:49:51 +0300 |
---|---|---|
committer | serg-belyakov <serg-belyakov@yandex-team.com> | 2023-07-27 16:49:51 +0300 |
commit | ae39bd001619ae985b82507fa070b8520720131a (patch) | |
tree | 3d056f5cd64a83de2878216572feadb542e93d7c | |
parent | 576a61b1beb4548edf1c9f0281799d74ca7c78f7 (diff) | |
download | ydb-ae39bd001619ae985b82507fa070b8520720131a.tar.gz |
Add TCompatibilityInfo to PDisk, KIKIMR-15989
Use PDISK_SYS_LOG_RECORD_VERSION_7 as current
Add serialized CompatibilityInfo to sys log format
10 files changed, 202 insertions, 38 deletions
diff --git a/ydb/core/blobstorage/pdisk/CMakeLists.darwin-x86_64.txt b/ydb/core/blobstorage/pdisk/CMakeLists.darwin-x86_64.txt index 69594119e22..0e624df7a73 100644 --- a/ydb/core/blobstorage/pdisk/CMakeLists.darwin-x86_64.txt +++ b/ydb/core/blobstorage/pdisk/CMakeLists.darwin-x86_64.txt @@ -36,6 +36,7 @@ target_link_libraries(core-blobstorage-pdisk PUBLIC core-blobstorage-groupinfo core-blobstorage-lwtrace_probes ydb-core-control + version ydb-core-protos ydb-core-util ydb-library-pdisk_io diff --git a/ydb/core/blobstorage/pdisk/CMakeLists.linux-aarch64.txt b/ydb/core/blobstorage/pdisk/CMakeLists.linux-aarch64.txt index 14483b3155f..5e9d1889dbd 100644 --- a/ydb/core/blobstorage/pdisk/CMakeLists.linux-aarch64.txt +++ b/ydb/core/blobstorage/pdisk/CMakeLists.linux-aarch64.txt @@ -37,6 +37,7 @@ target_link_libraries(core-blobstorage-pdisk PUBLIC core-blobstorage-groupinfo core-blobstorage-lwtrace_probes ydb-core-control + version ydb-core-protos ydb-core-util ydb-library-pdisk_io diff --git a/ydb/core/blobstorage/pdisk/CMakeLists.linux-x86_64.txt b/ydb/core/blobstorage/pdisk/CMakeLists.linux-x86_64.txt index 14483b3155f..5e9d1889dbd 100644 --- a/ydb/core/blobstorage/pdisk/CMakeLists.linux-x86_64.txt +++ b/ydb/core/blobstorage/pdisk/CMakeLists.linux-x86_64.txt @@ -37,6 +37,7 @@ target_link_libraries(core-blobstorage-pdisk PUBLIC core-blobstorage-groupinfo core-blobstorage-lwtrace_probes ydb-core-control + version ydb-core-protos ydb-core-util ydb-library-pdisk_io diff --git a/ydb/core/blobstorage/pdisk/CMakeLists.windows-x86_64.txt b/ydb/core/blobstorage/pdisk/CMakeLists.windows-x86_64.txt index 69594119e22..0e624df7a73 100644 --- a/ydb/core/blobstorage/pdisk/CMakeLists.windows-x86_64.txt +++ b/ydb/core/blobstorage/pdisk/CMakeLists.windows-x86_64.txt @@ -36,6 +36,7 @@ target_link_libraries(core-blobstorage-pdisk PUBLIC core-blobstorage-groupinfo core-blobstorage-lwtrace_probes ydb-core-control + version ydb-core-protos ydb-core-util ydb-library-pdisk_io diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_data.h b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_data.h index ae34711a718..ebf8b8f71be 100644 --- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_data.h +++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_data.h @@ -47,6 +47,7 @@ constexpr ui32 SmallDiskMaximumChunkSize = 32 * (1 << 20); // 32MB #define PDISK_SYS_LOG_RECORD_VERSION_4 4 // #define PDISK_SYS_LOG_RECORD_VERSION_5 5 // It was used in reverted commits, just avoid this version #define PDISK_SYS_LOG_RECORD_VERSION_6 6 +#define PDISK_SYS_LOG_RECORD_VERSION_7 7 #define PDISK_SYS_LOG_RECORD_INCOMPATIBLE_VERSION_1000 1000 #define FORMAT_TEXT_SIZE 1024 @@ -331,7 +332,7 @@ struct TSysLogRecord { TVDiskID OwnerVDisks[256]; TSysLogRecord() - : Version(PDISK_SYS_LOG_RECORD_VERSION_6) + : Version(PDISK_SYS_LOG_RECORD_VERSION_7) , LogHeadChunkIdx(0) , Reserved1(0) , LogHeadChunkPreviousNonce((ui64)-1) diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl.h b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl.h index 3e80f29a484..75e271996ab 100644 --- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl.h +++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl.h @@ -22,6 +22,7 @@ #include <ydb/core/node_whiteboard/node_whiteboard.h> #include <ydb/core/blobstorage/lwtrace_probes/blobstorage_probes.h> #include <ydb/core/control/immediate_control_board_wrapper.h> +#include <ydb/core/driver_lib/version/version.h> #include <ydb/library/schlab/schine/scheduler.h> #include <ydb/library/schlab/schine/job_kind.h> @@ -185,6 +186,9 @@ public: // Chunk locking TMap<TOwner, ui32> OwnerLocks; + // Serialized compatibility info record + std::optional<TString> SerializedCompatibilityInfo; + // Debug std::function<TString()> DebugInfoGenerator; @@ -197,7 +201,7 @@ public: bool CheckGuid(TString *outReason); // Called by actor bool CheckFormatComplete(); // Called by actor void ReadSysLog(const TActorId &pDiskActor); // Called by actor - void ProcessChunk0(const TEvReadLogResult &readLogResult); + bool ProcessChunk0(const TEvReadLogResult &readLogResult, TString& errorReason); void PrintChunksDebugInfo(); TRcBuf ProcessReadSysLogResult(ui64 &outWritePosition, ui64 &outLsn, const TEvReadLogResult &readLogResult); void ReadAndParseMainLog(const TActorId &pDiskActor); diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl_log.cpp b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl_log.cpp index 7e519ef2bed..abdb0e0db07 100644 --- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl_log.cpp +++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl_log.cpp @@ -170,29 +170,35 @@ void TPDisk::ReadSysLog(const TActorId &pDiskActor) { return; } -void TPDisk::ProcessChunk0(const NPDisk::TEvReadLogResult &readLogResult) { +bool TPDisk::ProcessChunk0(const NPDisk::TEvReadLogResult &readLogResult, TString& errorReason) { TGuard<TMutex> guard(StateMutex); ui64 writePosition = 0; ui64 lastLsn = 0; TRcBuf lastSysLogRecord = ProcessReadSysLogResult(writePosition, lastLsn, readLogResult); if (lastSysLogRecord.size() == 0) { - LOG_ERROR_S(*ActorSystem, NKikimrServices::BS_PDISK, "PDiskId# " << (ui32)PDiskId + errorReason = TStringBuilder() << "Error while parsing sys log at booting state: lastSysLogRecord is empty," << " lastSysLogRecord.Size()# 0 writePosition# " << writePosition << " lastLsn# " << lastLsn - << " readLogResult# " << readLogResult.ToString() + << " readLogResult# " << readLogResult.ToString(); + + LOG_ERROR_S(*ActorSystem, NKikimrServices::BS_PDISK, "PDiskId# " << (ui32)PDiskId + << " ErrorReason# " << errorReason << " Marker# BPD47"); - return; + + return false; } ui64 remainingSize = lastSysLogRecord.size(); if (remainingSize < sizeof(TSysLogRecord)) { - LOG_ERROR_S(*ActorSystem, NKikimrServices::BS_PDISK, "PDiskId# " << (ui32)PDiskId - << " remainingSize# " << remainingSize + errorReason = TStringBuilder() << "Error while parsing sys log at booting state: remainingSize# " << remainingSize << " < sizeof(TSysLogRecord)# " << sizeof(TSysLogRecord) << " writePosition# " << writePosition << " lastLsn# " << lastLsn - << " readLogResult# " << readLogResult.ToString() + << " readLogResult# " << readLogResult.ToString(); + + LOG_ERROR_S(*ActorSystem, NKikimrServices::BS_PDISK, "PDiskId# " << (ui32)PDiskId + << " ErrorReason# " << errorReason << " Marker# BPD48"); - return; + return false; } TSysLogRecord *sysLogRecord = (TSysLogRecord*)(lastSysLogRecord.data()); @@ -201,10 +207,13 @@ void TPDisk::ProcessChunk0(const NPDisk::TEvReadLogResult &readLogResult) { << sysLogRecord->ToString().c_str() << " Marker# BPD49"); } else { + errorReason = TStringBuilder() << "Error while parsing sys log at booting state: Incompatible SysLogRecord Version# " + << sysLogRecord->Version; + LOG_ERROR_S(*ActorSystem, NKikimrServices::BS_PDISK, "PDiskId# " << (ui32)PDiskId - << " Incompatible SysLogRecord Version# " << sysLogRecord->Version + << " ErrorReason# " << errorReason << " Marker# BPD50"); - return; + return false; } SysLogLsn = lastLsn + 1; @@ -224,7 +233,7 @@ void TPDisk::ProcessChunk0(const NPDisk::TEvReadLogResult &readLogResult) { } } SysLogRecord = *sysLogRecord; - SysLogRecord.Version = PDISK_SYS_LOG_RECORD_VERSION_6; + SysLogRecord.Version = PDISK_SYS_LOG_RECORD_VERSION_7; LOG_NOTICE(*ActorSystem, NKikimrServices::BS_PDISK, "PDiskId# %" PRIu32 " Read SysLogRecord# %s", (ui32)PDiskId, SysLogRecord.ToString().data()); @@ -248,14 +257,16 @@ void TPDisk::ProcessChunk0(const NPDisk::TEvReadLogResult &readLogResult) { remainingSize -= sizeof(TSysLogRecord); ui64 expectedSize = chunkCount * sizeof(TChunkInfo); if (remainingSize < expectedSize) { - LOG_ERROR_S(*ActorSystem, NKikimrServices::BS_PDISK, "PDiskId# " << (ui32)PDiskId - << " remainingSize# " << remainingSize + errorReason = TStringBuilder() << " remainingSize# " << remainingSize << " < expectedSize# " << expectedSize << " writePosition# " << writePosition << " lastLsn# " << lastLsn - << " readLogResult# " << readLogResult.ToString() + << " readLogResult# " << readLogResult.ToString(); + + LOG_ERROR_S(*ActorSystem, NKikimrServices::BS_PDISK, "PDiskId# " << (ui32)PDiskId + << " ErrorReason# " << errorReason << " Marker# BPD51"); - return; + return false; } // Checks are passed, so initialize position @@ -349,16 +360,68 @@ void TPDisk::ProcessChunk0(const NPDisk::TEvReadLogResult &readLogResult) { // Fill with default value to parse log form the start on old versions FirstLogChunkToParseCommits = SysLogRecord.LogHeadChunkIdx; + ui32 *firstChunkEnd = nullptr; if (sysLogRecord->Version >= PDISK_SYS_LOG_RECORD_VERSION_6) { Y_VERIFY(trimStateEnd); ui32 *firstChunk = reinterpret_cast<ui32*>(trimStateEnd); - ui64 minSize = (ui64)((char*)(firstChunk + 1) - (char*)sysLogRecord); + firstChunkEnd = firstChunk + 1; + ui64 minSize = (ui64)((char*)firstChunkEnd - (char*)sysLogRecord); Y_VERIFY_S(lastSysLogRecord.size() >= minSize, "SysLogRecord is too small, minSize# " << minSize << " size# " << lastSysLogRecord.size()); FirstLogChunkToParseCommits = ReadUnaligned<ui32>(firstChunk); } + char *compatibilityInfoEnd = nullptr; + if (sysLogRecord->Version >= PDISK_SYS_LOG_RECORD_VERSION_7) { + Y_VERIFY(firstChunkEnd); + ui32 *protoSizePtr = reinterpret_cast<ui32*>(firstChunkEnd); + ui32 *protoSizePtrEnd = protoSizePtr + 1; + + ui64 minSize = (ui64)((char*)protoSizePtrEnd - (char*)sysLogRecord); + Y_VERIFY_S(lastSysLogRecord.size() >= minSize, + "SysLogRecord is too small, minSize# " << minSize << " size# " << lastSysLogRecord.size()); + + ui32 protoSize = ReadUnaligned<ui32>(protoSizePtr); + Y_VERIFY(protoSize > 0); + + char *compatibilityInfo = reinterpret_cast<char*>(protoSizePtrEnd); + compatibilityInfoEnd = compatibilityInfo + protoSize; + auto storedCompatibilityInfo = NKikimrConfig::TStoredCompatibilityInfo(); + + minSize += protoSize; + Y_VERIFY_S(lastSysLogRecord.size() >= minSize, + "SysLogRecord is too small, minSize# " << minSize << " size# " << lastSysLogRecord.size()); + + bool success = storedCompatibilityInfo.ParseFromArray(compatibilityInfo, protoSize); + Y_VERIFY(success); + + bool isCompatible = CompatibilityInfo.CheckCompatibility(&storedCompatibilityInfo, + NKikimrConfig::TCompatibilityRule::PDisk, errorReason); + + if (!isCompatible) { + LOG_ERROR_S(*ActorSystem, NKikimrServices::BS_PDISK, "PDiskId# " << (ui32)PDiskId + << " Incompatible version, ErrorReason# " << errorReason); + return false; + } + } else if (sysLogRecord->Version != 0) { + // Sys log is not empty, but it doesn't contain compatibility info record + TString error; + bool isCompatible = CompatibilityInfo.CheckCompatibility(nullptr, + NKikimrConfig::TCompatibilityRule::PDisk, errorReason); + + if (!isCompatible) { + LOG_ERROR_S(*ActorSystem, NKikimrServices::BS_PDISK, "PDiskId# " << (ui32)PDiskId + << " Stored compatibility info is absent, current version is incompatible with the default stored version of PDisk," + << " ErrorReason# " << errorReason); + return false; + } + } + + // needed for further parsing + Y_UNUSED(compatibilityInfoEnd); + PrintChunksDebugInfo(); + return true; } void TPDisk::PrintChunksDebugInfo() { @@ -546,8 +609,16 @@ void TPDisk::WriteSysLogRestorePoint(TCompletionAction *action, TReqId reqId, NW FirstLogChunkToParseCommits = firstChunk.value_or(SysLogRecord.LogHeadChunkIdx); } + if (!SerializedCompatibilityInfo) { + SerializedCompatibilityInfo.emplace(TString()); + auto stored = CompatibilityInfo.MakeStored(NKikimrConfig::TCompatibilityRule::PDisk); + bool success = stored.SerializeToString(&*SerializedCompatibilityInfo); + Y_VERIFY(success); + } + ui32 compatibilityInfoSize = SerializedCompatibilityInfo->size(); + ui32 recordSize = sizeof(TSysLogRecord) + chunkOwnersSize + sizeof(TSysLogFirstNoncesToKeep) - + sizeof(ui64) + chunkIsTrimmedSize + sizeof(ui32); + + sizeof(ui64) + chunkIsTrimmedSize + sizeof(ui32) + sizeof(ui32) + compatibilityInfoSize; ui64 beginSectorIdx = SysLogger->SectorIdx; *Mon.BandwidthPSysLogPayload += recordSize; *Mon.BandwidthPSysLogRecordHeader += sizeof(TFirstLogPageHeader); @@ -559,6 +630,8 @@ void TPDisk::WriteSysLogRestorePoint(TCompletionAction *action, TReqId reqId, NW SysLogger->LogDataPart(&chunkIsTrimmedSize, sizeof(chunkIsTrimmedSize), reqId, traceId); SysLogger->LogDataPart(&chunkIsTrimmed[0], chunkIsTrimmedSize, reqId, traceId); SysLogger->LogDataPart(&FirstLogChunkToParseCommits, sizeof(FirstLogChunkToParseCommits), reqId, traceId); + SysLogger->LogDataPart(&compatibilityInfoSize, sizeof(compatibilityInfoSize), reqId, traceId); + SysLogger->LogDataPart(SerializedCompatibilityInfo->data(), compatibilityInfoSize, reqId, traceId); SysLogger->TerminateLog(reqId, traceId); SysLogger->Flush(reqId, traceId, action); @@ -1221,14 +1294,16 @@ void TPDisk::ProcessReadLogResult(const NPDisk::TEvReadLogResult &evReadLogResul switch (InitPhase) { case EInitPhase::ReadingSysLog: { - ProcessChunk0(evReadLogResult); + TString errorReason; + bool success = ProcessChunk0(evReadLogResult, errorReason); - if (InitialSysLogWritePosition == 0) { + if (InitialSysLogWritePosition == 0 || !success) { + ErrorStr = errorReason; *Mon.PDiskState = NKikimrBlobStorage::TPDiskState::InitialSysLogParseError; *Mon.PDiskBriefState = TPDiskMon::TPDisk::Error; *Mon.PDiskDetailedState = TPDiskMon::TPDisk::ErrorInitialSysLogParse; ActorSystem->Send(pDiskActor, new TEvLogInitResult(false, - "Error while parsing sys log at booting state")); + errorReason)); return; } // Parse the main log to obtain busy/free chunk lists diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut.cpp b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut.cpp index 3b51e620a8b..4d2f648eeaf 100644 --- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut.cpp +++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut.cpp @@ -5,6 +5,7 @@ #include "blobstorage_pdisk_ut_env.h" #include <ydb/core/blobstorage/crypto/default.h> +#include <ydb/core/driver_lib/version/ut/ut_helpers.h> #include <ydb/core/testlib/actors/test_runtime.h> #include <util/system/hp_timer.h> @@ -840,5 +841,81 @@ Y_UNIT_TEST_SUITE(TPDiskTest) { Y_UNIT_TEST(SmallDisk40) { SmallDisk(40); } + + using TCurrent = NKikimrConfig::TCurrentCompatibilityInfo; + void TestRestartWithDifferentVersion(TCurrent oldInfo, TCurrent newInfo, bool isCompatible) { + TCompatibilityInfoTest::Reset(&oldInfo); + + TActorTestContext testCtx({ false }); + TVDiskMock vdisk(&testCtx); + vdisk.InitFull(); + vdisk.SendEvLogSync(); + TCompatibilityInfoTest::Reset(&newInfo); + + testCtx.Send(new TEvBlobStorage::TEvRestartPDisk(testCtx.GetPDisk()->PDiskId, testCtx.MainKey, nullptr)); + testCtx.Recv<TEvBlobStorage::TEvRestartPDiskResult>(); + testCtx.Send(new NPDisk::TEvYardInit(vdisk.OwnerRound.fetch_add(1), vdisk.VDiskID, testCtx.TestCtx.PDiskGuid)); + const auto evInitRes = testCtx.Recv<NPDisk::TEvYardInitResult>(); + if (isCompatible) { + UNIT_ASSERT(evInitRes->Status == NKikimrProto::OK); + } else { + UNIT_ASSERT(evInitRes->Status != NKikimrProto::OK); + } + } + + Y_UNIT_TEST(YdbVersionOldCompatible) { + TestRestartWithDifferentVersion( + TCompatibilityInfo::TProtoConstructor::TCurrentCompatibilityInfo{ + .Build = "ydb", + .YdbVersion = TCompatibilityInfo::TProtoConstructor::TYdbVersion{ .Year = 23, .Major = 1, .Minor = 26, .Hotfix = 0 }, + }.ToPB(), + TCompatibilityInfo::TProtoConstructor::TCurrentCompatibilityInfo{ + .Build = "ydb", + .YdbVersion = TCompatibilityInfo::TProtoConstructor::TYdbVersion{ .Year = 23, .Major = 2, .Minor = 1, .Hotfix = 0 }, + }.ToPB(), + true + ); + } + + Y_UNIT_TEST(YdbVersionIncompatible) { + TestRestartWithDifferentVersion( + TCompatibilityInfo::TProtoConstructor::TCurrentCompatibilityInfo{ + .Build = "ydb", + .YdbVersion = TCompatibilityInfo::TProtoConstructor::TYdbVersion{ .Year = 23, .Major = 1, .Minor = 26, .Hotfix = 0 }, + }.ToPB(), + TCompatibilityInfo::TProtoConstructor::TCurrentCompatibilityInfo{ + .Build = "ydb", + .YdbVersion = TCompatibilityInfo::TProtoConstructor::TYdbVersion{ .Year = 23, .Major = 3, .Minor = 1, .Hotfix = 0 }, + }.ToPB(), + false + ); + } + + Y_UNIT_TEST(YdbVersionNewIncompatibleWithDefault) { + TestRestartWithDifferentVersion( + TCompatibilityInfo::TProtoConstructor::TCurrentCompatibilityInfo{ + .Build = "ydb", + .YdbVersion = TCompatibilityInfo::TProtoConstructor::TYdbVersion{ .Year = 24, .Major = 3, .Minor = 1, .Hotfix = 0 }, + }.ToPB(), + TCompatibilityInfo::TProtoConstructor::TCurrentCompatibilityInfo{ + .Build = "ydb", + .YdbVersion = TCompatibilityInfo::TProtoConstructor::TYdbVersion{ .Year = 24, .Major = 4, .Minor = 1, .Hotfix = 0 }, + }.ToPB(), + true + ); + } + + Y_UNIT_TEST(YdbVersionTrunk) { + TestRestartWithDifferentVersion( + TCompatibilityInfo::TProtoConstructor::TCurrentCompatibilityInfo{ + .Build = "trunk", + }.ToPB(), + TCompatibilityInfo::TProtoConstructor::TCurrentCompatibilityInfo{ + .Build = "trunk", + }.ToPB(), + true + ); + } + } } // namespace NKikimr diff --git a/ydb/core/blobstorage/pdisk/ya.make b/ydb/core/blobstorage/pdisk/ya.make index d352afc2689..1dcb13377b4 100644 --- a/ydb/core/blobstorage/pdisk/ya.make +++ b/ydb/core/blobstorage/pdisk/ya.make @@ -19,6 +19,7 @@ PEERDIR( ydb/core/blobstorage/groupinfo ydb/core/blobstorage/lwtrace_probes ydb/core/control + ydb/core/driver_lib/version ydb/core/protos ydb/core/util ydb/library/pdisk_io diff --git a/ydb/core/driver_lib/version/version.cpp b/ydb/core/driver_lib/version/version.cpp index 71dcb0cf007..5f83fef8f0f 100644 --- a/ydb/core/driver_lib/version/version.cpp +++ b/ydb/core/driver_lib/version/version.cpp @@ -36,22 +36,24 @@ TCompatibilityInfo::TCompatibilityInfo() { ///////////////////////////////////////////////////////// DefaultCompatibilityInfo = TDefaultCompatibilityInfo{}; #define EMPLACE_DEFAULT_COMPATIBILITY_INFO(componentName, build, year, major, minor, hotfix) \ - auto& defaultInfo = DefaultCompatibilityInfo[(ui32)EComponentId::componentName]; \ - defaultInfo.emplace(); \ - defaultInfo->CopyFrom( \ - TStoredConstructor{ \ - .Build = build, \ - .YdbVersion = TYdbVersionConstructor{ \ - .Year = year, \ - .Major = major, \ - .Minor = minor, \ - .Hotfix = hotfix, \ - }, \ - }.ToPB() \ - ); - -// EMPLACE_DEFAULT_COMPATIBILITY_INFO(PDisk, "ydb", ?, ?, ?, ?) TODO - EMPLACE_DEFAULT_COMPATIBILITY_INFO(VDisk, "ydb", 23, 2, 12, 0) + do { \ + auto& defaultInfo = DefaultCompatibilityInfo[(ui32)EComponentId::componentName]; \ + defaultInfo.emplace(); \ + defaultInfo->CopyFrom( \ + TStoredConstructor{ \ + .Build = build, \ + .YdbVersion = TYdbVersionConstructor{ \ + .Year = year, \ + .Major = major, \ + .Minor = minor, \ + .Hotfix = hotfix, \ + }, \ + }.ToPB() \ + ); \ + } while (false) + + EMPLACE_DEFAULT_COMPATIBILITY_INFO(PDisk, "ydb", 23, 2, 12, 0); + EMPLACE_DEFAULT_COMPATIBILITY_INFO(VDisk, "ydb", 23, 2, 12, 0); // EMPLACE_DEFAULT_COMPATIBILITY_INFO(BlobStorageController, "ydb", ?, ?, ?, ?) TODO #undef EMPLACE_DEFAULT_COMPATIBILITY_INFO |