diff options
author | robdrynkin <robdrynkin@yandex-team.com> | 2023-10-06 18:25:46 +0300 |
---|---|---|
committer | robdrynkin <robdrynkin@yandex-team.com> | 2023-10-06 21:01:29 +0300 |
commit | a8f808af42d92f92f79a0473f9c069ce8b2c178b (patch) | |
tree | a8615848ef243774aec1be855d8770126c5a792b | |
parent | b70412b8025dd0f7e40ff3484da3d49fbf5faf98 (diff) | |
download | ydb-a8f808af42d92f92f79a0473f9c069ce8b2c178b.tar.gz |
KIKIMR-19469: Restart vdisk button
26 files changed, 656 insertions, 13 deletions
diff --git a/.mapping.json b/.mapping.json index 7d001aaae8..e6f2333474 100644 --- a/.mapping.json +++ b/.mapping.json @@ -3449,6 +3449,11 @@ "ydb/core/blobstorage/ut_blobstorage/ut_scrub/CMakeLists.linux-x86_64.txt":"", "ydb/core/blobstorage/ut_blobstorage/ut_scrub/CMakeLists.txt":"", "ydb/core/blobstorage/ut_blobstorage/ut_scrub/CMakeLists.windows-x86_64.txt":"", + "ydb/core/blobstorage/ut_blobstorage/ut_vdisk_restart/CMakeLists.darwin-x86_64.txt":"", + "ydb/core/blobstorage/ut_blobstorage/ut_vdisk_restart/CMakeLists.linux-aarch64.txt":"", + "ydb/core/blobstorage/ut_blobstorage/ut_vdisk_restart/CMakeLists.linux-x86_64.txt":"", + "ydb/core/blobstorage/ut_blobstorage/ut_vdisk_restart/CMakeLists.txt":"", + "ydb/core/blobstorage/ut_blobstorage/ut_vdisk_restart/CMakeLists.windows-x86_64.txt":"", "ydb/core/blobstorage/ut_group/CMakeLists.darwin-x86_64.txt":"", "ydb/core/blobstorage/ut_group/CMakeLists.linux-aarch64.txt":"", "ydb/core/blobstorage/ut_group/CMakeLists.linux-x86_64.txt":"", diff --git a/ydb/core/base/blobstorage.h b/ydb/core/base/blobstorage.h index c3c1f02abb..f92e7441a5 100644 --- a/ydb/core/base/blobstorage.h +++ b/ydb/core/base/blobstorage.h @@ -851,6 +851,7 @@ struct TEvBlobStorage { // node controller internal messages EvRegisterNodeRetry = EvPut + 14 * 512, EvAskRestartPDisk, + EvAskRestartVDisk, EvRestartPDisk, EvRestartPDiskResult, EvNodeWardenQueryGroupInfo, @@ -2354,6 +2355,7 @@ struct TEvBlobStorage { struct TEvBunchOfEvents; struct TEvAskRestartPDisk; + struct TEvAskRestartVDisk; struct TEvRestartPDisk; struct TEvRestartPDiskResult; }; diff --git a/ydb/core/blobstorage/base/blobstorage_events.h b/ydb/core/blobstorage/base/blobstorage_events.h index 41c7cd087b..dedd8437e3 100644 --- a/ydb/core/blobstorage/base/blobstorage_events.h +++ b/ydb/core/blobstorage/base/blobstorage_events.h @@ -431,6 +431,19 @@ namespace NKikimr { {} }; + struct TEvBlobStorage::TEvAskRestartVDisk : TEventLocal<TEvAskRestartVDisk, EvAskRestartVDisk> { + const ui32 PDiskId; + const TVDiskID VDiskId; + + TEvAskRestartVDisk( + const ui32 pDiskId, + const TVDiskID& vDiskId + ) + : PDiskId(pDiskId) + , VDiskId(vDiskId) + {} + }; + struct TEvBlobStorage::TEvRestartPDisk : TEventLocal<TEvRestartPDisk, EvRestartPDisk> { const ui32 PDiskId; const NPDisk::TMainKey MainKey; diff --git a/ydb/core/blobstorage/nodewarden/blobstorage_node_warden_ut.cpp b/ydb/core/blobstorage/nodewarden/blobstorage_node_warden_ut.cpp index 9ae7f93854..2e72ab6c0c 100644 --- a/ydb/core/blobstorage/nodewarden/blobstorage_node_warden_ut.cpp +++ b/ydb/core/blobstorage/nodewarden/blobstorage_node_warden_ut.cpp @@ -807,7 +807,7 @@ Y_UNIT_TEST_SUITE(TBlobStorageWardenTest) { Setup(runtime, "", nullptr); auto edge = runtime.AllocateEdgeActor(0); TActorId nodeWarden = MakeBlobStorageNodeWardenID(edge.NodeId()); - THttpRequest HttpRequest; + THttpRequestMock HttpRequest; NMonitoring::TMonService2HttpRequest monService2HttpRequest(nullptr, &HttpRequest, nullptr, nullptr, path, nullptr); runtime.Send(new IEventHandle(nodeWarden, edge, new NMon::TEvHttpInfo(monService2HttpRequest)), 0); diff --git a/ydb/core/blobstorage/nodewarden/node_warden_impl.h b/ydb/core/blobstorage/nodewarden/node_warden_impl.h index 7c23f262ca..90dd50c512 100644 --- a/ydb/core/blobstorage/nodewarden/node_warden_impl.h +++ b/ydb/core/blobstorage/nodewarden/node_warden_impl.h @@ -464,6 +464,7 @@ namespace NKikimr::NStorage { void Handle(TEvBlobStorage::TEvDropDonor::TPtr ev); void Handle(TEvBlobStorage::TEvAskRestartPDisk::TPtr ev); + void Handle(TEvBlobStorage::TEvAskRestartVDisk::TPtr ev); void Handle(TEvBlobStorage::TEvRestartPDiskResult::TPtr ev); void FillInVDiskStatus(google::protobuf::RepeatedPtrField<NKikimrBlobStorage::TVDiskStatus> *pb, bool initial); @@ -535,6 +536,7 @@ namespace NKikimr::NStorage { hFunc(TEvStatusUpdate, Handle); hFunc(TEvBlobStorage::TEvDropDonor, Handle); hFunc(TEvBlobStorage::TEvAskRestartPDisk, Handle); + hFunc(TEvBlobStorage::TEvAskRestartVDisk, Handle); hFunc(TEvBlobStorage::TEvRestartPDiskResult, Handle); hFunc(TEvGroupStatReport, Handle); diff --git a/ydb/core/blobstorage/nodewarden/node_warden_vdisk.cpp b/ydb/core/blobstorage/nodewarden/node_warden_vdisk.cpp index 56093a131c..aec69ad075 100644 --- a/ydb/core/blobstorage/nodewarden/node_warden_vdisk.cpp +++ b/ydb/core/blobstorage/nodewarden/node_warden_vdisk.cpp @@ -6,6 +6,8 @@ namespace NKikimr::NStorage { + constexpr TDuration PDISK_CONFIDENCE_DELAY = TDuration::Seconds(15); + void TNodeWarden::DestroyLocalVDisk(TVDiskRecord& vdisk) { STLOG(PRI_INFO, BS_NODE, NW35, "DestroyLocalVDisk", (VDiskId, vdisk.GetVDiskId()), (VSlotId, vdisk.GetVSlotId())); Y_VERIFY(!vdisk.RuntimeData); @@ -267,7 +269,7 @@ namespace NKikimr::NStorage { StartLocalVDiskActor(record, TDuration::Zero()); } else if (record.RuntimeData->DonorMode < record.Config.HasDonorMode() || record.RuntimeData->ReadOnly != record.Config.GetReadOnly()) { PoisonLocalVDisk(record); - StartLocalVDiskActor(record, TDuration::Seconds(15) /* PDisk confidence delay */); + StartLocalVDiskActor(record, PDISK_CONFIDENCE_DELAY); } } @@ -285,6 +287,21 @@ namespace NKikimr::NStorage { } } + void TNodeWarden::Handle(TEvBlobStorage::TEvAskRestartVDisk::TPtr ev) { + const auto& [pDiskId, vDiskId] = *ev->Get(); + const auto nodeId = SelfId().NodeId(); // Skeleton and NodeWarden are on the same node + TVSlotId slotId(nodeId, pDiskId, 0); + + for (auto it = LocalVDisks.lower_bound(slotId); it != LocalVDisks.end() && it->first.NodeId == nodeId && it->first.PDiskId == pDiskId; ++it) { + auto& record = it->second; + if (record.GetVDiskId() == vDiskId) { + PoisonLocalVDisk(record); + StartLocalVDiskActor(record, PDISK_CONFIDENCE_DELAY); + break; + } + } + } + void TNodeWarden::Handle(TEvBlobStorage::TEvDropDonor::TPtr ev) { auto *msg = ev->Get(); const TVSlotId vslotId(msg->NodeId, msg->PDiskId, msg->VSlotId); diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_actions.h b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_actions.h index 52cd8bef13..92789f5bca 100644 --- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_actions.h +++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_actions.h @@ -1301,7 +1301,7 @@ public: }; class TTestHttpInfo : public TBaseTest { - THttpRequest HttpRequest; + THttpRequestMock HttpRequest; NMonitoring::TMonService2HttpRequest MonService2HttpRequest; void TestFSM(const TActorContext &ctx); @@ -1313,7 +1313,7 @@ public: }; class TTestHttpInfoFileDoesntExist : public TBaseTest { - THttpRequest HttpRequest; + THttpRequestMock HttpRequest; NMonitoring::TMonService2HttpRequest MonService2HttpRequest; void TestFSM(const TActorContext &ctx); @@ -1326,7 +1326,7 @@ public: class TTestBootingState : public TBaseTest { const ui32 HttpRequestsCount = 1000; - THttpRequest HttpRequest; + THttpRequestMock HttpRequest; NMonitoring::TMonService2HttpRequest MonService2HttpRequest; bool EvYardAnswered = false; ui32 AnsweredRequests = 0; diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_http_request.h b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_http_request.h index 7f4a18c762..bd597495cb 100644 --- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_http_request.h +++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_http_request.h @@ -3,18 +3,19 @@ namespace NKikimr { -struct THttpRequest : NMonitoring::IHttpRequest { +struct THttpRequestMock : NMonitoring::IHttpRequest { TCgiParameters CgiParameters; THttpHeaders HttpHeaders; + TString Path; - ~THttpRequest() {} + ~THttpRequestMock() {} const char* GetURI() const override { return ""; } const char* GetPath() const override { - return ""; + return Path.c_str(); } const TCgiParameters& GetParams() const override { diff --git a/ydb/core/blobstorage/pdisk/mock/pdisk_mock.cpp b/ydb/core/blobstorage/pdisk/mock/pdisk_mock.cpp index d12674684e..8f5aa08a4b 100644 --- a/ydb/core/blobstorage/pdisk/mock/pdisk_mock.cpp +++ b/ydb/core/blobstorage/pdisk/mock/pdisk_mock.cpp @@ -45,6 +45,7 @@ struct TPDiskMockState::TImpl { TIntervalSet<ui64> Corrupted; NPDisk::TStatusFlags StatusFlags; THashSet<TVDiskID> ReadOnlyVDisks; + TString StateErrorReason; TImpl(ui32 nodeId, ui32 pdiskId, ui64 pdiskGuid, ui64 size, ui32 chunkSize) : NodeId(nodeId) @@ -221,6 +222,15 @@ struct TPDiskMockState::TImpl { return ChunkSize; } + TMaybe<TOwner> GetOwner(const TVDiskID& vDiskId) const { + for (auto& [ownerId, owner] : Owners) { + if (owner.VDiskId.GroupID == vDiskId.GroupID && owner.VDiskId.VDisk == vDiskId.VDisk) { + return owner; + } + } + return Nothing(); + } + TIntervalSet<i64> GetWrittenAreas(ui32 chunkIdx) const { TIntervalSet<i64> res; for (auto& [ownerId, owner] : Owners) { @@ -308,12 +318,23 @@ void TPDiskMockState::SetReadOnly(const TVDiskID& vDiskId, bool isReadOnly) { Impl->SetReadOnly(vDiskId, isReadOnly); } +TString& TPDiskMockState::GetStateErrorReason() { + return Impl->StateErrorReason; +} + TPDiskMockState::TPtr TPDiskMockState::Snapshot() { auto res = MakeIntrusive<TPDiskMockState>(std::make_unique<TImpl>(*Impl)); res->Impl->AdjustRefs(); return res; } +TMaybe<NPDisk::TOwnerRound> TPDiskMockState::GetOwnerRound(const TVDiskID& vDiskId) const { + if (auto owner = Impl->GetOwner(vDiskId)) { + return owner->OwnerRound; + } + return Nothing(); +} + class TPDiskMockActor : public TActorBootstrapped<TPDiskMockActor> { enum { EvResume = EventSpaceBegin(TEvents::ES_PRIVATE), @@ -339,7 +360,7 @@ public: } void Bootstrap() { - Become(&TThis::StateFunc); + Become(&TThis::StateNormal); ReportMetrics(); } @@ -814,7 +835,89 @@ public: return Impl.StatusFlags; } - STRICT_STFUNC(StateFunc, + void ErrorHandle(NPDisk::TEvYardInit::TPtr &ev) { + Send(ev->Sender, new NPDisk::TEvYardInitResult(NKikimrProto::CORRUPTED, State->GetStateErrorReason())); + } + + void ErrorHandle(NPDisk::TEvCheckSpace::TPtr &ev) { + Send(ev->Sender, new NPDisk::TEvCheckSpaceResult(NKikimrProto::CORRUPTED, 0, 0, 0, 0, 0, State->GetStateErrorReason())); + } + + void ErrorHandle(NPDisk::TEvLog::TPtr &ev) { + const NPDisk::TEvLog &evLog = *ev->Get(); + THolder<NPDisk::TEvLogResult> result(new NPDisk::TEvLogResult(NKikimrProto::CORRUPTED, 0, State->GetStateErrorReason())); + result->Results.push_back(NPDisk::TEvLogResult::TRecord(evLog.Lsn, evLog.Cookie)); + Send(ev->Sender, result.Release()); + } + + void ErrorHandle(NPDisk::TEvMultiLog::TPtr &ev) { + const NPDisk::TEvMultiLog &evMultiLog = *ev->Get(); + THolder<NPDisk::TEvLogResult> result(new NPDisk::TEvLogResult(NKikimrProto::CORRUPTED, 0, State->GetStateErrorReason())); + for (auto &log : evMultiLog.Logs) { + result->Results.push_back(NPDisk::TEvLogResult::TRecord(log->Lsn, log->Cookie)); + } + Send(ev->Sender, result.Release()); + } + + void ErrorHandle(NPDisk::TEvReadLog::TPtr &ev) { + const NPDisk::TEvReadLog &evReadLog = *ev->Get(); + THolder<NPDisk::TEvReadLogResult> result(new NPDisk::TEvReadLogResult( + NKikimrProto::CORRUPTED, evReadLog.Position, evReadLog.Position, true, 0, State->GetStateErrorReason(), evReadLog.Owner)); + Send(ev->Sender, result.Release()); + } + + void ErrorHandle(NPDisk::TEvChunkWrite::TPtr &ev) { + const NPDisk::TEvChunkWrite &evChunkWrite = *ev->Get(); + Send(ev->Sender, new NPDisk::TEvChunkWriteResult(NKikimrProto::CORRUPTED, + evChunkWrite.ChunkIdx, evChunkWrite.Cookie, 0, State->GetStateErrorReason())); + } + + void ErrorHandle(NPDisk::TEvChunkRead::TPtr &ev) { + const NPDisk::TEvChunkRead &evChunkRead = *ev->Get(); + THolder<NPDisk::TEvChunkReadResult> result = MakeHolder<NPDisk::TEvChunkReadResult>(NKikimrProto::CORRUPTED, + evChunkRead.ChunkIdx, evChunkRead.Offset, evChunkRead.Cookie, 0, "PDisk is in error state"); + Send(ev->Sender, result.Release()); + } + + void ErrorHandle(NPDisk::TEvHarakiri::TPtr &ev) { + Send(ev->Sender, new NPDisk::TEvHarakiriResult(NKikimrProto::CORRUPTED, 0, State->GetStateErrorReason())); + } + + void ErrorHandle(NPDisk::TEvSlay::TPtr &ev) { + const NPDisk::TEvSlay &evSlay = *ev->Get(); + Send(ev->Sender, new NPDisk::TEvSlayResult(NKikimrProto::CORRUPTED, 0, + evSlay.VDiskId, evSlay.SlayOwnerRound, evSlay.PDiskId, evSlay.VSlotId, State->GetStateErrorReason())); + } + + void ErrorHandle(NPDisk::TEvChunkReserve::TPtr &ev) { + Send(ev->Sender, new NPDisk::TEvChunkReserveResult(NKikimrProto::CORRUPTED, 0, State->GetStateErrorReason())); + } + + void ErrorHandle(NPDisk::TEvChunkForget::TPtr &ev) { + Send(ev->Sender, new NPDisk::TEvChunkForgetResult(NKikimrProto::CORRUPTED, 0, State->GetStateErrorReason())); + } + + void ErrorHandle(NPDisk::TEvYardControl::TPtr &ev) { + const NPDisk::TEvYardControl &evControl = *ev->Get(); + Send(ev->Sender, new NPDisk::TEvYardControlResult(NKikimrProto::CORRUPTED, evControl.Cookie, State->GetStateErrorReason())); + } + + void ErrorHandle(NPDisk::TEvAskForCutLog::TPtr &ev) { + // Just ignore the event, can't send cut log in this state. + Y_UNUSED(ev); + } + + void HandleMoveToErrorState() { + Impl.StateErrorReason = "Some error reason"; + Become(&TThis::StateError); + } + + void HandleMoveToNormalState() { + Impl.StateErrorReason = ""; + Become(&TThis::StateNormal); + } + + STRICT_STFUNC(StateNormal, hFunc(NPDisk::TEvYardInit, Handle); hFunc(NPDisk::TEvLog, Handle); hFunc(NPDisk::TEvChunkForget, Handle); @@ -829,6 +932,25 @@ public: hFunc(NPDisk::TEvHarakiri, Handle); hFunc(NPDisk::TEvConfigureScheduler, Handle); cFunc(TEvents::TSystem::Wakeup, ReportMetrics); + + cFunc(EvBecomeError, HandleMoveToErrorState); + ) + + STRICT_STFUNC(StateError, + hFunc(NPDisk::TEvYardInit, ErrorHandle); + hFunc(NPDisk::TEvCheckSpace, ErrorHandle); + hFunc(NPDisk::TEvLog, ErrorHandle); + hFunc(NPDisk::TEvMultiLog, ErrorHandle); + hFunc(NPDisk::TEvReadLog, ErrorHandle); + hFunc(NPDisk::TEvChunkWrite, ErrorHandle); + hFunc(NPDisk::TEvChunkRead, ErrorHandle); + hFunc(NPDisk::TEvHarakiri, ErrorHandle); + hFunc(NPDisk::TEvSlay, ErrorHandle); + hFunc(NPDisk::TEvChunkReserve, ErrorHandle); + hFunc(NPDisk::TEvChunkForget, ErrorHandle); + + cFunc(TEvents::TSystem::Wakeup, ReportMetrics); + cFunc(EvBecomeNormal, HandleMoveToNormalState); ) }; diff --git a/ydb/core/blobstorage/pdisk/mock/pdisk_mock.h b/ydb/core/blobstorage/pdisk/mock/pdisk_mock.h index 62a4b863de..1b5c2f9a3b 100644 --- a/ydb/core/blobstorage/pdisk/mock/pdisk_mock.h +++ b/ydb/core/blobstorage/pdisk/mock/pdisk_mock.h @@ -7,6 +7,11 @@ namespace NKikimr { + enum EPDiskMockEvents { + EvBecomeError = TEvBlobStorage::EvEnd + 1, + EvBecomeNormal + }; + class TPDiskMockState : public TThrRefBase { struct TImpl; std::unique_ptr<TImpl> Impl; @@ -22,11 +27,13 @@ namespace NKikimr { void SetCorruptedArea(ui32 chunkIdx, ui32 begin, ui32 end, bool enabled); std::set<ui32> GetChunks(); + TMaybe<NPDisk::TOwnerRound> GetOwnerRound(const TVDiskID& vDiskId) const; ui32 GetChunkSize() const; TIntervalSet<i64> GetWrittenAreas(ui32 chunkIdx) const; void TrimQuery(); void SetStatusFlags(NKikimrBlobStorage::TPDiskSpaceColor::E spaceColor); void SetStatusFlags(NPDisk::TStatusFlags flags); + TString& GetStateErrorReason(); TPtr Snapshot(); // create a copy of PDisk whole state diff --git a/ydb/core/blobstorage/ut_blobstorage/CMakeLists.darwin-x86_64.txt b/ydb/core/blobstorage/ut_blobstorage/CMakeLists.darwin-x86_64.txt index 5f94d3258c..f9b38bd4a3 100644 --- a/ydb/core/blobstorage/ut_blobstorage/CMakeLists.darwin-x86_64.txt +++ b/ydb/core/blobstorage/ut_blobstorage/CMakeLists.darwin-x86_64.txt @@ -15,6 +15,7 @@ add_subdirectory(ut_osiris) add_subdirectory(ut_read_only_vdisk) add_subdirectory(ut_replication) add_subdirectory(ut_scrub) +add_subdirectory(ut_vdisk_restart) add_executable(ydb-core-blobstorage-ut_blobstorage) target_link_libraries(ydb-core-blobstorage-ut_blobstorage PUBLIC diff --git a/ydb/core/blobstorage/ut_blobstorage/CMakeLists.linux-aarch64.txt b/ydb/core/blobstorage/ut_blobstorage/CMakeLists.linux-aarch64.txt index b369f934b0..dfb076e3fb 100644 --- a/ydb/core/blobstorage/ut_blobstorage/CMakeLists.linux-aarch64.txt +++ b/ydb/core/blobstorage/ut_blobstorage/CMakeLists.linux-aarch64.txt @@ -15,6 +15,7 @@ add_subdirectory(ut_osiris) add_subdirectory(ut_read_only_vdisk) add_subdirectory(ut_replication) add_subdirectory(ut_scrub) +add_subdirectory(ut_vdisk_restart) add_executable(ydb-core-blobstorage-ut_blobstorage) target_link_libraries(ydb-core-blobstorage-ut_blobstorage PUBLIC diff --git a/ydb/core/blobstorage/ut_blobstorage/CMakeLists.linux-x86_64.txt b/ydb/core/blobstorage/ut_blobstorage/CMakeLists.linux-x86_64.txt index 02389cc29f..831e212021 100644 --- a/ydb/core/blobstorage/ut_blobstorage/CMakeLists.linux-x86_64.txt +++ b/ydb/core/blobstorage/ut_blobstorage/CMakeLists.linux-x86_64.txt @@ -15,6 +15,7 @@ add_subdirectory(ut_osiris) add_subdirectory(ut_read_only_vdisk) add_subdirectory(ut_replication) add_subdirectory(ut_scrub) +add_subdirectory(ut_vdisk_restart) add_executable(ydb-core-blobstorage-ut_blobstorage) target_link_libraries(ydb-core-blobstorage-ut_blobstorage PUBLIC diff --git a/ydb/core/blobstorage/ut_blobstorage/CMakeLists.windows-x86_64.txt b/ydb/core/blobstorage/ut_blobstorage/CMakeLists.windows-x86_64.txt index 984f0184b1..6850778337 100644 --- a/ydb/core/blobstorage/ut_blobstorage/CMakeLists.windows-x86_64.txt +++ b/ydb/core/blobstorage/ut_blobstorage/CMakeLists.windows-x86_64.txt @@ -15,6 +15,7 @@ add_subdirectory(ut_osiris) add_subdirectory(ut_read_only_vdisk) add_subdirectory(ut_replication) add_subdirectory(ut_scrub) +add_subdirectory(ut_vdisk_restart) add_executable(ydb-core-blobstorage-ut_blobstorage) target_link_libraries(ydb-core-blobstorage-ut_blobstorage PUBLIC diff --git a/ydb/core/blobstorage/ut_blobstorage/lib/env.h b/ydb/core/blobstorage/ut_blobstorage/lib/env.h index 493aa7cb01..f71efb94c5 100644 --- a/ydb/core/blobstorage/ut_blobstorage/lib/env.h +++ b/ydb/core/blobstorage/ut_blobstorage/lib/env.h @@ -19,6 +19,7 @@ struct TEnvironmentSetup { const ui32 NumGroups = 1; TIntrusivePtr<NFake::TProxyDS> Group0 = MakeIntrusive<NFake::TProxyDS>(); std::map<std::pair<ui32, ui32>, TIntrusivePtr<TPDiskMockState>> PDiskMockStates; + TVector<TActorId> PDiskActors; std::set<TActorId> CommencedReplication; std::unordered_map<ui32, TString> Cache; @@ -58,6 +59,7 @@ struct TEnvironmentSetup { const TActorId& actorId = ctx.Register(CreatePDiskMockActor(state), TMailboxType::HTSwap, poolId); const TActorId& serviceId = MakeBlobStoragePDiskID(nodeId, pdiskId); ctx.ExecutorThread.ActorSystem->RegisterLocalService(serviceId, actorId); + Env.PDiskActors.push_back(actorId); } }; diff --git a/ydb/core/blobstorage/ut_blobstorage/ut_vdisk_restart/CMakeLists.darwin-x86_64.txt b/ydb/core/blobstorage/ut_blobstorage/ut_vdisk_restart/CMakeLists.darwin-x86_64.txt new file mode 100644 index 0000000000..379dd6aafc --- /dev/null +++ b/ydb/core/blobstorage/ut_blobstorage/ut_vdisk_restart/CMakeLists.darwin-x86_64.txt @@ -0,0 +1,74 @@ + +# This file was generated by the build system used internally in the Yandex monorepo. +# Only simple modifications are allowed (adding source-files to targets, adding simple properties +# like target_include_directories). These modifications will be ported to original +# ya.make files by maintainers. Any complex modifications which can't be ported back to the +# original buildsystem will not be accepted. + + + +add_executable(blobstorage-ut_blobstorage-ut_vdisk_restart) +target_include_directories(blobstorage-ut_blobstorage-ut_vdisk_restart PRIVATE + ${CMAKE_SOURCE_DIR}/ydb/core/blobstorage/ut_blobstorage +) +target_link_libraries(blobstorage-ut_blobstorage-ut_vdisk_restart PUBLIC + contrib-libs-cxxsupp + yutil + library-cpp-cpuid_check + cpp-testing-unittest_main + blobstorage-ut_blobstorage-lib +) +target_link_options(blobstorage-ut_blobstorage-ut_vdisk_restart PRIVATE + -Wl,-platform_version,macos,11.0,11.0 + -fPIC + -fPIC + -framework + CoreFoundation +) +target_sources(blobstorage-ut_blobstorage-ut_vdisk_restart PRIVATE + ${CMAKE_SOURCE_DIR}/ydb/core/blobstorage/ut_blobstorage/vdisk_restart.cpp +) +set_property( + TARGET + blobstorage-ut_blobstorage-ut_vdisk_restart + PROPERTY + SPLIT_FACTOR + 10 +) +add_yunittest( + NAME + blobstorage-ut_blobstorage-ut_vdisk_restart + TEST_TARGET + blobstorage-ut_blobstorage-ut_vdisk_restart + TEST_ARG + --print-before-suite + --print-before-test + --fork-tests + --print-times + --show-fails +) +set_yunittest_property( + TEST + blobstorage-ut_blobstorage-ut_vdisk_restart + PROPERTY + LABELS + MEDIUM +) +set_yunittest_property( + TEST + blobstorage-ut_blobstorage-ut_vdisk_restart + PROPERTY + PROCESSORS + 1 +) +set_yunittest_property( + TEST + blobstorage-ut_blobstorage-ut_vdisk_restart + PROPERTY + TIMEOUT + 600 +) +target_allocator(blobstorage-ut_blobstorage-ut_vdisk_restart + system_allocator +) +vcs_info(blobstorage-ut_blobstorage-ut_vdisk_restart) diff --git a/ydb/core/blobstorage/ut_blobstorage/ut_vdisk_restart/CMakeLists.linux-aarch64.txt b/ydb/core/blobstorage/ut_blobstorage/ut_vdisk_restart/CMakeLists.linux-aarch64.txt new file mode 100644 index 0000000000..1026c68db9 --- /dev/null +++ b/ydb/core/blobstorage/ut_blobstorage/ut_vdisk_restart/CMakeLists.linux-aarch64.txt @@ -0,0 +1,77 @@ + +# This file was generated by the build system used internally in the Yandex monorepo. +# Only simple modifications are allowed (adding source-files to targets, adding simple properties +# like target_include_directories). These modifications will be ported to original +# ya.make files by maintainers. Any complex modifications which can't be ported back to the +# original buildsystem will not be accepted. + + + +add_executable(blobstorage-ut_blobstorage-ut_vdisk_restart) +target_include_directories(blobstorage-ut_blobstorage-ut_vdisk_restart PRIVATE + ${CMAKE_SOURCE_DIR}/ydb/core/blobstorage/ut_blobstorage +) +target_link_libraries(blobstorage-ut_blobstorage-ut_vdisk_restart PUBLIC + contrib-libs-linux-headers + contrib-libs-cxxsupp + yutil + cpp-testing-unittest_main + blobstorage-ut_blobstorage-lib +) +target_link_options(blobstorage-ut_blobstorage-ut_vdisk_restart PRIVATE + -ldl + -lrt + -Wl,--no-as-needed + -fPIC + -fPIC + -lpthread + -lrt + -ldl +) +target_sources(blobstorage-ut_blobstorage-ut_vdisk_restart PRIVATE + ${CMAKE_SOURCE_DIR}/ydb/core/blobstorage/ut_blobstorage/vdisk_restart.cpp +) +set_property( + TARGET + blobstorage-ut_blobstorage-ut_vdisk_restart + PROPERTY + SPLIT_FACTOR + 10 +) +add_yunittest( + NAME + blobstorage-ut_blobstorage-ut_vdisk_restart + TEST_TARGET + blobstorage-ut_blobstorage-ut_vdisk_restart + TEST_ARG + --print-before-suite + --print-before-test + --fork-tests + --print-times + --show-fails +) +set_yunittest_property( + TEST + blobstorage-ut_blobstorage-ut_vdisk_restart + PROPERTY + LABELS + MEDIUM +) +set_yunittest_property( + TEST + blobstorage-ut_blobstorage-ut_vdisk_restart + PROPERTY + PROCESSORS + 1 +) +set_yunittest_property( + TEST + blobstorage-ut_blobstorage-ut_vdisk_restart + PROPERTY + TIMEOUT + 600 +) +target_allocator(blobstorage-ut_blobstorage-ut_vdisk_restart + cpp-malloc-jemalloc +) +vcs_info(blobstorage-ut_blobstorage-ut_vdisk_restart) diff --git a/ydb/core/blobstorage/ut_blobstorage/ut_vdisk_restart/CMakeLists.linux-x86_64.txt b/ydb/core/blobstorage/ut_blobstorage/ut_vdisk_restart/CMakeLists.linux-x86_64.txt new file mode 100644 index 0000000000..7d6211c778 --- /dev/null +++ b/ydb/core/blobstorage/ut_blobstorage/ut_vdisk_restart/CMakeLists.linux-x86_64.txt @@ -0,0 +1,79 @@ + +# This file was generated by the build system used internally in the Yandex monorepo. +# Only simple modifications are allowed (adding source-files to targets, adding simple properties +# like target_include_directories). These modifications will be ported to original +# ya.make files by maintainers. Any complex modifications which can't be ported back to the +# original buildsystem will not be accepted. + + + +add_executable(blobstorage-ut_blobstorage-ut_vdisk_restart) +target_include_directories(blobstorage-ut_blobstorage-ut_vdisk_restart PRIVATE + ${CMAKE_SOURCE_DIR}/ydb/core/blobstorage/ut_blobstorage +) +target_link_libraries(blobstorage-ut_blobstorage-ut_vdisk_restart PUBLIC + contrib-libs-linux-headers + contrib-libs-cxxsupp + yutil + library-cpp-cpuid_check + cpp-testing-unittest_main + blobstorage-ut_blobstorage-lib +) +target_link_options(blobstorage-ut_blobstorage-ut_vdisk_restart PRIVATE + -ldl + -lrt + -Wl,--no-as-needed + -fPIC + -fPIC + -lpthread + -lrt + -ldl +) +target_sources(blobstorage-ut_blobstorage-ut_vdisk_restart PRIVATE + ${CMAKE_SOURCE_DIR}/ydb/core/blobstorage/ut_blobstorage/vdisk_restart.cpp +) +set_property( + TARGET + blobstorage-ut_blobstorage-ut_vdisk_restart + PROPERTY + SPLIT_FACTOR + 10 +) +add_yunittest( + NAME + blobstorage-ut_blobstorage-ut_vdisk_restart + TEST_TARGET + blobstorage-ut_blobstorage-ut_vdisk_restart + TEST_ARG + --print-before-suite + --print-before-test + --fork-tests + --print-times + --show-fails +) +set_yunittest_property( + TEST + blobstorage-ut_blobstorage-ut_vdisk_restart + PROPERTY + LABELS + MEDIUM +) +set_yunittest_property( + TEST + blobstorage-ut_blobstorage-ut_vdisk_restart + PROPERTY + PROCESSORS + 1 +) +set_yunittest_property( + TEST + blobstorage-ut_blobstorage-ut_vdisk_restart + PROPERTY + TIMEOUT + 600 +) +target_allocator(blobstorage-ut_blobstorage-ut_vdisk_restart + cpp-malloc-tcmalloc + libs-tcmalloc-no_percpu_cache +) +vcs_info(blobstorage-ut_blobstorage-ut_vdisk_restart) diff --git a/ydb/core/blobstorage/ut_blobstorage/ut_vdisk_restart/CMakeLists.txt b/ydb/core/blobstorage/ut_blobstorage/ut_vdisk_restart/CMakeLists.txt new file mode 100644 index 0000000000..f8b31df0c1 --- /dev/null +++ b/ydb/core/blobstorage/ut_blobstorage/ut_vdisk_restart/CMakeLists.txt @@ -0,0 +1,17 @@ + +# This file was generated by the build system used internally in the Yandex monorepo. +# Only simple modifications are allowed (adding source-files to targets, adding simple properties +# like target_include_directories). These modifications will be ported to original +# ya.make files by maintainers. Any complex modifications which can't be ported back to the +# original buildsystem will not be accepted. + + +if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA) + include(CMakeLists.linux-aarch64.txt) +elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") + include(CMakeLists.darwin-x86_64.txt) +elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA) + include(CMakeLists.windows-x86_64.txt) +elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA) + include(CMakeLists.linux-x86_64.txt) +endif() diff --git a/ydb/core/blobstorage/ut_blobstorage/ut_vdisk_restart/CMakeLists.windows-x86_64.txt b/ydb/core/blobstorage/ut_blobstorage/ut_vdisk_restart/CMakeLists.windows-x86_64.txt new file mode 100644 index 0000000000..40828e0922 --- /dev/null +++ b/ydb/core/blobstorage/ut_blobstorage/ut_vdisk_restart/CMakeLists.windows-x86_64.txt @@ -0,0 +1,67 @@ + +# This file was generated by the build system used internally in the Yandex monorepo. +# Only simple modifications are allowed (adding source-files to targets, adding simple properties +# like target_include_directories). These modifications will be ported to original +# ya.make files by maintainers. Any complex modifications which can't be ported back to the +# original buildsystem will not be accepted. + + + +add_executable(blobstorage-ut_blobstorage-ut_vdisk_restart) +target_include_directories(blobstorage-ut_blobstorage-ut_vdisk_restart PRIVATE + ${CMAKE_SOURCE_DIR}/ydb/core/blobstorage/ut_blobstorage +) +target_link_libraries(blobstorage-ut_blobstorage-ut_vdisk_restart PUBLIC + contrib-libs-cxxsupp + yutil + library-cpp-cpuid_check + cpp-testing-unittest_main + blobstorage-ut_blobstorage-lib +) +target_sources(blobstorage-ut_blobstorage-ut_vdisk_restart PRIVATE + ${CMAKE_SOURCE_DIR}/ydb/core/blobstorage/ut_blobstorage/vdisk_restart.cpp +) +set_property( + TARGET + blobstorage-ut_blobstorage-ut_vdisk_restart + PROPERTY + SPLIT_FACTOR + 10 +) +add_yunittest( + NAME + blobstorage-ut_blobstorage-ut_vdisk_restart + TEST_TARGET + blobstorage-ut_blobstorage-ut_vdisk_restart + TEST_ARG + --print-before-suite + --print-before-test + --fork-tests + --print-times + --show-fails +) +set_yunittest_property( + TEST + blobstorage-ut_blobstorage-ut_vdisk_restart + PROPERTY + LABELS + MEDIUM +) +set_yunittest_property( + TEST + blobstorage-ut_blobstorage-ut_vdisk_restart + PROPERTY + PROCESSORS + 1 +) +set_yunittest_property( + TEST + blobstorage-ut_blobstorage-ut_vdisk_restart + PROPERTY + TIMEOUT + 600 +) +target_allocator(blobstorage-ut_blobstorage-ut_vdisk_restart + system_allocator +) +vcs_info(blobstorage-ut_blobstorage-ut_vdisk_restart) diff --git a/ydb/core/blobstorage/ut_blobstorage/ut_vdisk_restart/ya.make b/ydb/core/blobstorage/ut_blobstorage/ut_vdisk_restart/ya.make new file mode 100644 index 0000000000..063edc83d4 --- /dev/null +++ b/ydb/core/blobstorage/ut_blobstorage/ut_vdisk_restart/ya.make @@ -0,0 +1,17 @@ +UNITTEST_FOR(ydb/core/blobstorage/ut_blobstorage) + + FORK_SUBTESTS() + + SIZE(MEDIUM) + + TIMEOUT(600) + + SRCS( + vdisk_restart.cpp + ) + + PEERDIR( + ydb/core/blobstorage/ut_blobstorage/lib + ) + +END() diff --git a/ydb/core/blobstorage/ut_blobstorage/vdisk_restart.cpp b/ydb/core/blobstorage/ut_blobstorage/vdisk_restart.cpp new file mode 100644 index 0000000000..a6b02c63f1 --- /dev/null +++ b/ydb/core/blobstorage/ut_blobstorage/vdisk_restart.cpp @@ -0,0 +1,64 @@ +#include <ydb/core/blobstorage/ut_blobstorage/lib/env.h> + +#include <ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_http_request.h> + + +Y_UNIT_TEST_SUITE(VDiskRestart) { + + Y_UNIT_TEST(Simple) { + TEnvironmentSetup env({ + .NodeCount = 8, + .VDiskReplPausedAtStart = false, + .Erasure = TBlobStorageGroupType::Erasure4Plus2Block, + }); + env.CreateBoxAndPool(1, 1); + env.Sim(TDuration::Minutes(1)); + + auto groups = env.GetGroups(); + UNIT_ASSERT_VALUES_EQUAL(groups.size(), 1); + + auto groupInfo = env.GetGroupInfo(groups.front()); + + + ui32 pos = 0; + auto vDiskActorId = groupInfo->GetActorId(pos); + auto baseConfig = env.FetchBaseConfig(); + const TVDiskID& someVDisk = groupInfo->GetVDiskId(pos); + const auto& somePDisk = baseConfig.GetPDisk(pos); + const auto& someVSlot = baseConfig.GetVSlot(pos); + auto getOwnerRound = [&]() { + return env.PDiskMockStates[{somePDisk.GetNodeId(), somePDisk.GetPDiskId()}]->GetOwnerRound(someVDisk); + }; + auto currentRound = getOwnerRound(); + + const TActorId sender = env.Runtime->AllocateEdgeActor(vDiskActorId.NodeId(), __FILE__, __LINE__); + + THttpRequestMock httpRequest; + httpRequest.CgiParameters.InsertUnescaped("type", "restart"); + httpRequest.Path = Sprintf("/actors/vdisks/vdisk%09" PRIu32 "_%09" PRIu32, somePDisk.GetPDiskId(), someVSlot.GetVSlotId().GetVSlotId()); + NMonitoring::TMonService2HttpRequest monService2HttpRequest(nullptr, &httpRequest, nullptr, nullptr, "", nullptr); + auto ev = std::make_unique<NMon::TEvHttpInfo>(monService2HttpRequest); + + auto sendPDiskEvent = [&](EPDiskMockEvents ev) { + for (const auto& pDisk: env.PDiskActors) { + env.Runtime->WrapInActorContext(sender, [&] () { + env.Runtime->Send(new IEventHandle(ev, 0, pDisk, sender, nullptr, 0)); + }); + } + }; + sendPDiskEvent(EvBecomeError); + env.Sim(TDuration::Seconds(1)); + + env.Runtime->WrapInActorContext(sender, [&] () { + env.Runtime->Send(new IEventHandle(vDiskActorId, sender, ev.release())); + }); + auto res = env.WaitForEdgeActorEvent<NMon::TEvHttpInfoRes>(sender, false); + UNIT_ASSERT_VALUES_UNEQUAL(res->Get()->Answer.find("VDisk restart request has been sent"), std::string::npos); + + env.Sim(TDuration::Seconds(10)); + sendPDiskEvent(EvBecomeNormal); + env.Sim(TDuration::Seconds(10)); + + UNIT_ASSERT_VALUES_UNEQUAL(currentRound, getOwnerRound()); + } +} diff --git a/ydb/core/blobstorage/ut_blobstorage/ya.make b/ydb/core/blobstorage/ut_blobstorage/ya.make index ce95915d31..c2acdec391 100644 --- a/ydb/core/blobstorage/ut_blobstorage/ya.make +++ b/ydb/core/blobstorage/ut_blobstorage/ya.make @@ -67,4 +67,5 @@ RECURSE_FOR_TESTS( ut_osiris ut_replication ut_scrub + ut_vdisk_restart ) diff --git a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_monactors.cpp b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_monactors.cpp index 8dda48b7c2..e2c611338d 100644 --- a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_monactors.cpp +++ b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_monactors.cpp @@ -3,6 +3,8 @@ #include "skeleton_mon_dbmainpage.h" #include "skeleton_mon_util.h" +#include <ydb/core/blobstorage/base/blobstorage_events.h> + #include <library/cpp/actors/core/hfunc.h> #include <library/cpp/actors/core/actor_bootstrapped.h> #include <library/cpp/actors/core/mon.h> @@ -983,6 +985,49 @@ namespace NKikimr { {} }; + class TRestartVDiskActor : public TActorBootstrapped<TRestartVDiskActor> { + const ui32 PDiskId; + const TVDiskID VDiskId; + const TActorId WardenId; + const TActorId NotifyId; + const TActorId Sender; + + friend class TActorBootstrapped<TRestartVDiskActor>; + + void Bootstrap(const TActorContext &ctx) { + ctx.Send(WardenId, new TEvBlobStorage::TEvAskRestartVDisk(PDiskId, VDiskId)); + ctx.Send(NotifyId, new TEvents::TEvActorDied); + ctx.Send(Sender, new NMon::TEvHttpInfoRes(MakeReply())); + Die(ctx); + } + + TString MakeReply() const { + TStringStream str; + HTML(str) { + str << "VDisk restart request has been sent <br>\n" + << "<a class=\"btn btn-default\" href=\"?\">Go back to the main VDisk page</a>"; + } + return str.Str(); + } + + public: + TRestartVDiskActor( + const ui32 pDiskId, + const TVDiskID &vDiskId, + const TActorId &wardenId, + const TActorId ¬ifyId, + const TActorId &sender + ) + : TActorBootstrapped<TRestartVDiskActor>() + , PDiskId(pDiskId) + , VDiskId(vDiskId) + , WardenId(wardenId) + , NotifyId(notifyId) + , Sender(sender) + { + } + }; + //////////////////////////////////////////////////////////////////////////// // TSkeletonFrontMonMainPageActor //////////////////////////////////////////////////////////////////////////// @@ -1064,6 +1109,10 @@ namespace NKikimr { {} }; + bool IsVDiskRestartAllowed(NKikimrWhiteboard::EVDiskState state) { + return state == NKikimrWhiteboard::EVDiskState::PDiskError; + } + //////////////////////////////////////////////////////////////////////////// // SKELETON FRONT MON REQUEST HANDLER //////////////////////////////////////////////////////////////////////////// @@ -1074,7 +1123,8 @@ namespace NKikimr { TIntrusivePtr<TVDiskConfig> cfg, const std::shared_ptr<TBlobStorageGroupInfo::TTopology> &top, NMon::TEvHttpInfo::TPtr &ev, - const TString &frontHtml) { + const TString &frontHtml, + const NMonGroup::TVDiskStateGroup& vDiskMonGroup) { const TCgiParameters& cgi = ev->Get()->Request.GetParams(); const TString &type = cgi.Get("type"); @@ -1104,6 +1154,17 @@ namespace NKikimr { ev, NKikimrBlobStorage::StatHugeAction, dbname); } else if (type == "dbmainpage") { return CreateMonDbMainPageActor(selfVDiskId, notifyId, skeletonFrontID, skeletonID, ev); + } else if (type == "restart") { + if (IsVDiskRestartAllowed(vDiskMonGroup.VDiskState())) { + return new TRestartVDiskActor( + cfg->BaseInfo.PDiskId, selfVDiskId, MakeBlobStorageNodeWardenID(skeletonFrontID.NodeId()), notifyId, ev->Sender + ); + } else { + return new TMonErrorActor(notifyId, ev, + "VDisk restart in the normal state is not allowed <br>\n" + "<a class=\"btn btn-default\" href=\"?\">Go back to the main VDisk page</a>" + ); + } } else { auto s = Sprintf("Unknown value '%s' for CGI parameter 'type'", type.data()); return new TMonErrorActor(notifyId, ev, s); diff --git a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_monactors.h b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_monactors.h index a05d0641a7..1eafd9ae69 100644 --- a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_monactors.h +++ b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_monactors.h @@ -21,7 +21,8 @@ namespace NKikimr { TIntrusivePtr<TVDiskConfig> cfg, const std::shared_ptr<TBlobStorageGroupInfo::TTopology> &top, NMon::TEvHttpInfo::TPtr &ev, - const TString &frontHtml); + const TString &frontHtml, + const NMonGroup::TVDiskStateGroup& vDiskMonGroup); IActor *CreateFrontSkeletonGetLogoBlobRequestHandler(const TVDiskID &selfVDiskId, const TActorId ¬ifyId, @@ -30,6 +31,7 @@ namespace NKikimr { const std::shared_ptr<TBlobStorageGroupInfo::TTopology> &top, TEvGetLogoBlobRequest::TPtr &ev); + bool IsVDiskRestartAllowed(NKikimrWhiteboard::EVDiskState state); } // NKikimr diff --git a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeletonfront.cpp b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeletonfront.cpp index dadb329e7b..5c7cda83ba 100644 --- a/ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeletonfront.cpp +++ b/ydb/core/blobstorage/vdisk/skeleton/blobstorage_skeletonfront.cpp @@ -926,6 +926,15 @@ namespace NKikimr { } } } + { + str << "<a class=\"btn btn-default\" href=\"?type=restart\" " + << ( + IsVDiskRestartAllowed(VDiskMonGroup.VDiskState()) + ? "style='background:Tomato' " + : "disabled style='background:LightGray' " + ) + << ">Restart</a>"; + } } } } @@ -1535,7 +1544,7 @@ namespace NKikimr { TString html = (type == TString()) ? GenerateHtmlState(ctx) : TString(); auto aid = ctx.Register(CreateFrontSkeletonMonRequestHandler(SelfVDiskId, ctx.SelfID, SkeletonId, - ctx.SelfID, Config, Top, ev, html)); + ctx.SelfID, Config, Top, ev, html, VDiskMonGroup)); ActiveActors.Insert(aid); } |