Skip to content

Fix Lost sub directory structure when mapping to a VHD volume#40857

Open
kvega005 wants to merge 25 commits into
microsoft:masterfrom
kvega005:lost+found
Open

Fix Lost sub directory structure when mapping to a VHD volume#40857
kvega005 wants to merge 25 commits into
microsoft:masterfrom
kvega005:lost+found

Conversation

@kvega005

Copy link
Copy Markdown
Contributor

Summary of the Pull Request

Fixes VHD-backed named volumes showing only an empty lost+found directory instead of the container image's contents on first use.

When a VHD volume is formatted with mkfs.ext4, ext4 always creates a lost+found directory at the filesystem root. Docker only seeds a named volume with the image's contents (copy-up) when the volume appears empty, so the stray lost+found made VHD volumes look non-empty and silently suppressed seeding — guest (Docker-native) volumes were unaffected. This change removes the lost+found directory after formatting so VHD volumes seed just like guest volumes.

PR Checklist

  • Closes: #xxx
  • Communication: Discussed with WSLC contributors
  • Tests: Added an e2e test; existing volume tests pass
  • Localization: New warning string added to en-US/Resources.resw
  • Dev docs: N/A
  • Documentation updated: N/A

Detailed Description of the Pull Request / Additional comments

Root cause: ext4's lost+found makes 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() strips lost+found so Docker seeds the volume. The deletion is gated: it only runs when lost+found is the sole entry in the volume root, so a volume that already holds data is never touched. Because rmdir only removes empty directories, a lost+found that captured recovered data is left intact and a localized warning is emitted.
  • Applied on both the create path and the recovery (Open) path, so volumes created before this fix get migrated (seeded) on next reattach.

Notes:

  • WSLC never runs fsck/e2fsck, so lost+found does not reappear once removed.

Validation Steps Performed

  • Added a test NamedVolumesVhdSeedsImageData: creates a VHD volume, mounts it over /etc (guaranteed-populated by the Debian test image), and verifies the image's /etc content (passwd) is seeded while lost+found is absent.
  • Manually reproduced the original bug (only lost+found visible) and confirmed the fix seeds image contents.

Copilot AI review requested due to automatic review settings June 19, 2026 18:22

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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+found from freshly formatted (and re-opened) VHD-backed ext4 volumes when it is the only root entry, enabling Docker seeding behavior.
  • Adds WSLCVirtualMachine helpers 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.

Comment thread src/windows/wslcsession/WSLCVhdVolume.cpp
Comment thread localization/strings/en-US/Resources.resw
@kvega005 kvega005 marked this pull request as ready for review June 19, 2026 19:56
@kvega005 kvega005 requested a review from a team as a code owner June 19, 2026 19:56
Copilot AI review requested due to automatic review settings June 19, 2026 19:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

</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 OneBlue left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change looks good, minor comment in ListDirectory's implementation

return {};
}

return wsl::shared::string::Split(stdOut->second, '\n');

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be another option to not create the lost and found directory? maybe this is configurable via an option to mkfs?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sadly it's not an option

Copilot AI review requested due to automatic review settings June 22, 2026 21:08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Comment thread src/windows/wslcsession/WSLCVhdVolume.cpp
@benhillis

Copy link
Copy Markdown
Member

As an alternative, could we use a subdirectory in the ext4 filesystem for the data so docker doesn't see the lost+found?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants