From 456b68125fa36df8726f0fed52020512cb7722d7 Mon Sep 17 00:00:00 2001 From: Blue Date: Tue, 10 Jun 2025 11:08:01 -0700 Subject: [PATCH] Correctly report corrupted disks when mount() fails with EUCLEAN (#13078) --- src/windows/service/exe/WslCoreInstance.cpp | 3 +- test/windows/UnitTests.cpp | 37 ++++++++++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/windows/service/exe/WslCoreInstance.cpp b/src/windows/service/exe/WslCoreInstance.cpp index 3ecaa8e..1765c55 100644 --- a/src/windows/service/exe/WslCoreInstance.cpp +++ b/src/windows/service/exe/WslCoreInstance.cpp @@ -59,7 +59,8 @@ WslCoreInstance::WslCoreInstance( if (result.Result != 0) { - if (result.Result == EINVAL && result.FailureStep == LxInitCreateInstanceStepMountDisk) + // N.B. EUCLEAN (117) can be returned if the disk's journal is corrupted. + if ((result.Result == EINVAL || result.Result == 117) && result.FailureStep == LxInitCreateInstanceStepMountDisk) { THROW_HR(WSL_E_DISK_CORRUPTED); } diff --git a/test/windows/UnitTests.cpp b/test/windows/UnitTests.cpp index 092fc6b..afbded6 100644 --- a/test/windows/UnitTests.cpp +++ b/test/windows/UnitTests.cpp @@ -2294,7 +2294,8 @@ Error code: Wsl/InstallDistro/WSL_E_DISTRO_NOT_FOUND WSL2_TEST_ONLY(); // Create a 100MB vhd without a filesystem. - auto vhdPath = std::filesystem::weakly_canonical(wil::GetCurrentDirectoryW() + L"\\CorruptedTest.vhdx"); + auto distroPath = std::filesystem::weakly_canonical(wil::GetCurrentDirectoryW()); + auto vhdPath = distroPath / L"CorruptedTest.vhdx"; VIRTUAL_STORAGE_TYPE storageType{}; storageType.DeviceId = VIRTUAL_STORAGE_TYPE_DEVICE_VHDX; @@ -2332,6 +2333,40 @@ Error code: Wsl/InstallDistro/WSL_E_DISTRO_NOT_FOUND vhd.reset(); + // Create a broken distribution registration + { + const auto userKey = wsl::windows::common::registry::OpenLxssUserKey(); + const auto distroKey = + wsl::windows::common::registry::CreateKey(userKey.get(), L"{baa405ef-1822-4bbe-84e2-30e4c6330d42}"); + + auto revert = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&] { + wsl::windows::common::registry::DeleteKey(userKey.get(), L"{baa405ef-1822-4bbe-84e2-30e4c6330d42}"); + }); + + wsl::windows::common::registry::WriteString(distroKey.get(), nullptr, L"BasePath", distroPath.c_str()); + wsl::windows::common::registry::WriteString(distroKey.get(), nullptr, L"VhdFileName", L"CorruptedTest.vhdx"); + wsl::windows::common::registry::WriteString(distroKey.get(), nullptr, L"DistributionName", L"BrokenDistro"); + wsl::windows::common::registry::WriteDword(distroKey.get(), nullptr, L"DefaultUid", 0); + wsl::windows::common::registry::WriteDword(distroKey.get(), nullptr, L"Version", LXSS_DISTRO_VERSION_2); + wsl::windows::common::registry::WriteDword(distroKey.get(), nullptr, L"State", LxssDistributionStateInstalled); + wsl::windows::common::registry::WriteDword(distroKey.get(), nullptr, L"Flags", LXSS_DISTRO_FLAGS_VM_MODE); + + // Validate that starting the distribution fails with the correct error code. + validateOutput( + L"-d BrokenDistro echo ok", + L"The distribution failed to start because its virtual disk is corrupted.\r\n" + L"Error code: Wsl/Service/CreateInstance/WSL_E_DISK_CORRUPTED\r\n"); + + // Validate that trying to export the distribution fails with the correct error code. + validateOutput( + L"--export BrokenDistro dummy.tar", + L"The distribution failed to start because its virtual disk is corrupted.\r\n" + L"Error code: Wsl/Service/WSL_E_DISK_CORRUPTED\r\n"); + + // Shutdown WSL to force the disk to detach. + VERIFY_ARE_EQUAL(LxsstuLaunchWsl(L"--shutdown"), 0L); + } + // Import a corrupted vhd. validateOutput( std::format(L"--import-in-place test-distro-corrupted \"{}\"", vhdPath.wstring()),