diff --git a/cloud/blockstore/config/disk.proto b/cloud/blockstore/config/disk.proto index a1da4c78308..85357954f28 100644 --- a/cloud/blockstore/config/disk.proto +++ b/cloud/blockstore/config/disk.proto @@ -251,6 +251,13 @@ message TDiskAgentConfig // Max. count of concurrently processing operations (io_setup). optional uint32 MaxAIOContextEvents = 33; + + // Number of paths per each FileIOService. + // 0 means that only one IO service will be created. + // 1 means that one IO service per file path will be created. + // 2 means that one IO service will be created for every two file paths. + // etc. + optional uint32 PathsPerFileIOService = 34; } //////////////////////////////////////////////////////////////////////////////// diff --git a/cloud/blockstore/libs/daemon/common/bootstrap.cpp b/cloud/blockstore/libs/daemon/common/bootstrap.cpp index 959edc2a701..47818fb1877 100644 --- a/cloud/blockstore/libs/daemon/common/bootstrap.cpp +++ b/cloud/blockstore/libs/daemon/common/bootstrap.cpp @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -737,7 +738,8 @@ void TBootstrapBase::InitLocalService() ? *Configs->ServerConfig->GetLocalServiceConfig() : NProto::TLocalServiceConfig(); - FileIOService = CreateAIOService(); + FileIOServiceProvider = + CreateSingleFileIOServiceProvider(CreateAIOService()); NvmeManager = CreateNvmeManager( Configs->DiskAgentConfig->GetSecureEraseTimeout()); @@ -746,7 +748,7 @@ void TBootstrapBase::InitLocalService() config, DiscoveryService, CreateAioStorageProvider( - FileIOService, + FileIOServiceProvider, NvmeManager, false, // directIO EAioSubmitQueueOpt::DontUse @@ -866,7 +868,7 @@ void TBootstrapBase::Start() START_KIKIMR_COMPONENT(StatsUploader); START_COMMON_COMPONENT(Spdk); START_KIKIMR_COMPONENT(ActorSystem); - START_COMMON_COMPONENT(FileIOService); + START_COMMON_COMPONENT(FileIOServiceProvider); START_COMMON_COMPONENT(EndpointProxyClient); START_COMMON_COMPONENT(EndpointManager); START_COMMON_COMPONENT(Service); @@ -936,7 +938,7 @@ void TBootstrapBase::Stop() STOP_COMMON_COMPONENT(Service); STOP_COMMON_COMPONENT(EndpointManager); STOP_COMMON_COMPONENT(EndpointProxyClient); - STOP_COMMON_COMPONENT(FileIOService); + STOP_COMMON_COMPONENT(FileIOServiceProvider); STOP_KIKIMR_COMPONENT(ActorSystem); STOP_COMMON_COMPONENT(Spdk); STOP_KIKIMR_COMPONENT(StatsUploader); diff --git a/cloud/blockstore/libs/daemon/common/bootstrap.h b/cloud/blockstore/libs/daemon/common/bootstrap.h index 8d66e06647e..d5cb4074f99 100644 --- a/cloud/blockstore/libs/daemon/common/bootstrap.h +++ b/cloud/blockstore/libs/daemon/common/bootstrap.h @@ -61,7 +61,7 @@ class TBootstrapBase NVhost::IServerPtr VhostServer; NVhost::TVhostCallbacks VhostCallbacks; NBD::IServerPtr NbdServer; - IFileIOServicePtr FileIOService; + IFileIOServiceProviderPtr FileIOServiceProvider; IStorageProviderPtr StorageProvider; IKmsKeyProviderPtr KmsKeyProvider; IRootKmsKeyProviderPtr RootKmsKeyProvider; diff --git a/cloud/blockstore/libs/daemon/ydb/bootstrap.cpp b/cloud/blockstore/libs/daemon/ydb/bootstrap.cpp index eac661418eb..edf0840a005 100644 --- a/cloud/blockstore/libs/daemon/ydb/bootstrap.cpp +++ b/cloud/blockstore/libs/daemon/ydb/bootstrap.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -433,23 +434,30 @@ void TBootstrapYdb::InitKikimrService() InitSpdk(); - FileIOService = CreateAIOService(); - - if (Configs->DiskAgentConfig->GetEnabled() && - Configs->DiskAgentConfig->GetBackend() == NProto::DISK_AGENT_BACKEND_AIO && + if (const auto& config = *Configs->DiskAgentConfig; + config.GetEnabled() && + config.GetBackend() == NProto::DISK_AGENT_BACKEND_AIO && !AioStorageProvider) { - Y_ABORT_UNLESS(FileIOService); - NvmeManager = CreateNvmeManager( Configs->DiskAgentConfig->GetSecureEraseTimeout()); + auto factory = [events = config.GetMaxAIOContextEvents()] { + return CreateAIOService(events); + }; + + FileIOServiceProvider = + config.GetPathsPerFileIOService() + ? CreateFileIOServiceProvider( + config.GetPathsPerFileIOService(), + factory) + : CreateSingleFileIOServiceProvider(factory()); + AioStorageProvider = CreateAioStorageProvider( - FileIOService, + FileIOServiceProvider, NvmeManager, - !Configs->DiskAgentConfig->GetDirectIoFlagDisabled(), - EAioSubmitQueueOpt::DontUse - ); + !config.GetDirectIoFlagDisabled(), + EAioSubmitQueueOpt::DontUse); STORAGE_INFO("AioStorageProvider initialized"); } @@ -465,8 +473,6 @@ void TBootstrapYdb::InitKikimrService() STORAGE_INFO("AioStorageProvider (null) initialized"); } - Y_ABORT_UNLESS(FileIOService); - Allocator = CreateCachingAllocator( Spdk ? Spdk->GetAllocator() : TDefaultAllocator::Instance(), Configs->DiskAgentConfig->GetPageSize(), @@ -534,7 +540,6 @@ void TBootstrapYdb::InitKikimrService() args.DiscoveryService = DiscoveryService; args.Spdk = Spdk; args.Allocator = Allocator; - args.FileIOService = FileIOService; args.AioStorageProvider = AioStorageProvider; args.ProfileLog = ProfileLog; args.BlockDigestGenerator = BlockDigestGenerator; diff --git a/cloud/blockstore/libs/disk_agent/bootstrap.cpp b/cloud/blockstore/libs/disk_agent/bootstrap.cpp index 2df8457fb0a..54716d7416d 100644 --- a/cloud/blockstore/libs/disk_agent/bootstrap.cpp +++ b/cloud/blockstore/libs/disk_agent/bootstrap.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -428,13 +429,22 @@ bool TBootstrap::InitKikimrService() break; } - case NProto::DISK_AGENT_BACKEND_AIO: - FileIOService = - CreateAIOService(config.GetMaxAIOContextEvents()); + case NProto::DISK_AGENT_BACKEND_AIO: { NvmeManager = CreateNvmeManager(config.GetSecureEraseTimeout()); + auto factory = [events = config.GetMaxAIOContextEvents()] { + return CreateAIOService(events); + }; + + FileIOServiceProvider = + config.GetPathsPerFileIOService() + ? CreateFileIOServiceProvider( + config.GetPathsPerFileIOService(), + factory) + : CreateSingleFileIOServiceProvider(factory()); + AioStorageProvider = CreateAioStorageProvider( - FileIOService, + FileIOServiceProvider, NvmeManager, !config.GetDirectIoFlagDisabled(), EAioSubmitQueueOpt::Use @@ -442,6 +452,7 @@ bool TBootstrap::InitKikimrService() STORAGE_INFO("Aio backend initialized"); break; + } case NProto::DISK_AGENT_BACKEND_NULL: NvmeManager = CreateNvmeManager(config.GetSecureEraseTimeout()); AioStorageProvider = CreateNullStorageProvider(); @@ -487,7 +498,6 @@ bool TBootstrap::InitKikimrService() args.AsyncLogger = AsyncLogger; args.Spdk = Spdk; args.Allocator = Allocator; - args.FileIOService = FileIOService; args.AioStorageProvider = AioStorageProvider; args.ProfileLog = ProfileLog; args.BlockDigestGenerator = BlockDigestGenerator; @@ -604,7 +614,7 @@ void TBootstrap::Start() START_COMPONENT(TraceProcessor); START_COMPONENT(Spdk); START_COMPONENT(RdmaServer); - START_COMPONENT(FileIOService); + START_COMPONENT(FileIOServiceProvider); START_COMPONENT(ActorSystem); // we need to start scheduler after all other components for 2 reasons: @@ -642,9 +652,9 @@ void TBootstrap::Stop() STOP_COMPONENT(Scheduler); STOP_COMPONENT(ActorSystem); - // stop FileIOService after ActorSystem to ensure that there are no + // stop FileIOServiceProvider after ActorSystem to ensure that there are no // in-flight I/O requests from TDiskAgentActor - STOP_COMPONENT(FileIOService); + STOP_COMPONENT(FileIOServiceProvider); STOP_COMPONENT(Spdk); STOP_COMPONENT(RdmaServer); diff --git a/cloud/blockstore/libs/disk_agent/bootstrap.h b/cloud/blockstore/libs/disk_agent/bootstrap.h index 3fd09906c0d..272e8f938f0 100644 --- a/cloud/blockstore/libs/disk_agent/bootstrap.h +++ b/cloud/blockstore/libs/disk_agent/bootstrap.h @@ -64,7 +64,7 @@ class TBootstrap ITraceProcessorPtr TraceProcessor; IProfileLogPtr ProfileLog; IBlockDigestGeneratorPtr BlockDigestGenerator; - IFileIOServicePtr FileIOService; + IFileIOServiceProviderPtr FileIOServiceProvider; NSpdk::ISpdkEnvPtr Spdk; std::function SpdkLogInitializer; ICachingAllocatorPtr Allocator; diff --git a/cloud/blockstore/libs/service_local/CMakeLists.darwin-x86_64.txt b/cloud/blockstore/libs/service_local/CMakeLists.darwin-x86_64.txt index ffd93da2cb0..d6ffcafa288 100644 --- a/cloud/blockstore/libs/service_local/CMakeLists.darwin-x86_64.txt +++ b/cloud/blockstore/libs/service_local/CMakeLists.darwin-x86_64.txt @@ -29,6 +29,7 @@ target_link_libraries(blockstore-libs-service_local PUBLIC target_sources(blockstore-libs-service_local PRIVATE ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/broken_storage.cpp ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/compound_storage.cpp + ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/file_io_service_provider.cpp ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/rdma_protocol.cpp ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/service_local.cpp ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/storage_aio.cpp diff --git a/cloud/blockstore/libs/service_local/CMakeLists.linux-aarch64.txt b/cloud/blockstore/libs/service_local/CMakeLists.linux-aarch64.txt index 701f76182e3..5b997e701a3 100644 --- a/cloud/blockstore/libs/service_local/CMakeLists.linux-aarch64.txt +++ b/cloud/blockstore/libs/service_local/CMakeLists.linux-aarch64.txt @@ -30,6 +30,7 @@ target_link_libraries(blockstore-libs-service_local PUBLIC target_sources(blockstore-libs-service_local PRIVATE ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/broken_storage.cpp ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/compound_storage.cpp + ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/file_io_service_provider.cpp ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/rdma_protocol.cpp ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/service_local.cpp ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/storage_aio.cpp diff --git a/cloud/blockstore/libs/service_local/CMakeLists.linux-x86_64.txt b/cloud/blockstore/libs/service_local/CMakeLists.linux-x86_64.txt index 701f76182e3..5b997e701a3 100644 --- a/cloud/blockstore/libs/service_local/CMakeLists.linux-x86_64.txt +++ b/cloud/blockstore/libs/service_local/CMakeLists.linux-x86_64.txt @@ -30,6 +30,7 @@ target_link_libraries(blockstore-libs-service_local PUBLIC target_sources(blockstore-libs-service_local PRIVATE ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/broken_storage.cpp ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/compound_storage.cpp + ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/file_io_service_provider.cpp ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/rdma_protocol.cpp ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/service_local.cpp ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/storage_aio.cpp diff --git a/cloud/blockstore/libs/service_local/CMakeLists.windows-x86_64.txt b/cloud/blockstore/libs/service_local/CMakeLists.windows-x86_64.txt index ffd93da2cb0..d6ffcafa288 100644 --- a/cloud/blockstore/libs/service_local/CMakeLists.windows-x86_64.txt +++ b/cloud/blockstore/libs/service_local/CMakeLists.windows-x86_64.txt @@ -29,6 +29,7 @@ target_link_libraries(blockstore-libs-service_local PUBLIC target_sources(blockstore-libs-service_local PRIVATE ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/broken_storage.cpp ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/compound_storage.cpp + ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/file_io_service_provider.cpp ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/rdma_protocol.cpp ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/service_local.cpp ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/storage_aio.cpp diff --git a/cloud/blockstore/libs/service_local/file_io_service_provider.cpp b/cloud/blockstore/libs/service_local/file_io_service_provider.cpp new file mode 100644 index 00000000000..9f681b49892 --- /dev/null +++ b/cloud/blockstore/libs/service_local/file_io_service_provider.cpp @@ -0,0 +1,114 @@ +#include "file_io_service_provider.h" + +#include + +#include +#include +#include + +namespace NCloud::NBlockStore::NServer { + +namespace { + +//////////////////////////////////////////////////////////////////////////////// + +class TFileIOServiceProvider final + : public IFileIOServiceProvider +{ +private: + const ui32 PathsPerServices; + std::function Factory; + + TVector> PathToFileIOIndex; + TVector FileIOs; + +public: + explicit TFileIOServiceProvider( + ui32 pathsPerServices, + std::function factory) + : PathsPerServices{Max(pathsPerServices, 1U)} + , Factory(std::move(factory)) + {} + + void Start() override + {} + + void Stop() override + { + for (auto& fileIO: FileIOs) { + fileIO->Stop(); + } + } + + IFileIOServicePtr CreateFileIOService(TStringBuf filePath) override + { + if (auto* p = FindIfPtr( + PathToFileIOIndex, + [=](const auto& p) { return p.first == filePath; })) + { + return FileIOs[p->second]; + } + + if (PathToFileIOIndex.size() + 1 > PathsPerServices * FileIOs.size()) { + auto service = Factory(); + Y_DEBUG_ABORT_UNLESS(service); + service->Start(); + FileIOs.push_back(service); + } + + PathToFileIOIndex.emplace_back(filePath, FileIOs.size() - 1); + + return FileIOs.back(); + } +}; + +//////////////////////////////////////////////////////////////////////////////// + +struct TSingleFileIOServiceProvider final + : IFileIOServiceProvider +{ + IFileIOServicePtr FileIO; + + explicit TSingleFileIOServiceProvider( + IFileIOServicePtr fileIO) + : FileIO{std::move(fileIO)} + {} + + void Start() override + { + FileIO->Start(); + } + + void Stop() override + { + FileIO->Stop(); + } + + IFileIOServicePtr CreateFileIOService(TStringBuf filePath) override + { + Y_UNUSED(filePath); + + return FileIO; + } +}; + +} // namespace + +//////////////////////////////////////////////////////////////////////////////// + +IFileIOServiceProviderPtr CreateSingleFileIOServiceProvider( + IFileIOServicePtr fileIO) +{ + return std::make_shared(std::move(fileIO)); +} + +IFileIOServiceProviderPtr CreateFileIOServiceProvider( + ui32 filePathsPerServices, + std::function factory) +{ + return std::make_shared( + filePathsPerServices, + std::move(factory)); +} + +} // namespace NCloud::NBlockStore::NServer diff --git a/cloud/blockstore/libs/service_local/file_io_service_provider.h b/cloud/blockstore/libs/service_local/file_io_service_provider.h new file mode 100644 index 00000000000..2f2f6c8f50c --- /dev/null +++ b/cloud/blockstore/libs/service_local/file_io_service_provider.h @@ -0,0 +1,31 @@ +#pragma once + +#include "public.h" + +#include +#include + +#include + +#include + +namespace NCloud::NBlockStore::NServer { + +//////////////////////////////////////////////////////////////////////////////// + +struct IFileIOServiceProvider + : IStartable +{ + virtual IFileIOServicePtr CreateFileIOService(TStringBuf filePath) = 0; +}; + +//////////////////////////////////////////////////////////////////////////////// + +IFileIOServiceProviderPtr CreateSingleFileIOServiceProvider( + IFileIOServicePtr fileIO); + +IFileIOServiceProviderPtr CreateFileIOServiceProvider( + ui32 filePathsPerServices, + std::function factory); + +} // namespace NCloud::NBlockStore::NServer diff --git a/cloud/blockstore/libs/service_local/file_io_service_provider_ut.cpp b/cloud/blockstore/libs/service_local/file_io_service_provider_ut.cpp new file mode 100644 index 00000000000..691118820ef --- /dev/null +++ b/cloud/blockstore/libs/service_local/file_io_service_provider_ut.cpp @@ -0,0 +1,271 @@ +#include "file_io_service_provider.h" + +#include + +#include + +namespace NCloud::NBlockStore::NServer { + +namespace { + +//////////////////////////////////////////////////////////////////////////////// + +struct TTestFileIOService + : IFileIOService +{ + int Started = 0; + int Stopped = 0; + + void Start() override + { + ++Started; + } + + void Stop() override + { + ++Stopped; + } + + void AsyncRead( + TFileHandle& file, + i64 offset, + TArrayRef buffer, + TFileIOCompletion* completion) override + { + Y_UNUSED(file); + Y_UNUSED(offset); + Y_UNUSED(buffer); + Y_UNUSED(completion); + } + + void AsyncWrite( + TFileHandle& file, + i64 offset, + TArrayRef buffer, + TFileIOCompletion* completion) override + { + Y_UNUSED(file); + Y_UNUSED(offset); + Y_UNUSED(buffer); + Y_UNUSED(completion); + } +}; + +//////////////////////////////////////////////////////////////////////////////// + +struct TTestProvider + : IFileIOServiceProvider +{ + int Started = 0; + int Stopped = 0; + + TVector> FileIOs; + + void Start() override + { + ++Started; + } + + void Stop() override + { + ++Stopped; + + for (auto& s: FileIOs) { + s->Stop(); + } + } + + IFileIOServicePtr CreateFileIOService(TStringBuf filePath) override + { + Y_UNUSED(filePath); + + auto service = std::make_shared(); + + FileIOs.push_back(service); + + return service; + } +}; + +} // namespace + +//////////////////////////////////////////////////////////////////////////////// + +Y_UNIT_TEST_SUITE(TFileIOServiceProviderTest) +{ + Y_UNIT_TEST(ShouldCreateSingleFileIOService) + { + auto fileIO = std::make_shared(); + UNIT_ASSERT_VALUES_EQUAL(0, fileIO->Started); + + auto provider = CreateSingleFileIOServiceProvider(fileIO); + provider->Start(); + + UNIT_ASSERT_VALUES_EQUAL(1, fileIO->Started); + + auto io1 = provider->CreateFileIOService("foo"); + UNIT_ASSERT(io1 == fileIO); + UNIT_ASSERT_VALUES_EQUAL(1, fileIO->Started); + + auto io2 = provider->CreateFileIOService("bar"); + UNIT_ASSERT(io2 == fileIO); + auto io3 = provider->CreateFileIOService("foo"); + UNIT_ASSERT(io3 == fileIO); + auto io4 = provider->CreateFileIOService("buz"); + UNIT_ASSERT(io4 == fileIO); + + UNIT_ASSERT_VALUES_EQUAL(1, fileIO->Started); + UNIT_ASSERT_VALUES_EQUAL(0, fileIO->Stopped); + + provider->Stop(); + UNIT_ASSERT_VALUES_EQUAL(1, fileIO->Stopped); + } + + void ShouldCreateOneServicePerOnePathImpl(ui32 pathsToServices) + { + UNIT_ASSERT(pathsToServices <= 1); + + TTestProvider upstream; + + auto provider = CreateFileIOServiceProvider( + pathsToServices, + [&] { return upstream.CreateFileIOService({}); }); + + provider->Start(); + + UNIT_ASSERT_VALUES_EQUAL(0, upstream.FileIOs.size()); + + auto io1 = provider->CreateFileIOService("p1"); + UNIT_ASSERT_VALUES_EQUAL(1, upstream.FileIOs.size()); + UNIT_ASSERT(io1 == upstream.FileIOs[0]); + UNIT_ASSERT_VALUES_EQUAL(1, upstream.FileIOs[0]->Started); + + auto io2 = provider->CreateFileIOService("p2"); + UNIT_ASSERT_VALUES_EQUAL(2, upstream.FileIOs.size()); + UNIT_ASSERT_VALUES_EQUAL(1, upstream.FileIOs[0]->Started); + UNIT_ASSERT_VALUES_EQUAL(1, upstream.FileIOs[1]->Started); + UNIT_ASSERT(io2 == upstream.FileIOs[1]); + UNIT_ASSERT(io1 != io2); + + auto io3 = provider->CreateFileIOService("p3"); + UNIT_ASSERT_VALUES_EQUAL(3, upstream.FileIOs.size()); + UNIT_ASSERT(io2 != io3); + + auto io4 = provider->CreateFileIOService("p4"); + UNIT_ASSERT_VALUES_EQUAL(4, upstream.FileIOs.size()); + UNIT_ASSERT(io3 != io4); + + auto io5 = provider->CreateFileIOService("p1"); + UNIT_ASSERT_VALUES_EQUAL(4, upstream.FileIOs.size()); + UNIT_ASSERT(io1 == io5); + + auto io6 = provider->CreateFileIOService("p4"); + UNIT_ASSERT_VALUES_EQUAL(4, upstream.FileIOs.size()); + UNIT_ASSERT(io4 == io6); + + provider->Stop(); + for (const auto& s: upstream.FileIOs) { + UNIT_ASSERT_VALUES_EQUAL(1, s->Started); + UNIT_ASSERT_VALUES_EQUAL(1, s->Stopped); + } + } + + Y_UNIT_TEST(ShouldCreateOneServicePerOnePath) + { + ShouldCreateOneServicePerOnePathImpl(0); + ShouldCreateOneServicePerOnePathImpl(1); + } + + Y_UNIT_TEST(ShouldCreateOneServicePerTwoPaths) + { + const ui32 pathsToServices = 2; + + TTestProvider upstream; + + auto provider = CreateFileIOServiceProvider( + pathsToServices, + [&] { return upstream.CreateFileIOService({}); }); + + provider->Start(); + + UNIT_ASSERT_VALUES_EQUAL(0, upstream.FileIOs.size()); + + auto io1 = provider->CreateFileIOService("p1"); + UNIT_ASSERT_VALUES_EQUAL(1, upstream.FileIOs.size()); + UNIT_ASSERT(io1); + + auto io2 = provider->CreateFileIOService("p2"); + UNIT_ASSERT_VALUES_EQUAL(1, upstream.FileIOs.size()); + UNIT_ASSERT(io1 == io2); + + auto io3 = provider->CreateFileIOService("p3"); + UNIT_ASSERT_VALUES_EQUAL(2, upstream.FileIOs.size()); + + auto io4 = provider->CreateFileIOService("p4"); + UNIT_ASSERT_VALUES_EQUAL(2, upstream.FileIOs.size()); + + UNIT_ASSERT(io3 == io4); + UNIT_ASSERT(io1 != io4); + + auto io5 = provider->CreateFileIOService("p1"); + UNIT_ASSERT_VALUES_EQUAL(2, upstream.FileIOs.size()); + UNIT_ASSERT(io1 == io5); + + auto io6 = provider->CreateFileIOService("p6"); + UNIT_ASSERT_VALUES_EQUAL(3, upstream.FileIOs.size()); + UNIT_ASSERT(io1 != io6); + UNIT_ASSERT(io3 != io6); + + auto io7 = provider->CreateFileIOService("p6"); + UNIT_ASSERT_VALUES_EQUAL(3, upstream.FileIOs.size()); + UNIT_ASSERT(io6 == io7); + + provider->Stop(); + for (const auto& s: upstream.FileIOs) { + UNIT_ASSERT_VALUES_EQUAL(1, s->Started); + UNIT_ASSERT_VALUES_EQUAL(1, s->Stopped); + } + } + + Y_UNIT_TEST(ShouldCreateOneServicePerFourPaths) + { + const ui32 pathsToServices = 4; + const ui32 devicesPerPath = 64; + const ui32 pathCount = 6; + const ui32 expectedServiceCount = 2; + + TTestProvider upstream; + + auto provider = CreateFileIOServiceProvider( + pathsToServices, + [&] { return upstream.CreateFileIOService({}); }); + + provider->Start(); + + for (ui32 i = 0; i != pathCount; ++i) { + const TString path = + "/dev/disk/by-partlabel/NVMENBS0" + ToString(i); + + for (ui32 j = 0; j != devicesPerPath; ++j) { + auto fileIO = provider->CreateFileIOService(path); + UNIT_ASSERT(fileIO == upstream.FileIOs.back()); + } + } + + UNIT_ASSERT_VALUES_EQUAL(expectedServiceCount, upstream.FileIOs.size()); + + for (const auto& s: upstream.FileIOs) { + UNIT_ASSERT_VALUES_EQUAL(1, s->Started); + UNIT_ASSERT_VALUES_EQUAL(0, s->Stopped); + } + + provider->Stop(); + + for (const auto& s: upstream.FileIOs) { + UNIT_ASSERT_VALUES_EQUAL(1, s->Started); + UNIT_ASSERT_VALUES_EQUAL(1, s->Stopped); + } + } +} + +} // namespace NCloud::NBlockStore::NServer diff --git a/cloud/blockstore/libs/service_local/public.h b/cloud/blockstore/libs/service_local/public.h index 13db8e64b97..651550c9ac8 100644 --- a/cloud/blockstore/libs/service_local/public.h +++ b/cloud/blockstore/libs/service_local/public.h @@ -8,4 +8,13 @@ namespace NProto { class TLocalServiceConfig; } // namespace NProto +namespace NServer { + +//////////////////////////////////////////////////////////////////////////////// + +struct IFileIOServiceProvider; +using IFileIOServiceProviderPtr = std::shared_ptr; + +} // namespace NServer + } // namespace NCloud::NBlockStore diff --git a/cloud/blockstore/libs/service_local/storage_aio.cpp b/cloud/blockstore/libs/service_local/storage_aio.cpp index d87ef9706bf..f2401c66225 100644 --- a/cloud/blockstore/libs/service_local/storage_aio.cpp +++ b/cloud/blockstore/libs/service_local/storage_aio.cpp @@ -1,5 +1,7 @@ #include "storage_aio.h" +#include "file_io_service_provider.h" + #include #include #include @@ -882,7 +884,7 @@ class TSafeDeallocator const NProto::TError& error, ui32 bytes) { - auto checker = static_cast(completion); + auto* checker = static_cast(completion); checker->ReadBlockComplete(error, bytes); } }; @@ -916,18 +918,18 @@ class TAioStorageProvider final { private: ITaskQueuePtr SubmitQueue; - IFileIOServicePtr FileIOService; + IFileIOServiceProviderPtr FileIOServiceProvider; INvmeManagerPtr NvmeManager; const bool DirectIO; public: explicit TAioStorageProvider( ITaskQueuePtr submitQueue, - IFileIOServicePtr fileIO, + IFileIOServiceProviderPtr fileIOProvider, INvmeManagerPtr nvmeManager, bool directIO) : SubmitQueue(std::move(submitQueue)) - , FileIOService(std::move(fileIO)) + , FileIOServiceProvider(std::move(fileIOProvider)) , NvmeManager(std::move(nvmeManager)) , DirectIO(directIO) {} @@ -957,7 +959,7 @@ class TAioStorageProvider final auto storage = std::make_shared( SubmitQueue, - FileIOService, + FileIOServiceProvider->CreateFileIOService(filePath), NvmeManager, blockSize, volume.GetStartIndex(), @@ -974,7 +976,7 @@ class TAioStorageProvider final //////////////////////////////////////////////////////////////////////////////// IStorageProviderPtr CreateAioStorageProvider( - IFileIOServicePtr fileIO, + IFileIOServiceProviderPtr fileIOProvider, INvmeManagerPtr nvmeManager, bool directIO, EAioSubmitQueueOpt submitQueueOpt) @@ -986,7 +988,7 @@ IStorageProviderPtr CreateAioStorageProvider( return std::make_shared( std::move(submitQueue), - std::move(fileIO), + std::move(fileIOProvider), std::move(nvmeManager), directIO); } diff --git a/cloud/blockstore/libs/service_local/storage_aio.h b/cloud/blockstore/libs/service_local/storage_aio.h index 4421a46ff97..4217c3b5835 100644 --- a/cloud/blockstore/libs/service_local/storage_aio.h +++ b/cloud/blockstore/libs/service_local/storage_aio.h @@ -19,7 +19,7 @@ enum class EAioSubmitQueueOpt : bool { //////////////////////////////////////////////////////////////////////////////// IStorageProviderPtr CreateAioStorageProvider( - IFileIOServicePtr fileIO, + IFileIOServiceProviderPtr fileIOProvider, NNvme::INvmeManagerPtr nvmeManager, bool directIO, EAioSubmitQueueOpt submitQueueOpt); diff --git a/cloud/blockstore/libs/service_local/storage_aio_ut.cpp b/cloud/blockstore/libs/service_local/storage_aio_ut.cpp index f6087631573..489960a4b29 100644 --- a/cloud/blockstore/libs/service_local/storage_aio_ut.cpp +++ b/cloud/blockstore/libs/service_local/storage_aio_ut.cpp @@ -1,5 +1,7 @@ #include "storage_aio.h" +#include "file_io_service_provider.h" + #include #include #include @@ -102,6 +104,14 @@ TFsPath TryGetRamDrivePath() : p; } +auto CreateAndStartAIOServiceProvider() +{ + auto provider = CreateSingleFileIOServiceProvider(CreateAIOService()); + provider->Start(); + + return provider; +} + } // namespace //////////////////////////////////////////////////////////////////////////////// @@ -119,12 +129,11 @@ Y_UNIT_TEST_SUITE(TAioStorageTest) TFile fileData(filePath, EOpenModeFlag::CreateAlways); fileData.Resize(blockSize * (blockCount + startIndex)); - auto service = CreateAIOService(); - service->Start(); - Y_DEFER { service->Stop(); }; + auto fileIOServiceProvider = CreateAndStartAIOServiceProvider(); + Y_DEFER { fileIOServiceProvider->Stop(); }; auto provider = CreateAioStorageProvider( - service, + fileIOServiceProvider, CreateNvmeManagerStub(), false, // directIO submitQueueOpt @@ -236,12 +245,11 @@ Y_UNIT_TEST_SUITE(TAioStorageTest) fileData.Flush(); } - auto service = CreateAIOService(); - service->Start(); - Y_DEFER { service->Stop(); }; + auto fileIOServiceProvider = CreateAndStartAIOServiceProvider(); + Y_DEFER { fileIOServiceProvider->Stop(); }; auto provider = CreateAioStorageProvider( - service, + fileIOServiceProvider, CreateNvmeManagerStub(), false, // directIO submitQueueOpt @@ -337,12 +345,11 @@ Y_UNIT_TEST_SUITE(TAioStorageTest) TFile fileData(filePath, EOpenModeFlag::CreateAlways); fileData.Resize(blockSize * blockCount); - auto service = CreateAIOService(); - service->Start(); - Y_DEFER { service->Stop(); }; + auto fileIOServiceProvider = CreateAndStartAIOServiceProvider(); + Y_DEFER { fileIOServiceProvider->Stop(); }; auto provider = CreateAioStorageProvider( - service, + fileIOServiceProvider, CreateNvmeManagerStub(), false, // directIO EAioSubmitQueueOpt::DontUse @@ -471,12 +478,11 @@ Y_UNIT_TEST_SUITE(TAioStorageTest) TFile fileData(filePath, EOpenModeFlag::CreateAlways); fileData.Resize(blockSize * blockCount); - auto service = CreateAIOService(); - service->Start(); - Y_DEFER { service->Stop(); }; + auto fileIOServiceProvider = CreateAndStartAIOServiceProvider(); + Y_DEFER { fileIOServiceProvider->Stop(); }; auto provider = CreateAioStorageProvider( - service, + fileIOServiceProvider, CreateNvmeManagerStub(), true, // directIO EAioSubmitQueueOpt::DontUse @@ -536,12 +542,11 @@ Y_UNIT_TEST_SUITE(TAioStorageTest) TFile fileData(filePath, EOpenModeFlag::CreateAlways); fileData.Resize(blockSize * blockCount); - auto service = CreateAIOService(); - service->Start(); - Y_DEFER { service->Stop(); }; + auto fileIOServiceProvider = CreateAndStartAIOServiceProvider(); + Y_DEFER { fileIOServiceProvider->Stop(); }; auto provider = CreateAioStorageProvider( - service, + fileIOServiceProvider, CreateNvmeManagerStub(false /* not ssd */), true, // directIO EAioSubmitQueueOpt::DontUse @@ -599,12 +604,11 @@ Y_UNIT_TEST_SUITE(TAioStorageTest) TFile fileData(filePath, EOpenModeFlag::CreateAlways); fileData.Resize(blockSize * blockCount); - auto service = CreateAIOService(); - service->Start(); - Y_DEFER { service->Stop(); }; + auto fileIOServiceProvider = CreateAndStartAIOServiceProvider(); + Y_DEFER { fileIOServiceProvider->Stop(); }; auto provider = CreateAioStorageProvider( - service, + fileIOServiceProvider, CreateNvmeManagerStub(), false, // directIO EAioSubmitQueueOpt::DontUse @@ -662,13 +666,13 @@ Y_UNIT_TEST_SUITE(TAioStorageTest) TFile fileData(filePath, EOpenModeFlag::CreateAlways); fileData.Resize(blockSize * blockCount); - auto service = CreateAIOService(); - service->Start(); - Y_DEFER { service->Stop(); }; + auto fileIOServiceProvider = CreateAndStartAIOServiceProvider(); + Y_DEFER { fileIOServiceProvider->Stop(); }; auto deallocateHistory = std::make_shared(); + auto provider = CreateAioStorageProvider( - service, + fileIOServiceProvider, CreateNvmeManagerStub(true, deallocateHistory), true, // directIO EAioSubmitQueueOpt::DontUse); diff --git a/cloud/blockstore/libs/service_local/storage_aio_ut_large.cpp b/cloud/blockstore/libs/service_local/storage_aio_ut_large.cpp index a2c3bab861d..5a8ad8000af 100644 --- a/cloud/blockstore/libs/service_local/storage_aio_ut_large.cpp +++ b/cloud/blockstore/libs/service_local/storage_aio_ut_large.cpp @@ -1,5 +1,7 @@ #include "storage_aio.h" +#include "file_io_service_provider.h" + #include #include #include @@ -44,12 +46,14 @@ Y_UNIT_TEST_SUITE(TAioStorageTest) TFile fileData(filePath, EOpenModeFlag::CreateAlways); fileData.Resize(blockSize * totalBlockCount); - auto service = CreateAIOService(); - service->Start(); - Y_DEFER { service->Stop(); }; + auto fileIOServiceProvider = + CreateSingleFileIOServiceProvider(CreateAIOService()); + + fileIOServiceProvider->Start(); + Y_DEFER { fileIOServiceProvider->Stop(); }; auto provider = CreateAioStorageProvider( - service, + fileIOServiceProvider, CreateNvmeManagerStub(), true, // directIO EAioSubmitQueueOpt::DontUse diff --git a/cloud/blockstore/libs/service_local/ut/CMakeLists.darwin-x86_64.txt b/cloud/blockstore/libs/service_local/ut/CMakeLists.darwin-x86_64.txt index 99bef9af7b1..276bf4fd07c 100644 --- a/cloud/blockstore/libs/service_local/ut/CMakeLists.darwin-x86_64.txt +++ b/cloud/blockstore/libs/service_local/ut/CMakeLists.darwin-x86_64.txt @@ -29,6 +29,7 @@ target_link_options(cloud-blockstore-libs-service_local-ut PRIVATE ) target_sources(cloud-blockstore-libs-service_local-ut PRIVATE ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/compound_storage_ut.cpp + ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/file_io_service_provider_ut.cpp ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/storage_aio_ut.cpp ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/storage_null_ut.cpp ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/storage_spdk_ut.cpp diff --git a/cloud/blockstore/libs/service_local/ut/CMakeLists.linux-aarch64.txt b/cloud/blockstore/libs/service_local/ut/CMakeLists.linux-aarch64.txt index 57db4cd02fd..2972646b863 100644 --- a/cloud/blockstore/libs/service_local/ut/CMakeLists.linux-aarch64.txt +++ b/cloud/blockstore/libs/service_local/ut/CMakeLists.linux-aarch64.txt @@ -32,6 +32,7 @@ target_link_options(cloud-blockstore-libs-service_local-ut PRIVATE ) target_sources(cloud-blockstore-libs-service_local-ut PRIVATE ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/compound_storage_ut.cpp + ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/file_io_service_provider_ut.cpp ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/storage_aio_ut.cpp ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/storage_null_ut.cpp ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/storage_spdk_ut.cpp diff --git a/cloud/blockstore/libs/service_local/ut/CMakeLists.linux-x86_64.txt b/cloud/blockstore/libs/service_local/ut/CMakeLists.linux-x86_64.txt index b485fa88295..004112d5928 100644 --- a/cloud/blockstore/libs/service_local/ut/CMakeLists.linux-x86_64.txt +++ b/cloud/blockstore/libs/service_local/ut/CMakeLists.linux-x86_64.txt @@ -33,6 +33,7 @@ target_link_options(cloud-blockstore-libs-service_local-ut PRIVATE ) target_sources(cloud-blockstore-libs-service_local-ut PRIVATE ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/compound_storage_ut.cpp + ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/file_io_service_provider_ut.cpp ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/storage_aio_ut.cpp ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/storage_null_ut.cpp ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/storage_spdk_ut.cpp diff --git a/cloud/blockstore/libs/service_local/ut/CMakeLists.windows-x86_64.txt b/cloud/blockstore/libs/service_local/ut/CMakeLists.windows-x86_64.txt index 85ba534ecbd..84a5ba21a62 100644 --- a/cloud/blockstore/libs/service_local/ut/CMakeLists.windows-x86_64.txt +++ b/cloud/blockstore/libs/service_local/ut/CMakeLists.windows-x86_64.txt @@ -22,6 +22,7 @@ target_link_libraries(cloud-blockstore-libs-service_local-ut PUBLIC ) target_sources(cloud-blockstore-libs-service_local-ut PRIVATE ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/compound_storage_ut.cpp + ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/file_io_service_provider_ut.cpp ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/storage_aio_ut.cpp ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/storage_null_ut.cpp ${CMAKE_SOURCE_DIR}/cloud/blockstore/libs/service_local/storage_spdk_ut.cpp diff --git a/cloud/blockstore/libs/service_local/ut/ya.make b/cloud/blockstore/libs/service_local/ut/ya.make index ab898928586..a711812d404 100644 --- a/cloud/blockstore/libs/service_local/ut/ya.make +++ b/cloud/blockstore/libs/service_local/ut/ya.make @@ -6,9 +6,10 @@ TIMEOUT(180) SRCS( compound_storage_ut.cpp + file_io_service_provider_ut.cpp storage_aio_ut.cpp - storage_rdma_ut.cpp storage_null_ut.cpp + storage_rdma_ut.cpp storage_spdk_ut.cpp ) diff --git a/cloud/blockstore/libs/service_local/ya.make b/cloud/blockstore/libs/service_local/ya.make index 66847518875..19c15d3b8b4 100644 --- a/cloud/blockstore/libs/service_local/ya.make +++ b/cloud/blockstore/libs/service_local/ya.make @@ -3,6 +3,7 @@ LIBRARY() SRCS( broken_storage.cpp compound_storage.cpp + file_io_service_provider.cpp rdma_protocol.cpp service_local.cpp storage_aio.cpp @@ -20,13 +21,13 @@ PEERDIR( cloud/blockstore/libs/service cloud/blockstore/libs/spdk/iface cloud/blockstore/libs/storage/protos - + cloud/storage/core/libs/common - + library/cpp/aio library/cpp/deprecated/atomic library/cpp/protobuf/util - + contrib/libs/protobuf ) diff --git a/cloud/blockstore/libs/storage/disk_agent/model/config.cpp b/cloud/blockstore/libs/storage/disk_agent/model/config.cpp index 8818372c868..f69a214135f 100644 --- a/cloud/blockstore/libs/storage/disk_agent/model/config.cpp +++ b/cloud/blockstore/libs/storage/disk_agent/model/config.cpp @@ -43,6 +43,7 @@ namespace { xxx(OffloadAllIORequestsParsingEnabled, bool, false )\ xxx(DisableNodeBrokerRegisterationOnDevicelessAgent, bool, false )\ xxx(MaxAIOContextEvents, ui32, 1024 )\ + xxx(PathsPerFileIOService, ui32, 0 )\ // BLOCKSTORE_AGENT_CONFIG #define BLOCKSTORE_DECLARE_CONFIG(name, type, value) \ diff --git a/cloud/blockstore/libs/storage/disk_agent/model/config.h b/cloud/blockstore/libs/storage/disk_agent/model/config.h index 6d7a65d94c5..ccccb94219d 100644 --- a/cloud/blockstore/libs/storage/disk_agent/model/config.h +++ b/cloud/blockstore/libs/storage/disk_agent/model/config.h @@ -112,6 +112,7 @@ class TDiskAgentConfig bool GetOffloadAllIORequestsParsingEnabled() const; bool GetDisableNodeBrokerRegisterationOnDevicelessAgent() const; ui32 GetMaxAIOContextEvents() const; + ui32 GetPathsPerFileIOService() const; void Dump(IOutputStream& out) const; void DumpHtml(IOutputStream& out) const; diff --git a/cloud/blockstore/libs/storage/disk_agent/testlib/test_env.cpp b/cloud/blockstore/libs/storage/disk_agent/testlib/test_env.cpp index 5d41b428fca..2370f3b63ec 100644 --- a/cloud/blockstore/libs/storage/disk_agent/testlib/test_env.cpp +++ b/cloud/blockstore/libs/storage/disk_agent/testlib/test_env.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -655,7 +656,7 @@ IStorageProviderPtr CreateTestStorageProvider( { return std::make_shared( NServer::CreateAioStorageProvider( - std::move(fileIO), + NServer::CreateSingleFileIOServiceProvider(std::move(fileIO)), std::move(nvmeManager), false, // directIO NServer::EAioSubmitQueueOpt::DontUse diff --git a/cloud/blockstore/libs/storage/init/server/actorsystem.h b/cloud/blockstore/libs/storage/init/server/actorsystem.h index 7dc88368094..086e5975820 100644 --- a/cloud/blockstore/libs/storage/init/server/actorsystem.h +++ b/cloud/blockstore/libs/storage/init/server/actorsystem.h @@ -51,7 +51,6 @@ struct TServerActorSystemArgs NDiscovery::IDiscoveryServicePtr DiscoveryService; NSpdk::ISpdkEnvPtr Spdk; ICachingAllocatorPtr Allocator; - IFileIOServicePtr FileIOService; IStorageProviderPtr AioStorageProvider; IProfileLogPtr ProfileLog; IBlockDigestGeneratorPtr BlockDigestGenerator; diff --git a/cloud/blockstore/tests/python/lib/config.py b/cloud/blockstore/tests/python/lib/config.py index 1d53e945cd4..2694ce56704 100644 --- a/cloud/blockstore/tests/python/lib/config.py +++ b/cloud/blockstore/tests/python/lib/config.py @@ -302,6 +302,7 @@ def generate_disk_agent_txt( config.ShutdownTimeout = 0 config.IOParserActorCount = 4 config.OffloadAllIORequestsParsingEnabled = True + config.PathsPerFileIOService = 1 if device_erase_method is not None: config.DeviceEraseMethod = EDeviceEraseMethod.Value(device_erase_method) diff --git a/cloud/blockstore/tests/python/lib/nonreplicated_setup.py b/cloud/blockstore/tests/python/lib/nonreplicated_setup.py index 7f769656c8f..087c1f8f6e7 100644 --- a/cloud/blockstore/tests/python/lib/nonreplicated_setup.py +++ b/cloud/blockstore/tests/python/lib/nonreplicated_setup.py @@ -222,6 +222,7 @@ def setup_disk_agent_config( config.ShutdownTimeout = get_shutdown_agent_interval() config.IOParserActorCount = 4 config.OffloadAllIORequestsParsingEnabled = True + config.PathsPerFileIOService = 1 if cached_sessions_path is not None: config.CachedSessionsPath = cached_sessions_path diff --git a/cloud/blockstore/vhost-server/backend_aio.cpp b/cloud/blockstore/vhost-server/backend_aio.cpp index 40402807a27..72f9655cd7b 100644 --- a/cloud/blockstore/vhost-server/backend_aio.cpp +++ b/cloud/blockstore/vhost-server/backend_aio.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -154,6 +155,8 @@ class TAioBackend final: public IBackend TSimpleStats& queueStats); void CompletionThreadFunc(); + + void IoSetup(); }; //////////////////////////////////////////////////////////////////////////////// @@ -168,6 +171,33 @@ TAioBackend::TAioBackend( Log = Logging->CreateLog("AIO"); } +void TAioBackend::IoSetup() +{ + const auto waitTime = TDuration::MilliSeconds(100); + const int maxIterations = 1000; + + int iterations = 0; + int error = 0; + + for (; iterations != maxIterations; ++iterations) { + error = io_setup(BatchSize, &Io); + if (error != -EAGAIN) { + break; + } + + const auto aioNr = TIFStream("/proc/sys/fs/aio-nr").ReadLine(); + const auto aioMaxNr = TIFStream("/proc/sys/fs/aio-max-nr").ReadLine(); + + STORAGE_WARN( + "retrying EAGAIN from io_setup, BatchSize: " + << BatchSize << ", aio-nr/aio-max-nr: " << aioNr << "/" + << aioMaxNr); + + Sleep(waitTime); + } + Y_ABORT_UNLESS(!error, "io_setup: %d, iterations: %d", error, iterations); +} + vhd_bdev_info TAioBackend::Init(const TOptions& options) { STORAGE_INFO("Initializing AIO backend"); @@ -176,7 +206,7 @@ vhd_bdev_info TAioBackend::Init(const TOptions& options) } BatchSize = options.BatchSize; - Y_ABORT_UNLESS(io_setup(BatchSize, &Io) >= 0, "io_setup"); + IoSetup(); for (ui32 i = 0; i < options.QueueCount; i++) { Batches.emplace_back();