Fix Lost sub directory structure when mapping to a VHD volume#40857
Fix Lost sub directory structure when mapping to a VHD volume#40857kvega005 wants to merge 25 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes an issue where newly formatted ext4 VHD-backed named volumes appear non-empty due to the default lost+found directory, which causes Docker to skip initial copy-up (seeding) from the container image.
Changes:
- Removes
lost+foundfrom freshly formatted (and re-opened) VHD-backed ext4 volumes when it is the only root entry, enabling Docker seeding behavior. - Adds
WSLCVirtualMachinehelpers to list a directory and remove an empty directory in the guest VM. - Adds an end-to-end regression test to validate VHD volume seeding and absence of
lost+found, plus a new localized warning string.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| test/windows/WSLCTests.cpp | Adds an e2e test verifying VHD named volumes seed image data and do not contain lost+found. |
| src/windows/wslcsession/WSLCVirtualMachine.h | Declares new helpers for removing an empty directory and listing directory contents. |
| src/windows/wslcsession/WSLCVirtualMachine.cpp | Implements the new helpers using guest rmdir and ls -A. |
| src/windows/wslcsession/WSLCVhdVolume.cpp | Removes lost+found post-format/mount (create + open paths) when it is the sole root entry; emits warning if removal fails. |
| localization/strings/en-US/Resources.resw | Adds a warning string for when lost+found cannot be removed. |
| </data> | ||
| <data name="MessageWslcVolumeLostFoundNotEmpty" xml:space="preserve"> | ||
| <value>Volume '{}' has a non-empty lost+found directory. It was left in place and the volume may not be seeded with image contents.</value> | ||
| <comment>{FixedPlaceholder="{}"}Command line arguments, file names and string inserts should not be translated</comment> |
OneBlue
left a comment
There was a problem hiding this comment.
Change looks good, minor comment in ListDirectory's implementation
| return {}; | ||
| } | ||
|
|
||
| return wsl::shared::string::Split(stdOut->second, '\n'); |
There was a problem hiding this comment.
Unfortunately it's possible to create files named '\n' in linux, which would break this.
If we want to enumerate files at a given path, I think the easiest solution would be to create a new message type. Something like (WSLC_LISTDIR), and use wsl::shared::string::ArrayFromSpan() to read the list on the Windows side (similar for what we do for the the environment in WSLC_EXEC for instance)
|
|
||
| auto mountCleanup = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&]() { VirtualMachine.Unmount(virtualMachinePath.c_str()); }); | ||
|
|
||
| // mkfs.ext4 always creates a lost+found directory at the filesystem root, |
There was a problem hiding this comment.
Would it be another option to not create the lost and found directory? maybe this is configurable via an option to mkfs?
|
As an alternative, could we use a subdirectory in the ext4 filesystem for the data so docker doesn't see the lost+found? |
Summary of the Pull Request
Fixes VHD-backed named volumes showing only an empty
lost+founddirectory instead of the container image's contents on first use.When a VHD volume is formatted with
mkfs.ext4, ext4 always creates alost+founddirectory at the filesystem root. Docker only seeds a named volume with the image's contents (copy-up) when the volume appears empty, so the straylost+foundmade VHD volumes look non-empty and silently suppressed seeding — guest (Docker-native) volumes were unaffected. This change removes thelost+founddirectory after formatting so VHD volumes seed just like guest volumes.PR Checklist
en-US/Resources.reswDetailed Description of the Pull Request / Additional comments
Root cause: ext4's
lost+foundmakes a freshly formatted VHD volume non-empty, so Docker skips copy-up and the image's files never get seeded into the volume.Changes:
WSLCVhdVolume: After formatting + mounting,RemoveLostFoundDirectory()stripslost+foundso Docker seeds the volume. The deletion is gated: it only runs whenlost+foundis the sole entry in the volume root, so a volume that already holds data is never touched. Becausermdironly removes empty directories, alost+foundthat captured recovered data is left intact and a localized warning is emitted.Open) path, so volumes created before this fix get migrated (seeded) on next reattach.Notes:
fsck/e2fsck, solost+founddoes not reappear once removed.Validation Steps Performed
NamedVolumesVhdSeedsImageData: creates a VHD volume, mounts it over/etc(guaranteed-populated by the Debian test image), and verifies the image's/etccontent (passwd) is seeded whilelost+foundis absent.lost+foundvisible) and confirmed the fix seeds image contents.