From 0504c484a3b86fffea29ac5bbcdf064a2ba8577f Mon Sep 17 00:00:00 2001 From: Pavel Misko Date: Tue, 21 Jul 2026 21:53:16 +0200 Subject: [PATCH] [NBS] Allow custom BlockDigestGenerator for volumes --- .../blockstore/libs/daemon/ydb/bootstrap.cpp | 16 +-- cloud/blockstore/libs/daemon/ydb/bootstrap.h | 1 + .../libs/diagnostics/block_digest.h | 2 + .../storage/core/block_digest_factory.cpp | 40 ++++++ .../libs/storage/core/block_digest_factory.h | 22 ++++ cloud/blockstore/libs/storage/core/public.h | 3 + cloud/blockstore/libs/storage/core/ya.make | 1 + .../libs/storage/init/server/actorsystem.cpp | 10 +- .../libs/storage/init/server/actorsystem.h | 1 + .../libs/storage/service/service.cpp | 4 +- .../blockstore/libs/storage/service/service.h | 2 +- .../libs/storage/service/service_actor.cpp | 4 +- .../libs/storage/service/service_actor.h | 6 +- .../storage/service/service_actor_mount.cpp | 2 +- .../storage/service/volume_session_actor.cpp | 6 +- .../storage/service/volume_session_actor.h | 6 +- .../service/volume_session_actor_start.cpp | 16 +-- .../libs/storage/testlib/test_env.cpp | 5 +- .../libs/storage/volume/testlib/test_env.cpp | 12 +- .../libs/storage/volume/testlib/test_env.h | 3 +- .../blockstore/libs/storage/volume/volume.cpp | 4 +- cloud/blockstore/libs/storage/volume/volume.h | 2 +- .../libs/storage/volume/volume_actor.cpp | 4 +- .../libs/storage/volume/volume_actor.h | 6 +- .../volume_actor_change_storage_config.cpp | 6 + .../storage/volume/volume_actor_loadstate.cpp | 5 + .../libs/storage/volume/volume_ut.cpp | 116 ++++++++++++++++++ 27 files changed, 255 insertions(+), 50 deletions(-) create mode 100644 cloud/blockstore/libs/storage/core/block_digest_factory.cpp create mode 100644 cloud/blockstore/libs/storage/core/block_digest_factory.h diff --git a/cloud/blockstore/libs/daemon/ydb/bootstrap.cpp b/cloud/blockstore/libs/daemon/ydb/bootstrap.cpp index cc9f7f76b55..10680dac32a 100644 --- a/cloud/blockstore/libs/daemon/ydb/bootstrap.cpp +++ b/cloud/blockstore/libs/daemon/ydb/bootstrap.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -774,16 +775,10 @@ void TBootstrapYdb::InitKikimrService() STORAGE_INFO("StatsFetcher initialized"); - if (Configs->StorageConfig->GetBlockDigestsEnabled()) { - if (Configs->StorageConfig->GetUseTestBlockDigestGenerator()) { - BlockDigestGenerator = CreateTestBlockDigestGenerator(); - } else { - BlockDigestGenerator = CreateExt4BlockDigestGenerator( - Configs->StorageConfig->GetDigestedBlocksPercentage()); - } - } else { - BlockDigestGenerator = CreateBlockDigestGeneratorStub(); - } + BlockDigestGeneratorFactory = NStorage::CreateBlockDigestGeneratorFactory(); + BlockDigestGenerator = + BlockDigestGeneratorFactory->CreateBlockDigestGenerator( + *Configs->StorageConfig); STORAGE_INFO("DigestGenerator initialized"); @@ -849,6 +844,7 @@ void TBootstrapYdb::InitKikimrService() args.Allocator = Allocator; args.LocalStorageProvider = LocalStorageProvider; args.ProfileLog = ProfileLog; + args.BlockDigestGeneratorFactory = BlockDigestGeneratorFactory; args.BlockDigestGenerator = BlockDigestGenerator; args.TraceSerializer = TraceSerializer; args.LogbrokerService = LogbrokerService; diff --git a/cloud/blockstore/libs/daemon/ydb/bootstrap.h b/cloud/blockstore/libs/daemon/ydb/bootstrap.h index b5e5a4e3067..5acc3f10dd2 100644 --- a/cloud/blockstore/libs/daemon/ydb/bootstrap.h +++ b/cloud/blockstore/libs/daemon/ydb/bootstrap.h @@ -119,6 +119,7 @@ struct TBootstrapYdb final ITraceServiceClientPtr TraceServiceClient; std::function SpdkLogInitializer; NStorage::TPartitionBudgetManagerPtr PartitionBudgetManager; + NStorage::IBlockDigestGeneratorFactoryPtr BlockDigestGeneratorFactory; public: TBootstrapYdb( diff --git a/cloud/blockstore/libs/diagnostics/block_digest.h b/cloud/blockstore/libs/diagnostics/block_digest.h index 1ec91148e6d..c3a2a31102a 100644 --- a/cloud/blockstore/libs/diagnostics/block_digest.h +++ b/cloud/blockstore/libs/diagnostics/block_digest.h @@ -12,6 +12,8 @@ namespace NCloud::NBlockStore { struct IBlockDigestGenerator { + virtual ~IBlockDigestGenerator() = default; + virtual TMaybe ComputeDigest( ui64 blockIndex, TBlockDataRef blockContent) const = 0; diff --git a/cloud/blockstore/libs/storage/core/block_digest_factory.cpp b/cloud/blockstore/libs/storage/core/block_digest_factory.cpp new file mode 100644 index 00000000000..bc71bb8601a --- /dev/null +++ b/cloud/blockstore/libs/storage/core/block_digest_factory.cpp @@ -0,0 +1,40 @@ +#include "block_digest_factory.h" + +#include "config.h" + +#include + +namespace NCloud::NBlockStore::NStorage { + +namespace { + +//////////////////////////////////////////////////////////////////////////////// + +struct TBlockDigestGeneratorFactory final: IBlockDigestGeneratorFactory +{ + [[nodiscard]] auto CreateBlockDigestGenerator(const TStorageConfig& config) + -> IBlockDigestGeneratorPtr final + { + if (!config.GetBlockDigestsEnabled()) { + return CreateBlockDigestGeneratorStub(); + } + + if (config.GetUseTestBlockDigestGenerator()) { + return CreateTestBlockDigestGenerator(); + } + + return CreateExt4BlockDigestGenerator( + config.GetDigestedBlocksPercentage()); + } +}; + +} // namespace + +//////////////////////////////////////////////////////////////////////////////// + +IBlockDigestGeneratorFactoryPtr CreateBlockDigestGeneratorFactory() +{ + return std::make_shared(); +} + +} // namespace NCloud::NBlockStore::NStorage diff --git a/cloud/blockstore/libs/storage/core/block_digest_factory.h b/cloud/blockstore/libs/storage/core/block_digest_factory.h new file mode 100644 index 00000000000..50493a60006 --- /dev/null +++ b/cloud/blockstore/libs/storage/core/block_digest_factory.h @@ -0,0 +1,22 @@ +#pragma once +#include "public.h" + +#include + +namespace NCloud::NBlockStore::NStorage { + +//////////////////////////////////////////////////////////////////////////////// + +struct IBlockDigestGeneratorFactory +{ + virtual ~IBlockDigestGeneratorFactory() = default; + + [[nodiscard]] virtual auto CreateBlockDigestGenerator( + const TStorageConfig& config) -> IBlockDigestGeneratorPtr = 0; +}; + +//////////////////////////////////////////////////////////////////////////////// + +IBlockDigestGeneratorFactoryPtr CreateBlockDigestGeneratorFactory(); + +} // namespace NCloud::NBlockStore::NStorage diff --git a/cloud/blockstore/libs/storage/core/public.h b/cloud/blockstore/libs/storage/core/public.h index c979d986c42..ac593ca588b 100644 --- a/cloud/blockstore/libs/storage/core/public.h +++ b/cloud/blockstore/libs/storage/core/public.h @@ -36,6 +36,9 @@ using TManuallyPreemptedVolumesPtr = std::shared_ptr; class TPartitionBudgetManager; using TPartitionBudgetManagerPtr = std::shared_ptr; +struct IBlockDigestGeneratorFactory; +using IBlockDigestGeneratorFactoryPtr = std::shared_ptr; + //////////////////////////////////////////////////////////////////////////////// enum class EStorageAccessMode diff --git a/cloud/blockstore/libs/storage/core/ya.make b/cloud/blockstore/libs/storage/core/ya.make index 0806ed12c92..6e2d20c85ad 100644 --- a/cloud/blockstore/libs/storage/core/ya.make +++ b/cloud/blockstore/libs/storage/core/ya.make @@ -4,6 +4,7 @@ GENERATE_ENUM_SERIALIZATION(device_operation_tracker.h) GENERATE_ENUM_SERIALIZATION(mount_token.h) SRCS( + block_digest_factory.cpp block_handler.cpp channel_permissions.cpp compaction_map.cpp diff --git a/cloud/blockstore/libs/storage/init/server/actorsystem.cpp b/cloud/blockstore/libs/storage/init/server/actorsystem.cpp index 8a14897f24e..8b892419f1a 100644 --- a/cloud/blockstore/libs/storage/init/server/actorsystem.cpp +++ b/cloud/blockstore/libs/storage/init/server/actorsystem.cpp @@ -225,7 +225,7 @@ class TStorageServicesInitializer final Args.StorageConfig, Args.DiagnosticsConfig, Args.ProfileLog, - Args.BlockDigestGenerator, + Args.BlockDigestGeneratorFactory, Args.DiscoveryService, Args.TraceSerializer, Args.EndpointEventHandler, @@ -383,6 +383,7 @@ class TCustomLocalServiceInitializer final const TStorageConfigPtr StorageConfig; const TDiagnosticsConfigPtr DiagnosticsConfig; const IProfileLogPtr ProfileLog; + const IBlockDigestGeneratorFactoryPtr BlockDigestGeneratorFactory; const IBlockDigestGeneratorPtr BlockDigestGenerator; const ITraceSerializerPtr TraceSerializer; const NLogbroker::IServicePtr LogbrokerService; @@ -400,6 +401,7 @@ class TCustomLocalServiceInitializer final TStorageConfigPtr storageConfig, TDiagnosticsConfigPtr diagnosticsConfig, IProfileLogPtr profileLog, + IBlockDigestGeneratorFactoryPtr blockDigestGeneratorFactory, IBlockDigestGeneratorPtr blockDigestGenerator, ITraceSerializerPtr traceSerializer, NLogbroker::IServicePtr logbrokerService, @@ -414,6 +416,7 @@ class TCustomLocalServiceInitializer final , StorageConfig(std::move(storageConfig)) , DiagnosticsConfig(std::move(diagnosticsConfig)) , ProfileLog(std::move(profileLog)) + , BlockDigestGeneratorFactory(std::move(blockDigestGeneratorFactory)) , BlockDigestGenerator(std::move(blockDigestGenerator)) , TraceSerializer(std::move(traceSerializer)) , LogbrokerService(std::move(logbrokerService)) @@ -432,7 +435,7 @@ class TCustomLocalServiceInitializer final auto storageConfig = StorageConfig; auto diagnosticsConfig = DiagnosticsConfig; auto profileLog = ProfileLog; - auto blockDigestGenerator = BlockDigestGenerator; + auto blockDigestGeneratorFactory = BlockDigestGeneratorFactory; auto traceSerializer = TraceSerializer; auto logbrokerService = LogbrokerService; auto notifyService = NotifyService; @@ -450,7 +453,7 @@ class TCustomLocalServiceInitializer final storageConfig, diagnosticsConfig, profileLog, - blockDigestGenerator, + blockDigestGeneratorFactory, traceSerializer, rdmaClient, partitionBudgetManager, @@ -580,6 +583,7 @@ IActorSystemPtr CreateActorSystem(const TServerActorSystemArgs& sArgs) sArgs.StorageConfig, sArgs.DiagnosticsConfig, sArgs.ProfileLog, + sArgs.BlockDigestGeneratorFactory, sArgs.BlockDigestGenerator, sArgs.TraceSerializer, sArgs.LogbrokerService, diff --git a/cloud/blockstore/libs/storage/init/server/actorsystem.h b/cloud/blockstore/libs/storage/init/server/actorsystem.h index a97eacebd94..dd6b27dfbfc 100644 --- a/cloud/blockstore/libs/storage/init/server/actorsystem.h +++ b/cloud/blockstore/libs/storage/init/server/actorsystem.h @@ -56,6 +56,7 @@ struct TServerActorSystemArgs IStorageProviderPtr LocalStorageProvider; IProfileLogPtr ProfileLog; IBlockDigestGeneratorPtr BlockDigestGenerator; + IBlockDigestGeneratorFactoryPtr BlockDigestGeneratorFactory; ITraceSerializerPtr TraceSerializer; NLogbroker::IServicePtr LogbrokerService; NNotify::IServicePtr NotifyService; diff --git a/cloud/blockstore/libs/storage/service/service.cpp b/cloud/blockstore/libs/storage/service/service.cpp index 065bf828fef..98c281ba3bf 100644 --- a/cloud/blockstore/libs/storage/service/service.cpp +++ b/cloud/blockstore/libs/storage/service/service.cpp @@ -12,7 +12,7 @@ IActorPtr CreateStorageService( TStorageConfigPtr config, TDiagnosticsConfigPtr diagnosticsConfig, IProfileLogPtr profileLog, - IBlockDigestGeneratorPtr blockDigestGenerator, + IBlockDigestGeneratorFactoryPtr blockDigestGeneratorFactory, NDiscovery::IDiscoveryServicePtr discoveryService, ITraceSerializerPtr traceSerializer, NServer::IEndpointEventHandlerPtr endpointEventHandler, @@ -27,7 +27,7 @@ IActorPtr CreateStorageService( std::move(config), std::move(diagnosticsConfig), std::move(profileLog), - std::move(blockDigestGenerator), + std::move(blockDigestGeneratorFactory), std::move(discoveryService), std::move(traceSerializer), std::move(endpointEventHandler), diff --git a/cloud/blockstore/libs/storage/service/service.h b/cloud/blockstore/libs/storage/service/service.h index 220ac9f8d31..a837fe0bd42 100644 --- a/cloud/blockstore/libs/storage/service/service.h +++ b/cloud/blockstore/libs/storage/service/service.h @@ -19,7 +19,7 @@ NActors::IActorPtr CreateStorageService( TStorageConfigPtr config, TDiagnosticsConfigPtr diagnosticsConfig, IProfileLogPtr profileLog, - IBlockDigestGeneratorPtr blockDigestGenerator, + IBlockDigestGeneratorFactoryPtr blockDigestGeneratorFactory, NDiscovery::IDiscoveryServicePtr discoveryService, ITraceSerializerPtr traceSerializer, NServer::IEndpointEventHandlerPtr endpointEventHandler, diff --git a/cloud/blockstore/libs/storage/service/service_actor.cpp b/cloud/blockstore/libs/storage/service/service_actor.cpp index 5a17d6836ee..6192a7ecefe 100644 --- a/cloud/blockstore/libs/storage/service/service_actor.cpp +++ b/cloud/blockstore/libs/storage/service/service_actor.cpp @@ -20,7 +20,7 @@ TServiceActor::TServiceActor( TStorageConfigPtr config, TDiagnosticsConfigPtr diagnosticsConfig, IProfileLogPtr profileLog, - IBlockDigestGeneratorPtr blockDigestGenerator, + IBlockDigestGeneratorFactoryPtr blockDigestGeneratorFactory, NDiscovery::IDiscoveryServicePtr discoveryService, ITraceSerializerPtr traceSerializer, NServer::IEndpointEventHandlerPtr endpointEventHandler, @@ -33,7 +33,7 @@ TServiceActor::TServiceActor( : Config(std::move(config)) , DiagnosticsConfig(std::move(diagnosticsConfig)) , ProfileLog(std::move(profileLog)) - , BlockDigestGenerator(std::move(blockDigestGenerator)) + , BlockDigestGeneratorFactory(std::move(blockDigestGeneratorFactory)) , DiscoveryService(std::move(discoveryService)) , TraceSerializer(std::move(traceSerializer)) , EndpointEventHandler(std::move(endpointEventHandler)) diff --git a/cloud/blockstore/libs/storage/service/service_actor.h b/cloud/blockstore/libs/storage/service/service_actor.h index b3a773ffae6..f169911e129 100644 --- a/cloud/blockstore/libs/storage/service/service_actor.h +++ b/cloud/blockstore/libs/storage/service/service_actor.h @@ -43,7 +43,7 @@ class TServiceActor final const TStorageConfigPtr Config; const TDiagnosticsConfigPtr DiagnosticsConfig; const IProfileLogPtr ProfileLog; - const IBlockDigestGeneratorPtr BlockDigestGenerator; + const IBlockDigestGeneratorFactoryPtr BlockDigestGeneratorFactory; const NDiscovery::IDiscoveryServicePtr DiscoveryService; const ITraceSerializerPtr TraceSerializer; const NServer::IEndpointEventHandlerPtr EndpointEventHandler; @@ -72,7 +72,7 @@ class TServiceActor final TStorageConfigPtr config, TDiagnosticsConfigPtr diagnosticsConfig, IProfileLogPtr profileLog, - IBlockDigestGeneratorPtr blockDigestGenerator, + IBlockDigestGeneratorFactoryPtr blockDigestGeneratorFactory, NDiscovery::IDiscoveryServicePtr discoveryService, ITraceSerializerPtr traceSerializer, NServer::IEndpointEventHandlerPtr endpointEventHandler, @@ -496,7 +496,7 @@ NActors::IActorPtr CreateVolumeSessionActor( TStorageConfigPtr config, TDiagnosticsConfigPtr diagnosticsConfig, IProfileLogPtr profileLog, - IBlockDigestGeneratorPtr blockDigestGenerator, + IBlockDigestGeneratorFactoryPtr blockDigestGeneratorFactory, ITraceSerializerPtr traceSerializer, NServer::IEndpointEventHandlerPtr endpointEventHandler, NCloud::NStorage::NRdma::IClientPtr rdmaClient, diff --git a/cloud/blockstore/libs/storage/service/service_actor_mount.cpp b/cloud/blockstore/libs/storage/service/service_actor_mount.cpp index 9dcebd58426..0f9f1817c3c 100644 --- a/cloud/blockstore/libs/storage/service/service_actor_mount.cpp +++ b/cloud/blockstore/libs/storage/service/service_actor_mount.cpp @@ -138,7 +138,7 @@ void TServiceActor::HandleMountVolume( Config, DiagnosticsConfig, ProfileLog, - BlockDigestGenerator, + BlockDigestGeneratorFactory, TraceSerializer, EndpointEventHandler, RdmaClient, diff --git a/cloud/blockstore/libs/storage/service/volume_session_actor.cpp b/cloud/blockstore/libs/storage/service/volume_session_actor.cpp index 7aa7720ff22..d34b8de6deb 100644 --- a/cloud/blockstore/libs/storage/service/volume_session_actor.cpp +++ b/cloud/blockstore/libs/storage/service/volume_session_actor.cpp @@ -381,7 +381,7 @@ IActorPtr CreateVolumeSessionActor( TStorageConfigPtr config, TDiagnosticsConfigPtr diagnosticsConfig, IProfileLogPtr profileLog, - IBlockDigestGeneratorPtr blockDigestGenerator, + IBlockDigestGeneratorFactoryPtr blockDigestGeneratorFactory, ITraceSerializerPtr traceSerializer, NServer::IEndpointEventHandlerPtr endpointEventHandler, NCloud::NStorage::NRdma::IClientPtr rdmaClient, @@ -396,7 +396,7 @@ IActorPtr CreateVolumeSessionActor( std::move(config), std::move(diagnosticsConfig), std::move(profileLog), - std::move(blockDigestGenerator), + std::move(blockDigestGeneratorFactory), std::move(traceSerializer), std::move(endpointEventHandler), std::move(rdmaClient), @@ -407,6 +407,4 @@ IActorPtr CreateVolumeSessionActor( temporaryServer); } -//////////////////////////////////////////////////////////////////////////////// - } // namespace NCloud::NBlockStore::NStorage diff --git a/cloud/blockstore/libs/storage/service/volume_session_actor.h b/cloud/blockstore/libs/storage/service/volume_session_actor.h index a99bd2a5bbd..5cd06b58149 100644 --- a/cloud/blockstore/libs/storage/service/volume_session_actor.h +++ b/cloud/blockstore/libs/storage/service/volume_session_actor.h @@ -54,7 +54,7 @@ class TVolumeSessionActor final const TStorageConfigPtr Config; const TDiagnosticsConfigPtr DiagnosticsConfig; const IProfileLogPtr ProfileLog; - const IBlockDigestGeneratorPtr BlockDigestGenerator; + const IBlockDigestGeneratorFactoryPtr BlockDigestGeneratorFactory; const ITraceSerializerPtr TraceSerializer; const NServer::IEndpointEventHandlerPtr EndpointEventHandler; const NCloud::NStorage::NRdma::IClientPtr RdmaClient; @@ -96,7 +96,7 @@ class TVolumeSessionActor final TStorageConfigPtr config, TDiagnosticsConfigPtr diagnosticsConfig, IProfileLogPtr profileLog, - IBlockDigestGeneratorPtr blockDigestGenerator, + IBlockDigestGeneratorFactoryPtr blockDigestGeneratorFactory, ITraceSerializerPtr traceSerializer, NServer::IEndpointEventHandlerPtr endpointEventHandler, NCloud::NStorage::NRdma::IClientPtr rdmaClient, @@ -109,7 +109,7 @@ class TVolumeSessionActor final , Config(std::move(config)) , DiagnosticsConfig(std::move(diagnosticsConfig)) , ProfileLog(std::move(profileLog)) - , BlockDigestGenerator(std::move(blockDigestGenerator)) + , BlockDigestGeneratorFactory(std::move(blockDigestGeneratorFactory)) , TraceSerializer(std::move(traceSerializer)) , EndpointEventHandler(std::move(endpointEventHandler)) , RdmaClient(std::move(rdmaClient)) diff --git a/cloud/blockstore/libs/storage/service/volume_session_actor_start.cpp b/cloud/blockstore/libs/storage/service/volume_session_actor_start.cpp index ebae63a3e99..e557d955840 100644 --- a/cloud/blockstore/libs/storage/service/volume_session_actor_start.cpp +++ b/cloud/blockstore/libs/storage/service/volume_session_actor_start.cpp @@ -48,7 +48,7 @@ class TStartVolumeActor final const TStorageConfigPtr Config; const TDiagnosticsConfigPtr DiagnosticsConfig; const IProfileLogPtr ProfileLog; - const IBlockDigestGeneratorPtr BlockDigestGenerator; + const IBlockDigestGeneratorFactoryPtr BlockDigestGeneratorFactory; const ITraceSerializerPtr TraceSerializer; const NServer::IEndpointEventHandlerPtr EndpointEventHandler; const NCloud::NStorage::NRdma::IClientPtr RdmaClient; @@ -90,7 +90,7 @@ class TStartVolumeActor final TStorageConfigPtr config, TDiagnosticsConfigPtr diagnosticsConfig, IProfileLogPtr profileLog, - IBlockDigestGeneratorPtr blockDigestGenerator, + IBlockDigestGeneratorFactoryPtr blockDigestGeneratorFactory, ITraceSerializerPtr traceSerializer, NServer::IEndpointEventHandlerPtr endpointEventHandler, NCloud::NStorage::NRdma::IClientPtr rdmaClient, @@ -185,7 +185,7 @@ TStartVolumeActor::TStartVolumeActor( TStorageConfigPtr config, TDiagnosticsConfigPtr diagnosticsConfig, IProfileLogPtr profileLog, - IBlockDigestGeneratorPtr blockDigestGenerator, + IBlockDigestGeneratorFactoryPtr blockDigestGeneratorFactory, ITraceSerializerPtr traceSerializer, NServer::IEndpointEventHandlerPtr endpointEventHandler, NCloud::NStorage::NRdma::IClientPtr rdmaClient, @@ -196,7 +196,7 @@ TStartVolumeActor::TStartVolumeActor( , Config(std::move(config)) , DiagnosticsConfig(std::move(diagnosticsConfig)) , ProfileLog(std::move(profileLog)) - , BlockDigestGenerator(std::move(blockDigestGenerator)) + , BlockDigestGeneratorFactory(std::move(blockDigestGeneratorFactory)) , TraceSerializer(std::move(traceSerializer)) , EndpointEventHandler(std::move(endpointEventHandler)) , RdmaClient(std::move(rdmaClient)) @@ -587,7 +587,7 @@ void TStartVolumeActor::StartTablet(const TActorContext& ctx) auto config = Config; auto diagnosticsConfig = DiagnosticsConfig; auto profileLog = ProfileLog; - auto blockDigestGenerator = BlockDigestGenerator; + auto blockDigestGeneratorFactory = BlockDigestGeneratorFactory; auto traceSerializer = TraceSerializer; auto endpointEventHandler = EndpointEventHandler; auto rdmaClient = RdmaClient; @@ -597,7 +597,7 @@ void TStartVolumeActor::StartTablet(const TActorContext& ctx) [config, diagnosticsConfig, profileLog, - blockDigestGenerator, + blockDigestGeneratorFactory, traceSerializer, rdmaClient, endpointEventHandler, @@ -612,7 +612,7 @@ void TStartVolumeActor::StartTablet(const TActorContext& ctx) config, diagnosticsConfig, profileLog, - blockDigestGenerator, + blockDigestGeneratorFactory, traceSerializer, rdmaClient, partitionBudgetManager, @@ -1119,7 +1119,7 @@ void TVolumeSessionActor::HandleStartVolumeRequest( Config, DiagnosticsConfig, ProfileLog, - BlockDigestGenerator, + BlockDigestGeneratorFactory, TraceSerializer, EndpointEventHandler, RdmaClient, diff --git a/cloud/blockstore/libs/storage/testlib/test_env.cpp b/cloud/blockstore/libs/storage/testlib/test_env.cpp index 3e008863b5b..73c3af29fa9 100644 --- a/cloud/blockstore/libs/storage/testlib/test_env.cpp +++ b/cloud/blockstore/libs/storage/testlib/test_env.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -249,7 +250,7 @@ ui32 TTestEnv::CreateBlockStoreNode( storageConfig, diagnosticsConfig, CreateProfileLogStub(), - CreateBlockDigestGeneratorStub(), + NStorage::CreateBlockDigestGeneratorFactory(), TraceSerializer, nullptr, // RdmaClient partitionBudgetManager, @@ -409,7 +410,7 @@ ui32 TTestEnv::CreateBlockStoreNode( storageConfig, diagnosticsConfig, CreateProfileLogStub(), - CreateBlockDigestGeneratorStub(), + NStorage::CreateBlockDigestGeneratorFactory(), NDiscovery::CreateDiscoveryServiceStub(), TraceSerializer, NServer::CreateEndpointEventProxy(), diff --git a/cloud/blockstore/libs/storage/volume/testlib/test_env.cpp b/cloud/blockstore/libs/storage/volume/testlib/test_env.cpp index c68c9b38805..17f76cb0ee1 100644 --- a/cloud/blockstore/libs/storage/volume/testlib/test_env.cpp +++ b/cloud/blockstore/libs/storage/volume/testlib/test_env.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -795,7 +796,8 @@ std::unique_ptr PrepareTestActorRuntime( NProto::TFeaturesConfig featuresConfig, NCloud::NStorage::NRdma::IClientPtr rdmaClient, TVector diskAgentStates, - bool debugActorRegistration) + bool debugActorRegistration, + IProfileLogPtr profileLog) { const ui32 agentCount = Max(diskAgentStates.size(), 1); auto runtime = std::make_unique(agentCount); @@ -965,6 +967,10 @@ std::unique_ptr PrepareTestActorRuntime( auto partitionBudgetManager = std::make_shared(config); + if (!profileLog) { + profileLog = CreateProfileLogStub(); + } + auto createFunc = [=](const TActorId& owner, TTabletStorageInfo* info) { auto tablet = CreateVolumeTablet( @@ -972,8 +978,8 @@ std::unique_ptr PrepareTestActorRuntime( info, config, diagConfig, - CreateProfileLogStub(), - CreateBlockDigestGeneratorStub(), + profileLog, + NStorage::CreateBlockDigestGeneratorFactory(), CreateTraceSerializer( CreateLoggingService("console"), "BLOCKSTORE_TRACE", diff --git a/cloud/blockstore/libs/storage/volume/testlib/test_env.h b/cloud/blockstore/libs/storage/volume/testlib/test_env.h index cccff0a714f..d0a5cd6316b 100644 --- a/cloud/blockstore/libs/storage/volume/testlib/test_env.h +++ b/cloud/blockstore/libs/storage/volume/testlib/test_env.h @@ -598,7 +598,8 @@ std::unique_ptr PrepareTestActorRuntime( NProto::TFeaturesConfig featuresConfig = {}, NCloud::NStorage::NRdma::IClientPtr rdmaClient = {}, TVector diskAgentStates = {}, - bool debugActorRegistration = false); + bool debugActorRegistration = false, + IProfileLogPtr profileLog = nullptr); struct TTestRuntimeBuilder { diff --git a/cloud/blockstore/libs/storage/volume/volume.cpp b/cloud/blockstore/libs/storage/volume/volume.cpp index 55f5c6f79b0..6315c27b6db 100644 --- a/cloud/blockstore/libs/storage/volume/volume.cpp +++ b/cloud/blockstore/libs/storage/volume/volume.cpp @@ -16,7 +16,7 @@ IActorPtr CreateVolumeTablet( TStorageConfigPtr config, TDiagnosticsConfigPtr diagnosticsConfig, IProfileLogPtr profileLog, - IBlockDigestGeneratorPtr blockDigestGenerator, + IBlockDigestGeneratorFactoryPtr blockDigestGeneratorFactory, ITraceSerializerPtr traceSerializer, NCloud::NStorage::NRdma::IClientPtr rdmaClient, TPartitionBudgetManagerPtr partitionBudgetManager, @@ -30,7 +30,7 @@ IActorPtr CreateVolumeTablet( std::move(config), std::move(diagnosticsConfig), std::move(profileLog), - std::move(blockDigestGenerator), + std::move(blockDigestGeneratorFactory), std::move(traceSerializer), std::move(rdmaClient), std::move(partitionBudgetManager), diff --git a/cloud/blockstore/libs/storage/volume/volume.h b/cloud/blockstore/libs/storage/volume/volume.h index 5b512c801c5..aa1ce818744 100644 --- a/cloud/blockstore/libs/storage/volume/volume.h +++ b/cloud/blockstore/libs/storage/volume/volume.h @@ -29,7 +29,7 @@ NActors::IActorPtr CreateVolumeTablet( TStorageConfigPtr config, TDiagnosticsConfigPtr diagnosticsConfig, IProfileLogPtr profileLog, - IBlockDigestGeneratorPtr blockDigestGenerator, + IBlockDigestGeneratorFactoryPtr blockDigestGeneratorFactory, ITraceSerializerPtr traceSerializer, NCloud::NStorage::NRdma::IClientPtr rdmaClient, TPartitionBudgetManagerPtr partitionBudgetManager, diff --git a/cloud/blockstore/libs/storage/volume/volume_actor.cpp b/cloud/blockstore/libs/storage/volume/volume_actor.cpp index 1de3e95055e..60f42690435 100644 --- a/cloud/blockstore/libs/storage/volume/volume_actor.cpp +++ b/cloud/blockstore/libs/storage/volume/volume_actor.cpp @@ -91,7 +91,7 @@ TVolumeActor::TVolumeActor( TStorageConfigPtr config, TDiagnosticsConfigPtr diagnosticsConfig, IProfileLogPtr profileLog, - IBlockDigestGeneratorPtr blockDigestGenerator, + IBlockDigestGeneratorFactoryPtr blockDigestGeneratorFactory, ITraceSerializerPtr traceSerializer, NCloud::NStorage::NRdma::IClientPtr rdmaClient, TPartitionBudgetManagerPtr partitionBudgetManager, @@ -104,7 +104,7 @@ TVolumeActor::TVolumeActor( , Config(std::move(config)) , DiagnosticsConfig(std::move(diagnosticsConfig)) , ProfileLog(std::move(profileLog)) - , BlockDigestGenerator(std::move(blockDigestGenerator)) + , BlockDigestGeneratorFactory(std::move(blockDigestGeneratorFactory)) , TraceSerializer(std::move(traceSerializer)) , RdmaClient(std::move(rdmaClient)) , PartitionBudgetManager(std::move(partitionBudgetManager)) diff --git a/cloud/blockstore/libs/storage/volume/volume_actor.h b/cloud/blockstore/libs/storage/volume/volume_actor.h index eedadb5424a..d12adcfb7b6 100644 --- a/cloud/blockstore/libs/storage/volume/volume_actor.h +++ b/cloud/blockstore/libs/storage/volume/volume_actor.h @@ -211,12 +211,14 @@ class TVolumeActor final bool HasPerformanceProfileModifications = false; const TDiagnosticsConfigPtr DiagnosticsConfig; const IProfileLogPtr ProfileLog; - const IBlockDigestGeneratorPtr BlockDigestGenerator; + const IBlockDigestGeneratorFactoryPtr BlockDigestGeneratorFactory; const ITraceSerializerPtr TraceSerializer; const NCloud::NStorage::NRdma::IClientPtr RdmaClient; const TPartitionBudgetManagerPtr PartitionBudgetManager; NServer::IEndpointEventHandlerPtr EndpointEventHandler; const EVolumeStartMode StartMode; + + IBlockDigestGeneratorPtr BlockDigestGenerator; TLogTitle LogTitle; TVolumeThrottlerLogger ThrottlerLogger; @@ -477,7 +479,7 @@ class TVolumeActor final TStorageConfigPtr config, TDiagnosticsConfigPtr diagnosticsConfig, IProfileLogPtr profileLog, - IBlockDigestGeneratorPtr blockDigestGenerator, + IBlockDigestGeneratorFactoryPtr blockDigestGeneratorFactory, ITraceSerializerPtr traceSerializer, NCloud::NStorage::NRdma::IClientPtr rdmaClient, TPartitionBudgetManagerPtr partitionBudgetManager, diff --git a/cloud/blockstore/libs/storage/volume/volume_actor_change_storage_config.cpp b/cloud/blockstore/libs/storage/volume/volume_actor_change_storage_config.cpp index 5b03a5bc30b..1930201fba1 100644 --- a/cloud/blockstore/libs/storage/volume/volume_actor_change_storage_config.cpp +++ b/cloud/blockstore/libs/storage/volume/volume_actor_change_storage_config.cpp @@ -2,6 +2,8 @@ #include "volume_database.h" +#include + namespace NCloud::NBlockStore::NStorage { using namespace NActors; @@ -58,6 +60,10 @@ void TVolumeActor::CompleteChangeStorageConfig( TStorageConfig::Merge(GlobalStorageConfig, args.ResultStorageConfig); HasStorageConfigPatch = Config != GlobalStorageConfig; + // Recreate BlockDigestGenerator with the updated configuration + BlockDigestGenerator = + BlockDigestGeneratorFactory->CreateBlockDigestGenerator(*Config); + if (State->GetPartitionsState() == TPartitionInfo::READY || State->GetPartitionsState() == TPartitionInfo::STARTED) { diff --git a/cloud/blockstore/libs/storage/volume/volume_actor_loadstate.cpp b/cloud/blockstore/libs/storage/volume/volume_actor_loadstate.cpp index 771396e9a0a..2f3572b0eca 100644 --- a/cloud/blockstore/libs/storage/volume/volume_actor_loadstate.cpp +++ b/cloud/blockstore/libs/storage/volume/volume_actor_loadstate.cpp @@ -2,6 +2,7 @@ #include "volume_database.h" +#include #include #include @@ -112,6 +113,10 @@ void TVolumeActor::CompleteLoadState( HasStorageConfigPatch = Config != GlobalStorageConfig; } + // Create BlockDigestGenerator using the effective storage configuration + BlockDigestGenerator = + BlockDigestGeneratorFactory->CreateBlockDigestGenerator(*Config); + if (args.Meta.Defined()) { const auto throttlerInfo = args.ThrottlerStateInfo.GetOrElse( TVolumeDatabase::TThrottlerStateInfo{ diff --git a/cloud/blockstore/libs/storage/volume/volume_ut.cpp b/cloud/blockstore/libs/storage/volume/volume_ut.cpp index 095ed8fbdf6..9569e705af4 100644 --- a/cloud/blockstore/libs/storage/volume/volume_ut.cpp +++ b/cloud/blockstore/libs/storage/volume/volume_ut.cpp @@ -13,6 +13,7 @@ #include #include +#include namespace NCloud::NBlockStore::NStorage { @@ -62,6 +63,35 @@ IOutputStream& operator<<(IOutputStream& out, ETransferMethod rhs) //////////////////////////////////////////////////////////////////////////////// +class TTestProfileLog final: public IProfileLog +{ +private: + TLockFreeQueue& Queue; + +public: + explicit TTestProfileLog(TLockFreeQueue& queue) + : Queue(queue) + {} + + void Start() final + {} + + void Stop() final + {} + + void Write(TRecord record) final + { + Queue.Enqueue(std::move(record)); + } + + bool Flush() final + { + return true; + } +}; + +//////////////////////////////////////////////////////////////////////////////// + Y_UNIT_TEST_SUITE(TVolumeTest) { Y_UNIT_TEST(ShouldUpdateVolumeConfig) @@ -11377,6 +11407,92 @@ Y_UNIT_TEST_SUITE(TVolumeTest) UNIT_ASSERT(deadActors.contains(firstFollower)); } + + Y_UNIT_TEST(ShouldOverrideBlockDigestGenerator) + { + TLockFreeQueue recordsQueue; + + auto runtime = PrepareTestActorRuntime( + {}, // storageServiceConfig + {}, // diskRegistryState + {}, // featuresConfig + {}, // rdmaClient + {}, // diskAgentStates + false, // debugActorRegistration + std::make_shared(recordsQueue)); + + TVolumeClient volume(*runtime); + volume.UpdateVolumeConfig(); + + volume.WaitReady(); + + auto clientInfo = CreateVolumeClientInfo( + NProto::VOLUME_ACCESS_READ_WRITE, + NProto::VOLUME_MOUNT_LOCAL, + 0); + volume.AddClient(clientInfo); + + { + NProto::TStorageServiceConfig patch; + patch.SetBlockDigestsEnabled(true); + volume.ChangeStorageConfig(std::move(patch)); + } + + volume.WriteBlocksLocal( + TBlockRange64::MakeOneBlock(1), + clientInfo.GetClientId(), + GetBlockContent(1)); + + volume.WriteBlocksLocal( + TBlockRange64::MakeOneBlock(2), + clientInfo.GetClientId(), + GetBlockContent(2)); + + TVector records; + + runtime->DispatchEvents( + { + .CustomFinalCondition = + [&] + { + recordsQueue.DequeueAll(&records); + return records.size() == 2; + }, + }, + TDuration::Seconds(15)); + + UNIT_ASSERT_VALUES_EQUAL(2, records.size()); + + { + const auto& record = records[0]; + UNIT_ASSERT_VALUES_EQUAL("vol0", record.DiskId); + auto* req = std::get_if( + &record.Request); + UNIT_ASSERT_C(req, record.Request.index()); + UNIT_ASSERT_VALUES_EQUAL( + EBlockStoreRequest::WriteBlocks, + req->RequestType); + UNIT_ASSERT_VALUES_EQUAL(1, req->BlockInfos.size()); + + UNIT_ASSERT_VALUES_EQUAL(1, req->BlockInfos[0].BlockIndex); + UNIT_ASSERT_VALUES_UNEQUAL(0, req->BlockInfos[0].Checksum); + } + + { + const auto& record = records[1]; + UNIT_ASSERT_VALUES_EQUAL("vol0", record.DiskId); + auto* req = std::get_if( + &record.Request); + UNIT_ASSERT_C(req, record.Request.index()); + UNIT_ASSERT_VALUES_EQUAL( + EBlockStoreRequest::WriteBlocks, + req->RequestType); + UNIT_ASSERT_VALUES_EQUAL(1, req->BlockInfos.size()); + + UNIT_ASSERT_VALUES_EQUAL(2, req->BlockInfos[0].BlockIndex); + UNIT_ASSERT_VALUES_UNEQUAL(0, req->BlockInfos[0].Checksum); + } + } } } // namespace NCloud::NBlockStore::NStorage