Correctly report corrupted disks when mount() fails with EUCLEAN (#13078)

Blue committed Jun 10, 2025 at 11:08 UTC 456b68125fa36df8726f0fed52020512cb7722d7
2 files changed +38 -2
src/windows/service/exe/WslCoreInstance.cpp
+2 -1
@@ -59,7 +59,8 @@ WslCoreInstance::WslCoreInstance(
59
60 if (result.Result != 0)
61 {
62 - if (result.Result == EINVAL && result.FailureStep == LxInitCreateInstanceStepMountDisk)
62 + // N.B. EUCLEAN (117) can be returned if the disk's journal is corrupted.
63 + if ((result.Result == EINVAL || result.Result == 117) && result.FailureStep == LxInitCreateInstanceStepMountDisk)
64 {
65 THROW_HR(WSL_E_DISK_CORRUPTED);
66 }
test/windows/UnitTests.cpp
+36 -1
@@ -2294,7 +2294,8 @@ Error code: Wsl/InstallDistro/WSL_E_DISTRO_NOT_FOUND
2294 WSL2_TEST_ONLY();
2295
2296 // Create a 100MB vhd without a filesystem.
2297 - auto vhdPath = std::filesystem::weakly_canonical(wil::GetCurrentDirectoryW<std::wstring>() + L"\\CorruptedTest.vhdx");
2297 + auto distroPath = std::filesystem::weakly_canonical(wil::GetCurrentDirectoryW<std::wstring>());
2298 + auto vhdPath = distroPath / L"CorruptedTest.vhdx";
2299
2300 VIRTUAL_STORAGE_TYPE storageType{};
2301 storageType.DeviceId = VIRTUAL_STORAGE_TYPE_DEVICE_VHDX;
@@ -2332,6 +2333,40 @@ Error code: Wsl/InstallDistro/WSL_E_DISTRO_NOT_FOUND
2333
2334 vhd.reset();
2335
2336 + // Create a broken distribution registration
2337 + {
2338 + const auto userKey = wsl::windows::common::registry::OpenLxssUserKey();
2339 + const auto distroKey =
2340 + wsl::windows::common::registry::CreateKey(userKey.get(), L"{baa405ef-1822-4bbe-84e2-30e4c6330d42}");
2341 +
2342 + auto revert = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&] {
2343 + wsl::windows::common::registry::DeleteKey(userKey.get(), L"{baa405ef-1822-4bbe-84e2-30e4c6330d42}");
2344 + });
2345 +
2346 + wsl::windows::common::registry::WriteString(distroKey.get(), nullptr, L"BasePath", distroPath.c_str());
2347 + wsl::windows::common::registry::WriteString(distroKey.get(), nullptr, L"VhdFileName", L"CorruptedTest.vhdx");
2348 + wsl::windows::common::registry::WriteString(distroKey.get(), nullptr, L"DistributionName", L"BrokenDistro");
2349 + wsl::windows::common::registry::WriteDword(distroKey.get(), nullptr, L"DefaultUid", 0);
2350 + wsl::windows::common::registry::WriteDword(distroKey.get(), nullptr, L"Version", LXSS_DISTRO_VERSION_2);
2351 + wsl::windows::common::registry::WriteDword(distroKey.get(), nullptr, L"State", LxssDistributionStateInstalled);
2352 + wsl::windows::common::registry::WriteDword(distroKey.get(), nullptr, L"Flags", LXSS_DISTRO_FLAGS_VM_MODE);
2353 +
2354 + // Validate that starting the distribution fails with the correct error code.
2355 + validateOutput(
2356 + L"-d BrokenDistro echo ok",
2357 + L"The distribution failed to start because its virtual disk is corrupted.\r\n"
2358 + L"Error code: Wsl/Service/CreateInstance/WSL_E_DISK_CORRUPTED\r\n");
2359 +
2360 + // Validate that trying to export the distribution fails with the correct error code.
2361 + validateOutput(
2362 + L"--export BrokenDistro dummy.tar",
2363 + L"The distribution failed to start because its virtual disk is corrupted.\r\n"
2364 + L"Error code: Wsl/Service/WSL_E_DISK_CORRUPTED\r\n");
2365 +
2366 + // Shutdown WSL to force the disk to detach.
2367 + VERIFY_ARE_EQUAL(LxsstuLaunchWsl(L"--shutdown"), 0L);
2368 + }
2369 +
2370 // Import a corrupted vhd.
2371 validateOutput(
2372 std::format(L"--import-in-place test-distro-corrupted \"{}\"", vhdPath.wstring()),