From 6bc430c0f113d0815ed730dd40bae40a1d2e52fc Mon Sep 17 00:00:00 2001 From: Andrei Strelkovskii Date: Wed, 21 Aug 2024 13:33:53 +0300 Subject: [PATCH] issue-1823: allowing FS size decrease with a Force flag + some cleanup (#1828) * issue-1823: allowing FS size decrease with a Force flag + some cleanup * issue-1823: fixed format string * issue-1823: tablet_ut.cpp - BlockCount can be decreased now --- .../storage/service/service_actor_alterfs.cpp | 8 +- .../libs/storage/service/service_ut.cpp | 197 +++++++++++++----- .../tablet/tablet_actor_updateconfig.cpp | 55 ++--- .../libs/storage/tablet/tablet_ut.cpp | 5 +- .../libs/storage/testlib/service_client.h | 4 +- cloud/filestore/public/api/protos/fs.proto | 3 + 6 files changed, 183 insertions(+), 89 deletions(-) diff --git a/cloud/filestore/libs/storage/service/service_actor_alterfs.cpp b/cloud/filestore/libs/storage/service/service_actor_alterfs.cpp index 5f714407282..671c1cc3556 100644 --- a/cloud/filestore/libs/storage/service/service_actor_alterfs.cpp +++ b/cloud/filestore/libs/storage/service/service_actor_alterfs.cpp @@ -25,7 +25,8 @@ class TAlterFileStoreActor final const TRequestInfoPtr RequestInfo; const TString FileSystemId; const NProto::TFileStorePerformanceProfile PerformanceProfile; - const bool Alter = false; + const bool Alter; + const bool Force; NKikimrFileStore::TConfig Config; @@ -81,6 +82,7 @@ TAlterFileStoreActor::TAlterFileStoreActor( , RequestInfo(std::move(requestInfo)) , FileSystemId(request.GetFileSystemId()) , Alter(true) + , Force(false) { Config.SetCloudId(request.GetCloudId()); Config.SetFolderId(request.GetFolderId()); @@ -96,6 +98,8 @@ TAlterFileStoreActor::TAlterFileStoreActor( , RequestInfo(std::move(requestInfo)) , FileSystemId(request.GetFileSystemId()) , PerformanceProfile(request.GetPerformanceProfile()) + , Alter(false) + , Force(request.GetForce()) { Config.SetBlocksCount(request.GetBlocksCount()); Config.SetVersion(request.GetConfigVersion()); @@ -137,7 +141,7 @@ void TAlterFileStoreActor::HandleDescribeFileStoreResponse( const bool allocateMixed0 = thirdChannelDataKind == EChannelDataKind::Mixed0; if (!Alter) { - if (config.GetBlocksCount() > Config.GetBlocksCount()) { + if (config.GetBlocksCount() > Config.GetBlocksCount() && !Force) { ReplyAndDie( ctx, MakeError(E_ARGUMENT, "Cannot decrease filestore size")); diff --git a/cloud/filestore/libs/storage/service/service_ut.cpp b/cloud/filestore/libs/storage/service/service_ut.cpp index 9df0f2c4f9c..773d29638ae 100644 --- a/cloud/filestore/libs/storage/service/service_ut.cpp +++ b/cloud/filestore/libs/storage/service/service_ut.cpp @@ -60,28 +60,36 @@ Y_UNIT_TEST_SUITE(TStorageServiceTest) service.CreateFileStore("test", 1'000); auto response = service.GetFileStoreInfo("test")->Record.GetFileStore(); - UNIT_ASSERT_VALUES_EQUAL(response.GetFileSystemId(), "test"); - UNIT_ASSERT_VALUES_EQUAL(response.GetCloudId(), "test"); - UNIT_ASSERT_VALUES_EQUAL(response.GetFolderId(), "test"); - UNIT_ASSERT_VALUES_EQUAL(response.GetBlocksCount(), 1'000); - UNIT_ASSERT_VALUES_EQUAL(response.GetBlockSize(), DefaultBlockSize); - UNIT_ASSERT_VALUES_EQUAL(response.GetConfigVersion(), 1); + UNIT_ASSERT_VALUES_EQUAL("test", response.GetFileSystemId()); + UNIT_ASSERT_VALUES_EQUAL("test", response.GetCloudId()); + UNIT_ASSERT_VALUES_EQUAL("test", response.GetFolderId()); + UNIT_ASSERT_VALUES_EQUAL(1'000, response.GetBlocksCount()); + UNIT_ASSERT_VALUES_EQUAL(DefaultBlockSize, response.GetBlockSize()); + UNIT_ASSERT_VALUES_EQUAL(1, response.GetConfigVersion()); const auto& profile = response.GetPerformanceProfile(); UNIT_ASSERT(!profile.GetThrottlingEnabled()); - UNIT_ASSERT_VALUES_EQUAL(profile.GetMaxReadIops(), 100); - UNIT_ASSERT_VALUES_EQUAL(profile.GetMaxWriteIops(), 300); - UNIT_ASSERT_VALUES_EQUAL(profile.GetMaxReadBandwidth(), 30_MB); - UNIT_ASSERT_VALUES_EQUAL(profile.GetMaxWriteBandwidth(), 30_MB); - UNIT_ASSERT_VALUES_EQUAL(profile.GetMaxPostponedWeight(), 128_MB); - UNIT_ASSERT_VALUES_EQUAL(profile.GetMaxPostponedTime(), TDuration::Seconds(20).MilliSeconds()); - UNIT_ASSERT_VALUES_EQUAL(profile.GetMaxPostponedCount(), 1024); - UNIT_ASSERT_VALUES_EQUAL(profile.GetBoostTime(), TDuration::Minutes(30).MilliSeconds()); - UNIT_ASSERT_VALUES_EQUAL(profile.GetBoostRefillTime(), TDuration::Hours(12).MilliSeconds()); - UNIT_ASSERT_VALUES_EQUAL(profile.GetBoostPercentage(), 400); - UNIT_ASSERT_VALUES_EQUAL(profile.GetBurstPercentage(), 10); - UNIT_ASSERT_VALUES_EQUAL(profile.GetMaxWriteCostMultiplier(), 20); - UNIT_ASSERT_VALUES_EQUAL(profile.GetDefaultPostponedRequestWeight(), 4_KB); + UNIT_ASSERT_VALUES_EQUAL(100, profile.GetMaxReadIops()); + UNIT_ASSERT_VALUES_EQUAL(300, profile.GetMaxWriteIops()); + UNIT_ASSERT_VALUES_EQUAL(30_MB, profile.GetMaxReadBandwidth()); + UNIT_ASSERT_VALUES_EQUAL(30_MB, profile.GetMaxWriteBandwidth()); + UNIT_ASSERT_VALUES_EQUAL(128_MB, profile.GetMaxPostponedWeight()); + UNIT_ASSERT_VALUES_EQUAL( + TDuration::Seconds(20).MilliSeconds(), + profile.GetMaxPostponedTime()); + UNIT_ASSERT_VALUES_EQUAL(1024, profile.GetMaxPostponedCount()); + UNIT_ASSERT_VALUES_EQUAL( + TDuration::Minutes(30).MilliSeconds(), + profile.GetBoostTime()); + UNIT_ASSERT_VALUES_EQUAL( + TDuration::Hours(12).MilliSeconds(), + profile.GetBoostRefillTime()); + UNIT_ASSERT_VALUES_EQUAL(400, profile.GetBoostPercentage()); + UNIT_ASSERT_VALUES_EQUAL(10, profile.GetBurstPercentage()); + UNIT_ASSERT_VALUES_EQUAL(20, profile.GetMaxWriteCostMultiplier()); + UNIT_ASSERT_VALUES_EQUAL( + 4_KB, + profile.GetDefaultPostponedRequestWeight()); service.DestroyFileStore("test"); service.AssertGetFileStoreInfoFailed("test"); @@ -99,28 +107,36 @@ Y_UNIT_TEST_SUITE(TStorageServiceTest) service.AlterFileStore("test", "yyyy", "zzzz"); auto response = service.GetFileStoreInfo("test")->Record.GetFileStore(); - UNIT_ASSERT_VALUES_EQUAL(response.GetFileSystemId(), "test"); - UNIT_ASSERT_VALUES_EQUAL(response.GetCloudId(), "yyyy"); - UNIT_ASSERT_VALUES_EQUAL(response.GetFolderId(), "zzzz"); - UNIT_ASSERT_VALUES_EQUAL(response.GetBlocksCount(), 1'000); - UNIT_ASSERT_VALUES_EQUAL(response.GetBlockSize(), DefaultBlockSize); - UNIT_ASSERT_VALUES_EQUAL(response.GetConfigVersion(), 2); + UNIT_ASSERT_VALUES_EQUAL("test", response.GetFileSystemId()); + UNIT_ASSERT_VALUES_EQUAL("yyyy", response.GetCloudId()); + UNIT_ASSERT_VALUES_EQUAL("zzzz", response.GetFolderId()); + UNIT_ASSERT_VALUES_EQUAL(1'000, response.GetBlocksCount()); + UNIT_ASSERT_VALUES_EQUAL(DefaultBlockSize, response.GetBlockSize()); + UNIT_ASSERT_VALUES_EQUAL(2, response.GetConfigVersion()); const auto& profile = response.GetPerformanceProfile(); UNIT_ASSERT(!profile.GetThrottlingEnabled()); - UNIT_ASSERT_VALUES_EQUAL(profile.GetMaxReadIops(), 100); - UNIT_ASSERT_VALUES_EQUAL(profile.GetMaxWriteIops(), 300); - UNIT_ASSERT_VALUES_EQUAL(profile.GetMaxReadBandwidth(), 30_MB); - UNIT_ASSERT_VALUES_EQUAL(profile.GetMaxWriteBandwidth(), 30_MB); - UNIT_ASSERT_VALUES_EQUAL(profile.GetMaxPostponedWeight(), 128_MB); - UNIT_ASSERT_VALUES_EQUAL(profile.GetMaxPostponedTime(), TDuration::Seconds(20).MilliSeconds()); - UNIT_ASSERT_VALUES_EQUAL(profile.GetMaxPostponedCount(), 1024); - UNIT_ASSERT_VALUES_EQUAL(profile.GetBoostTime(), TDuration::Minutes(30).MilliSeconds()); - UNIT_ASSERT_VALUES_EQUAL(profile.GetBoostRefillTime(), TDuration::Hours(12).MilliSeconds()); - UNIT_ASSERT_VALUES_EQUAL(profile.GetBoostPercentage(), 400); - UNIT_ASSERT_VALUES_EQUAL(profile.GetBurstPercentage(), 10); - UNIT_ASSERT_VALUES_EQUAL(profile.GetMaxWriteCostMultiplier(), 20); - UNIT_ASSERT_VALUES_EQUAL(profile.GetDefaultPostponedRequestWeight(), 4_KB); + UNIT_ASSERT_VALUES_EQUAL(100, profile.GetMaxReadIops()); + UNIT_ASSERT_VALUES_EQUAL(300, profile.GetMaxWriteIops()); + UNIT_ASSERT_VALUES_EQUAL(30_MB, profile.GetMaxReadBandwidth()); + UNIT_ASSERT_VALUES_EQUAL(30_MB, profile.GetMaxWriteBandwidth()); + UNIT_ASSERT_VALUES_EQUAL(128_MB, profile.GetMaxPostponedWeight()); + UNIT_ASSERT_VALUES_EQUAL( + TDuration::Seconds(20).MilliSeconds(), + profile.GetMaxPostponedTime()); + UNIT_ASSERT_VALUES_EQUAL(1024, profile.GetMaxPostponedCount()); + UNIT_ASSERT_VALUES_EQUAL( + TDuration::Minutes(30).MilliSeconds(), + profile.GetBoostTime()); + UNIT_ASSERT_VALUES_EQUAL( + TDuration::Hours(12).MilliSeconds(), + profile.GetBoostRefillTime()); + UNIT_ASSERT_VALUES_EQUAL(400, profile.GetBoostPercentage()); + UNIT_ASSERT_VALUES_EQUAL(10, profile.GetBurstPercentage()); + UNIT_ASSERT_VALUES_EQUAL(20, profile.GetMaxWriteCostMultiplier()); + UNIT_ASSERT_VALUES_EQUAL( + 4_KB, + profile.GetDefaultPostponedRequestWeight()); } Y_UNIT_TEST(ShouldResizeFileStore) @@ -135,33 +151,100 @@ Y_UNIT_TEST_SUITE(TStorageServiceTest) service.ResizeFileStore("test", 100'000'000); auto response = service.GetFileStoreInfo("test")->Record.GetFileStore(); - UNIT_ASSERT_VALUES_EQUAL(response.GetFileSystemId(), "test"); - UNIT_ASSERT_VALUES_EQUAL(response.GetCloudId(), "test"); - UNIT_ASSERT_VALUES_EQUAL(response.GetFolderId(), "test"); - UNIT_ASSERT_VALUES_EQUAL(response.GetBlocksCount(), 100'000'000); - UNIT_ASSERT_VALUES_EQUAL(response.GetBlockSize(), DefaultBlockSize); - UNIT_ASSERT_VALUES_EQUAL(response.GetConfigVersion(), 2); + UNIT_ASSERT_VALUES_EQUAL("test", response.GetFileSystemId()); + UNIT_ASSERT_VALUES_EQUAL("test", response.GetCloudId()); + UNIT_ASSERT_VALUES_EQUAL("test", response.GetFolderId()); + UNIT_ASSERT_VALUES_EQUAL(100'000'000, response.GetBlocksCount()); + UNIT_ASSERT_VALUES_EQUAL(DefaultBlockSize, response.GetBlockSize()); + UNIT_ASSERT_VALUES_EQUAL(2, response.GetConfigVersion()); const auto& profile = response.GetPerformanceProfile(); UNIT_ASSERT(!profile.GetThrottlingEnabled()); - UNIT_ASSERT_VALUES_EQUAL(profile.GetMaxReadIops(), 200); - UNIT_ASSERT_VALUES_EQUAL(profile.GetMaxWriteIops(), 600); - UNIT_ASSERT_VALUES_EQUAL(profile.GetMaxReadBandwidth(), 60_MB); - UNIT_ASSERT_VALUES_EQUAL(profile.GetMaxWriteBandwidth(), 60_MB); - UNIT_ASSERT_VALUES_EQUAL(profile.GetMaxPostponedWeight(), 128_MB); - UNIT_ASSERT_VALUES_EQUAL(profile.GetMaxPostponedTime(), TDuration::Seconds(20).MilliSeconds()); - UNIT_ASSERT_VALUES_EQUAL(profile.GetMaxPostponedCount(), 1024); - UNIT_ASSERT_VALUES_EQUAL(profile.GetBoostTime(), TDuration::Minutes(30).MilliSeconds()); - UNIT_ASSERT_VALUES_EQUAL(profile.GetBoostRefillTime(), TDuration::Hours(12).MilliSeconds()); - UNIT_ASSERT_VALUES_EQUAL(profile.GetBoostPercentage(), 200); - UNIT_ASSERT_VALUES_EQUAL(profile.GetBurstPercentage(), 10); - UNIT_ASSERT_VALUES_EQUAL(profile.GetMaxWriteCostMultiplier(), 20); - UNIT_ASSERT_VALUES_EQUAL(profile.GetDefaultPostponedRequestWeight(), 4_KB); + UNIT_ASSERT_VALUES_EQUAL(200, profile.GetMaxReadIops()); + UNIT_ASSERT_VALUES_EQUAL(600, profile.GetMaxWriteIops()); + UNIT_ASSERT_VALUES_EQUAL(60_MB, profile.GetMaxReadBandwidth()); + UNIT_ASSERT_VALUES_EQUAL(60_MB, profile.GetMaxWriteBandwidth()); + UNIT_ASSERT_VALUES_EQUAL(128_MB, profile.GetMaxPostponedWeight()); + UNIT_ASSERT_VALUES_EQUAL( + TDuration::Seconds(20).MilliSeconds(), + profile.GetMaxPostponedTime()); + UNIT_ASSERT_VALUES_EQUAL(1024, profile.GetMaxPostponedCount()); + UNIT_ASSERT_VALUES_EQUAL( + TDuration::Minutes(30).MilliSeconds(), + profile.GetBoostTime()); + UNIT_ASSERT_VALUES_EQUAL( + TDuration::Hours(12).MilliSeconds(), + profile.GetBoostRefillTime()); + UNIT_ASSERT_VALUES_EQUAL(200, profile.GetBoostPercentage()); + UNIT_ASSERT_VALUES_EQUAL(10, profile.GetBurstPercentage()); + UNIT_ASSERT_VALUES_EQUAL(20, profile.GetMaxWriteCostMultiplier()); + UNIT_ASSERT_VALUES_EQUAL( + 4_KB, + profile.GetDefaultPostponedRequestWeight()); service.AssertResizeFileStoreFailed("test", 1'000); service.AssertResizeFileStoreFailed("test", 0); } + Y_UNIT_TEST(ShouldDownsizeFileStore) + { + TTestEnv env; + env.CreateSubDomain("nfs"); + + ui32 nodeIdx = env.CreateNode("nfs"); + + TServiceClient service(env.GetRuntime(), nodeIdx); + service.CreateFileStore("test", 100'000'000); + + { + service.SendResizeFileStoreRequest("test", 10'000'000); + auto response = service.RecvResizeFileStoreResponse(); + UNIT_ASSERT_VALUES_EQUAL_C( + E_ARGUMENT, + response->GetStatus(), + response->GetErrorReason()); + + service.SendResizeFileStoreRequest("test", 10'000'000, true); + response = service.RecvResizeFileStoreResponse(); + UNIT_ASSERT_VALUES_EQUAL_C( + S_OK, + response->GetStatus(), + response->GetErrorReason()); + } + + auto response = service.GetFileStoreInfo("test")->Record.GetFileStore(); + UNIT_ASSERT_VALUES_EQUAL("test", response.GetFileSystemId()); + UNIT_ASSERT_VALUES_EQUAL("test", response.GetCloudId()); + UNIT_ASSERT_VALUES_EQUAL("test", response.GetFolderId()); + UNIT_ASSERT_VALUES_EQUAL(100'000'00, response.GetBlocksCount()); + UNIT_ASSERT_VALUES_EQUAL(DefaultBlockSize, response.GetBlockSize()); + UNIT_ASSERT_VALUES_EQUAL(2, response.GetConfigVersion()); + + const auto& profile = response.GetPerformanceProfile(); + UNIT_ASSERT(!profile.GetThrottlingEnabled()); + UNIT_ASSERT_VALUES_EQUAL(200, profile.GetMaxReadIops()); + UNIT_ASSERT_VALUES_EQUAL(600, profile.GetMaxWriteIops()); + UNIT_ASSERT_VALUES_EQUAL(60_MB, profile.GetMaxReadBandwidth()); + UNIT_ASSERT_VALUES_EQUAL(60_MB, profile.GetMaxWriteBandwidth()); + UNIT_ASSERT_VALUES_EQUAL(128_MB, profile.GetMaxPostponedWeight()); + UNIT_ASSERT_VALUES_EQUAL( + TDuration::Seconds(20).MilliSeconds(), + profile.GetMaxPostponedTime()); + UNIT_ASSERT_VALUES_EQUAL(1024, profile.GetMaxPostponedCount()); + UNIT_ASSERT_VALUES_EQUAL( + TDuration::Minutes(30).MilliSeconds(), + profile.GetBoostTime()); + UNIT_ASSERT_VALUES_EQUAL( + TDuration::Hours(12).MilliSeconds(), + profile.GetBoostRefillTime()); + UNIT_ASSERT_VALUES_EQUAL(400, profile.GetBoostPercentage()); + UNIT_ASSERT_VALUES_EQUAL(10, profile.GetBurstPercentage()); + UNIT_ASSERT_VALUES_EQUAL(20, profile.GetMaxWriteCostMultiplier()); + UNIT_ASSERT_VALUES_EQUAL( + 4_KB, + profile.GetDefaultPostponedRequestWeight()); + } + Y_UNIT_TEST(ShouldResizeFileStoreWithCustomPerformanceProfile) { TTestEnv env; diff --git a/cloud/filestore/libs/storage/tablet/tablet_actor_updateconfig.cpp b/cloud/filestore/libs/storage/tablet/tablet_actor_updateconfig.cpp index 7a2a7c48076..2bd1de2f94d 100644 --- a/cloud/filestore/libs/storage/tablet/tablet_actor_updateconfig.cpp +++ b/cloud/filestore/libs/storage/tablet/tablet_actor_updateconfig.cpp @@ -30,17 +30,6 @@ TString ValidateUpdateConfigRequest( << ")"; } - const ui64 oldBlockCount = oldConfig.GetBlocksCount(); - const ui64 newBlockCount = newConfig.GetBlocksCount(); - - if (oldBlockCount > newBlockCount) { - return TStringBuilder() - << "it's not allowed to decrease blockCount" - << " (old: " << oldBlockCount - << ", new: " << newBlockCount - << ")"; - } - const ui32 oldChannelCount = oldConfig.ExplicitChannelProfilesSize(); const ui32 newChannelCount = newConfig.ExplicitChannelProfilesSize(); @@ -53,28 +42,28 @@ TString ValidateUpdateConfigRequest( } using TChannelDiff = std::tuple; - TVector ChangedChannels; + TVector changedChannels; - for (ui32 channel = 0; channel < oldChannelCount; ++channel) { + for (ui32 c = 0; c < oldChannelCount; ++c) { const auto oldDataKind = static_cast(oldConfig - .GetExplicitChannelProfiles(channel) + .GetExplicitChannelProfiles(c) .GetDataKind()); const auto newDataKind = static_cast(newConfig - .GetExplicitChannelProfiles(channel) + .GetExplicitChannelProfiles(c) .GetDataKind()); if (oldDataKind != newDataKind) { - ChangedChannels.emplace_back(channel, oldDataKind, newDataKind); + changedChannels.emplace_back(c, oldDataKind, newDataKind); } } - if (ChangedChannels) { + if (changedChannels) { auto error = TStringBuilder() << "it's not allowed to change dataKind of existing channels ["; - for (const auto& [channel, oldDataKind, newDataKind]: ChangedChannels) { - error << " (channel: " << channel + for (const auto& [c, oldDataKind, newDataKind]: changedChannels) { + error << " (channel: " << c << ", oldDataKind: " << ToString(oldDataKind) << ", newDataKind: " << ToString(newDataKind) << ") "; @@ -88,24 +77,24 @@ TString ValidateUpdateConfigRequest( // Resizing tablet: check new channels dataKind. using TChannelDesc = std::tuple; - TVector BadNewChannels; + TVector badNewChannels; - for (ui32 channel = oldChannelCount; channel < newChannelCount; ++channel) { + for (ui32 c = oldChannelCount; c < newChannelCount; ++c) { const auto dataKind = static_cast(newConfig - .GetExplicitChannelProfiles(channel) + .GetExplicitChannelProfiles(c) .GetDataKind()); if (dataKind != EChannelDataKind::Mixed) { - BadNewChannels.emplace_back(channel, dataKind); + badNewChannels.emplace_back(c, dataKind); } } - if (BadNewChannels) { + if (badNewChannels) { auto error = TStringBuilder() << "it's allowed to add new channels with Mixed dataKind only ["; - for (const auto& [channel, dataKind]: BadNewChannels) { - error << " (channel: " << channel + for (const auto& [c, dataKind]: badNewChannels) { + error << " (channel: " << c << ", dataKind: " << ToString(dataKind) << ") "; } @@ -164,7 +153,7 @@ void TIndexTabletActor::HandleUpdateConfig( // Config update occured due to alter/resize. if (auto error = ValidateUpdateConfigRequest(oldConfig, newConfig)) { LOG_ERROR(ctx, TFileStoreComponents::TABLET, - "%s Failed to update config [txId: %d]: %s", + "%s Failed to update config [txId: %lu]: %s", LogTag.c_str(), txId, error.c_str()); @@ -183,6 +172,18 @@ void TIndexTabletActor::HandleUpdateConfig( return; } + const ui64 oldBlockCount = oldConfig.GetBlocksCount(); + const ui64 newBlockCount = newConfig.GetBlocksCount(); + + if (oldBlockCount > newBlockCount) { + LOG_WARN(ctx, TFileStoreComponents::TABLET, + "%s BlocksCount will be decreased %lu -> %lu [txId: %lu]", + LogTag.c_str(), + oldBlockCount, + newBlockCount, + txId); + } + ExecuteTx( ctx, std::move(requestInfo), diff --git a/cloud/filestore/libs/storage/tablet/tablet_ut.cpp b/cloud/filestore/libs/storage/tablet/tablet_ut.cpp index df21fbdf099..5770f073d67 100644 --- a/cloud/filestore/libs/storage/tablet/tablet_ut.cpp +++ b/cloud/filestore/libs/storage/tablet/tablet_ut.cpp @@ -190,15 +190,16 @@ Y_UNIT_TEST_SUITE(TIndexTabletTest) }); UNIT_ASSERT_VALUES_EQUAL(1, tabletUpdateConfigCounter->Val()); + // BlockCount can actually be decreased without problems tablet.UpdateConfig({ .BlockCount = 1, .ChannelCount = channelCount }); - UNIT_ASSERT_VALUES_EQUAL(2, tabletUpdateConfigCounter->Val()); + UNIT_ASSERT_VALUES_EQUAL(1, tabletUpdateConfigCounter->Val()); tablet.UpdateConfig({ .ChannelCount = channelCount - 1 }); - UNIT_ASSERT_VALUES_EQUAL(3, tabletUpdateConfigCounter->Val()); + UNIT_ASSERT_VALUES_EQUAL(2, tabletUpdateConfigCounter->Val()); { auto stats = GetStorageStats(tablet); UNIT_ASSERT_VALUES_EQUAL( diff --git a/cloud/filestore/libs/storage/testlib/service_client.h b/cloud/filestore/libs/storage/testlib/service_client.h index dc0e1ae7dbf..05ea2244e44 100644 --- a/cloud/filestore/libs/storage/testlib/service_client.h +++ b/cloud/filestore/libs/storage/testlib/service_client.h @@ -131,11 +131,13 @@ class TServiceClient auto CreateResizeFileStoreRequest( const TString& fileSystemId, - ui64 blocksCount) + ui64 blocksCount, + bool force = false) { auto request = std::make_unique(); request->Record.SetFileSystemId(fileSystemId); request->Record.SetBlocksCount(blocksCount); + request->Record.SetForce(force); return request; } diff --git a/cloud/filestore/public/api/protos/fs.proto b/cloud/filestore/public/api/protos/fs.proto index cce1487e909..73c494294e6 100644 --- a/cloud/filestore/public/api/protos/fs.proto +++ b/cloud/filestore/public/api/protos/fs.proto @@ -220,6 +220,9 @@ message TResizeFileStoreRequest // File system performance profile. TFileStorePerformanceProfile PerformanceProfile = 5; + + // Bypass some checks. + bool Force = 6; } message TResizeFileStoreResponse