Skip to content

virtiofs=true: automount of ALL fixed drives is silently skipped when AddVirtioFsShare fails for a single drive #40773

@moto-pu

Description

@moto-pu

Windows Version

Microsoft Windows [Version 10.0.26200.8655]

WSL Version

2.7.8.0

Are you using WSL 1 or WSL 2?

  • WSL 2
  • WSL 1

Kernel Version

6.18.33.1-1

Distro Version

Ubuntu 24.04

Other Software

Docker Desktop 4.77.0 (its docker-desktop distro is also affected, see below)

Repro Steps

Machine has two fixed NTFS drives: C: (NVMe) and P: (SATA). Both automount fine via 9p when virtiofs is disabled.

  1. Add virtiofs=true to the [wsl2] section of .wslconfig
  2. wsl --shutdown, start the distro
  3. mount | grep /mnt

Expected Behavior

/mnt/c and /mnt/p are automounted (virtiofs where possible, 9p fallback otherwise), as documented for the virtiofs opt-in.

Actual Behavior

No fixed drive is automounted at all/mnt/c and /mnt/p simply don't exist as mounts. There is no warning on the terminal, nothing in dmesg and nothing in the boot log. Interop path translation also degrades (wsl: Failed to translate 'C:\...' warnings for every PATH entry when launching Windows executables from another distro).

The virtiofs device for C: is created and works — the tag is visible at kernel boot and a manual mount succeeds:

[    0.253334] virtiofs virtio1: discovered new tag: f8407c95-93b2-41f6-ac92-7b8deb88fd19
$ sudo mount -t virtiofs f8407c95-... /mnt/c   # works fine

Meanwhile the share for P: is never created. Requesting it manually shows the failure that I believe poisons the whole automount:

$ sudo mount -t drvfs 'P:\' /mnt/p
WSL (...) WARNING: Add virtiofs share for P:\ failed 22, falling back to Plan9

(P: is a plain healthy NTFS volume on a SATA SSD, DriveType: Fixed; the 9p fallback works fine, so per-drive fallback clearly exists for the runtime path — just not for the boot path.)

Analysis (from the 2.7.8 sources)

WslCoreVm::AddDrvFsShare (src/windows/service/exe/WslCoreVm.cpp, around line 859) loops over the fixed-drive bitmap and calls AddVirtioFsShare for each drive without any per-drive error handling:

auto fixedDrives = wsl::windows::common::filesystem::EnumerateFixedDrives(UserToken).first;
while (fixedDrives != 0)
{
    ...
    AddVirtioFsShare(Admin, fixedDrivePath, TEXT(LX_INIT_DEFAULT_PLAN9_MOUNT_OPTIONS), UserToken);
    fixedDrives ^= (1 << index);
}

If AddVirtioFsShare throws for any single drive (here: P:, error 22/EINVAL), the exception propagates out of InitializeDrvFs, so the instance reports LxInitDrvfsMountNone to init. On the Linux side (src/linux/init/config.cpp:726):

if (Config.AutoMount && (Message->DrvfsMount != LxInitDrvfsMountNone))
{
    ConfigMountDrvFsVolumes(Message->DrvFsVolumesBitmap, DefaultUid, Elevated, Config);
}

…which silently skips all volumes, including the perfectly healthy C: whose virtiofs device already exists. Since InitializeDrvFs is VM-wide, every distro in the VM loses its drive mounts (Docker Desktop's docker-desktop distro ends up without /mnt/host/c as well, which breaks Windows-path bind mounts).

Two issues, in order of impact:

  1. One failing drive should not disable automount for all drives. A per-drive try/catch around AddVirtioFsShare with a 9p fallback (like the runtime path in MountVirtioFs already does) would keep everything working.
  2. The failure is completely silent — an EMIT_USER_WARNING would have saved a lot of debugging.

I have not been able to determine from the outside why AddVirtioFsShare fails with EINVAL for this particular volume — happy to collect WslLogs / networking.sh output or test a private build if that helps.

Workaround

A boot script that, when /mnt/c is not mounted, finds the drive tag via /sys/fs/virtiofs/*/tag, mounts it manually, recreates the /run/wsl/virtiofs/<tag> symlink (needed for interop path translation), and mounts the remaining drives via mount -t drvfs (9p fallback). Works reliably across reboots.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions