diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl.cpp b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl.cpp index 9fecb8e3d36b..8e54b24fa7ef 100644 --- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl.cpp +++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_impl.cpp @@ -2292,6 +2292,23 @@ void TPDisk::Slay(TSlay &evSlay) { TVDiskID vDiskId = evSlay.VDiskId; vDiskId.GroupGeneration = -1; auto it = VDiskOwners.find(vDiskId); + + for (auto& pendingInit : PendingYardInits) { + if (vDiskId == pendingInit->VDiskIdWOGeneration()) { + TStringStream str; + str << PCtx->PDiskLogPrefix << "Can't slay VDiskId# " << evSlay.VDiskId + << " as it has pending YardInit Marker# BPD48"; + P_LOG(PRI_ERROR, BPD48, str.Str()); + THolder result(new NPDisk::TEvSlayResult( + NKikimrProto::NOTREADY, + GetStatusFlags(evSlay.Owner, evSlay.OwnerGroupType), evSlay.VDiskId, evSlay.SlayOwnerRound, + evSlay.PDiskId, evSlay.VSlotId, str.Str())); + PCtx->ActorSystem->Send(evSlay.Sender, result.Release()); + Mon.YardSlay.CountResponse(); + return; + } + } + if (it == VDiskOwners.end()) { TStringStream str; str << PCtx->PDiskLogPrefix << "Can't slay VDiskId# " << evSlay.VDiskId; diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut.cpp b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut.cpp index 39be6c85adaf..d9609749ee3c 100644 --- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut.cpp +++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut.cpp @@ -614,6 +614,33 @@ Y_UNIT_TEST_SUITE(TPDiskTest) { vdisk.SendEvLogSync(); } + Y_UNIT_TEST(PDiskOwnerSlayRace) { + TActorTestContext testCtx{{}}; + testCtx.GetPDisk(); // inits pdisk + TVDiskMock vdisk(&testCtx); + + testCtx.TestResponse( + new NPDisk::TEvYardControl(NPDisk::TEvYardControl::ActionPause, nullptr), + NKikimrProto::OK); + + auto* yardInit = new NPDisk::TEvYardInit(TVDiskMock::OwnerRound.fetch_add(1), vdisk.VDiskID, testCtx.TestCtx.PDiskGuid, testCtx.Sender); + testCtx.Send(yardInit); + auto* slay = new NPDisk::TEvSlay(vdisk.VDiskID, TVDiskMock::OwnerRound.load(), 0, 0); + testCtx.Send(slay); + + testCtx.TestResponse( + new NPDisk::TEvYardControl(NPDisk::TEvYardControl::ActionResume, nullptr), + NKikimrProto::OK); + + auto slayResult = testCtx.Recv(); + + UNIT_ASSERT_VALUES_EQUAL(NKikimrProto::NOTREADY, slayResult->Status); + + testCtx.TestResponse( + new NPDisk::TEvSlay(vdisk.VDiskID, TVDiskMock::OwnerRound.load(), 0, 0), + NKikimrProto::OK); + } + Y_UNIT_TEST(PDiskRestartManyLogWrites) { TActorTestContext testCtx{{}};