Add a limit to how many virtiofs shares can be mounted (#40910)
Blue committed
Jun 25, 2026 at 15:07 UTC
68ee60c8d3c0eb71879c5f1bb54202e29866ba67
4 files changed
+66
localization/strings/en-US/Resources.resw
+4
@@ -2382,6 +2382,10 @@ For privacy information about this product please visit https://aka.ms/privacy.<
2382
<value>Failed to create volume '{}': {}</value>
2383
<comment>{FixedPlaceholder="{}"}Command line arguments, file names and string inserts should not be translated</comment>
2384
</data>
2385
+ <data name = "MessageWslcTooManyVirtioFsShares" xml:space = "preserve" >
2386
+ <value>Too many volumes have been mounted (limit: {}). Restart the session to mount more volumes. This will be fixed in a future release.</value>
2387
+ <comment>{FixedPlaceholder="{}"}Command line arguments, file names and string inserts should not be translated</comment>
2388
+ </data>
2389
<data name = "MessageWslcPortInUse" xml:space = "preserve" >
2390
<value>Port {} is already in use, cannot start container {}</value>
2391
<comment>{FixedPlaceholder="{}"}Command line arguments, file names and string inserts should not be translated</comment>
src/shared/inc/defs.h
+5
@@ -52,6 +52,11 @@ inline constexpr std::uint32_t VersionMinor = WSL_PACKAGE_VERSION_MINOR;
52
inline constexpr std::uint32_t VersionRevision = WSL_PACKAGE_VERSION_REVISION;
53
inline constexpr std::tuple<uint32_t, uint32_t, uint32_t> PackageVersion{VersionMajor, VersionMinor, VersionRevision};
54
55
+// Maximum number of virtiofs shares that can be mounted (with different paths) over the lifetime of a VM.
56
+// This limit is there to avoid a hang when too many virtiofs shares are mounted.
57
+// TODO: Remove once we can use the same PCI devices for all shares.
58
+inline constexpr size_t c_maxVirtioFsShares = 15;
59
+
60
#ifdef WSL_OFFICIAL_BUILD
61
62
inline constexpr bool OfficialBuild = true;
src/windows/wslcsession/WSLCVirtualMachine.cpp
+7
@@ -1072,6 +1072,13 @@ try
1072
shareGuid = shareIt->second;
1073
reusingShare = true;
1074
}
1075
+ else
1076
+ {
1077
+ THROW_HR_WITH_USER_ERROR_IF(
1078
+ E_OUTOFMEMORY,
1079
+ shared::Localization::MessageWslcTooManyVirtioFsShares(shared::c_maxVirtioFsShares),
1080
+ m_virtioFsShares.size() >= shared::c_maxVirtioFsShares);
1081
+ }
1082
}
1083
1084
if (!reusingShare)
test/windows/WSLCTests.cpp
+50
@@ -3612,6 +3612,56 @@ class WSLCTests
3612
}
3613
}
3614
3615
+ // Validate that the correct error is returned when too many virtiofs shares are mounted.
3616
+ WSLC_TEST_METHOD(VirtiofsVolumesLimit)
3617
+ {
3618
+ constexpr size_t c_maxVirtioFsShares = wsl::shared::c_maxVirtioFsShares;
3619
+
3620
+ auto settings = GetDefaultSessionSettings(L"virtiofs-share-limit-test");
3621
+ WI_SetFlag(settings.FeatureFlags, WslcFeatureFlagsVirtioFs);
3622
+
3623
+ // Use a dedicated session so the share count starts at zero (no GPU libraries are mounted).
3624
+ auto session = CreateSession(settings);
3625
+
3626
+ auto testRoot = std::filesystem::current_path() / "test-folder-share-limit";
3627
+ std::filesystem::create_directories(testRoot);
3628
+ auto cleanup = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&]() { std::filesystem::remove_all(testRoot); });
3629
+
3630
+ auto folderForIndex = [&](size_t index) {
3631
+ auto folder = testRoot / std::to_string(index);
3632
+ std::filesystem::create_directories(folder);
3633
+ return folder;
3634
+ };
3635
+
3636
+ // Mount distinct Windows folders (each creates a new share) until the limit is reached.
3637
+ size_t mounted = 0;
3638
+ HRESULT lastResult = S_OK;
3639
+ for (size_t i = 0; i <= c_maxVirtioFsShares; ++i)
3640
+ {
3641
+ auto folder = folderForIndex(i);
3642
+ auto mountPoint = std::format("/vfs-limit-{}", i);
3643
+
3644
+ lastResult = session->MountWindowsFolder(folder.c_str(), mountPoint.c_str(), false);
3645
+ if (FAILED(lastResult))
3646
+ {
3647
+ break;
3648
+ }
3649
+
3650
+ mounted++;
3651
+ }
3652
+
3653
+ VERIFY_ARE_EQUAL(mounted, c_maxVirtioFsShares);
3654
+ VERIFY_ARE_EQUAL(lastResult, E_OUTOFMEMORY);
3655
+ ValidateCOMErrorMessage(
3656
+ L"Too many volumes have been mounted (limit: 15). Restart the session to mount more volumes. This will be fixed in a "
3657
+ L"future release.");
3658
+
3659
+ // Reusing an already-created share must still succeed.
3660
+ auto reusedFolder = folderForIndex(0);
3661
+ VERIFY_SUCCEEDED(session->MountWindowsFolder(reusedFolder.c_str(), "/vfs-limit-reuse", false));
3662
+ VERIFY_SUCCEEDED(session->UnmountWindowsFolder("/vfs-limit-reuse"));
3663
+ }
3664
+
3665
// This test case validates that no file descriptors are leaked to user processes.
3666
WSLC_TEST_METHOD(Fd)
3667
{