@samitouri / QOSAMI-WSL / commits / 68ee60c8

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 {