Skip to content

aggregate virtiofs: share multiple Windows folders via a single device#40729

Draft
benhillis wants to merge 1 commit into
masterfrom
user/benhill/virtiofs_submount
Draft

aggregate virtiofs: share multiple Windows folders via a single device#40729
benhillis wants to merge 1 commit into
masterfrom
user/benhill/virtiofs_submount

Conversation

@benhillis

Copy link
Copy Markdown
Member

Share Windows folders through aggregate virtio-fs PCI devices instead of creating a separate device per share. Each share becomes a child of an aggregate's synthetic root, addressed by a per-share subname derived from the share GUID, so guest and host agree on the device name without a return channel.

Layers touched:

  • guest (init/drvfs, config, util): mount aggregate virtio-fs children by subname.
  • host (WslCoreVm, HcsVirtualMachine, GuestDeviceManager): lazily create the aggregate device on the first share; register subsequent shares as children via ExtendVirtioFsAggregate.
  • wslc consumer (WSLCVirtualMachine): dedup shares by {path, readOnly} and mount them as children of the aggregate device.
  • shared (stringshared, lxinitshared): subname derivation helper and the fixed aggregate tag constants.

Read-only is enforced host-side for WSLc Windows-folder shares. The device host requires all children of one aggregate to share a single readonly setting, so read-only shares route to a separate read-only aggregate (c_wslcVirtioFsAggregateReadOnlyTag) created with the ro child option; its virtio-fs backend rejects writes (EROFS) regardless of the guest's mount options. Read-write shares continue to use c_wslcVirtioFsAggregateTag. The guest selects the matching tag from the share's read-only flag.

Aggregate children are append-only for the VM lifetime (devices torn down with the VM), so per-share RemoveShare drops only its bookkeeping.

Test fixes: FAT-over-virtiofs (drvfs.c, lxtmount.c), SMB-over-virtiofs DrvFs variations (DrvFsTests.cpp, drvfs.c), and the WSLc Windows-mount read-only host-enforcement check (WSLCTests.cpp), which now binds the share elsewhere, asserts the bind is genuinely rw via findmnt, and confirms writes still fail (EROFS) from the read-only aggregate.

Depends on the openvmm backend change: microsoft/openvmm#3681

Copilot AI review requested due to automatic review settings June 6, 2026 06:12

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 changes Windows-folder sharing over virtio-fs to use aggregate virtio-fs devices (one per bucket) with per-share children addressed by a deterministic subname, reducing the need to create a PCI device per share. It updates both host and guest paths (including WSLc) and adjusts tests to account for the new mount topology (bind mounts from an aggregate synthetic root).

Changes:

  • Add aggregate virtio-fs plumbing: host-side device creation/extension (ExtendVirtioFsAggregate), guest-side mounting via subname, and shared wire/schema updates.
  • Update WSLc Windows-folder mounting to use fixed aggregate tags (+ RO/RW split) and GUID-derived child subnames.
  • Fix/adjust drvfs + mount enumeration logic and unit tests to tolerate aggregate-child roots and virtiofs behavior.

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
test/windows/WSLCTests.cpp Updates read-only enforcement test to validate host-enforced RO via a RW bind mount + findmnt.
test/windows/DrvFsTests.cpp Removes virtiofs-mode skip so the relevant drvfs test runs under virtiofs.
test/linux/unit_tests/lxtmount.c Makes mount-root assertions tolerant of aggregate virtiofs child roots (/<opaque>/...).
test/linux/unit_tests/drvfs.c Adjusts expectations/comments for virtiofs behavior (case/dentry behavior; VM-mode mount limitations).
src/windows/wslcsession/WSLCVirtualMachine.h Extends mount API to include optional Subname; adds case-insensitive virtiofs share cache key compare.
src/windows/wslcsession/WSLCVirtualMachine.cpp Mounts Windows-folder shares as aggregate virtio-fs children using fixed aggregate tags and GUID-derived subnames.
src/windows/service/exe/WslCoreVm.h Updates virtio-fs share API to return {tag, subname, canonicalPath} and adds aggregate tag bookkeeping.
src/windows/service/exe/WslCoreVm.cpp Implements deterministic aggregate subname hashing; switches drvfs virtio-fs sharing to aggregate+children and updates remount/add response payloads.
src/windows/service/exe/HcsVirtualMachine.h Adds state to track lazily-created RW/RO aggregate devices for WSLc sharing.
src/windows/service/exe/HcsVirtualMachine.cpp Switches WSLc AddShare/RemoveShare behavior to aggregate virtio-fs devices and append-only children.
src/windows/common/GuestDeviceManager.h Adds VIRTIO_FS_FLAGS_TYPE_AGGREGATE and declares ExtendVirtioFsAggregate.
src/windows/common/GuestDeviceManager.cpp Implements ExtendVirtioFsAggregate to add children to an existing aggregate without new PCI devices.
src/shared/inc/stringshared.h Adds GuidToHexString() helper for 32-hex, path-safe GUID formatting.
src/shared/inc/lxinitshared.h Extends virtio-fs and WSLc mount message schemas with Subname* fields; adds fixed WSLc aggregate tag GUIDs.
src/linux/init/WSLCInit.cpp Routes WSLC virtiofs mounts with a subname through MountVirtioFsAggregateChild instead of direct virtiofs mounts.
src/linux/init/util.cpp Adjusts virtiofs mount source resolution for aggregate-child bind mounts (uses Root as subname).
src/linux/init/drvfs.h Adds aggregate root dir constant and updates virtiofs APIs to accept an optional Subname.
src/linux/init/drvfs.cpp Adds aggregate-root mounting + child bind-mount helper; extends tag mapping to {Tag,Subname}; updates mount/remount flows accordingly.
src/linux/init/config.cpp Updates drvfs mount enumeration/remounting to treat aggregate-child virtiofs bind mounts as valid and skip internal aggregate-root mounts.

Comment thread src/windows/service/exe/WslCoreVm.cpp
Comment thread src/windows/service/exe/WslCoreVm.h
Comment thread src/windows/service/exe/WslCoreVm.cpp Outdated
@benhillis benhillis force-pushed the user/benhill/virtiofs_submount branch from d38ffce to 3419dca Compare June 6, 2026 07:08
Copilot AI review requested due to automatic review settings June 6, 2026 15:16
@benhillis benhillis force-pushed the user/benhill/virtiofs_submount branch from 3419dca to d99449b Compare June 6, 2026 15:16
@benhillis benhillis force-pushed the user/benhill/virtiofs_submount branch from d99449b to fb368d5 Compare June 6, 2026 15:18

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 19 out of 19 changed files in this pull request and generated 1 comment.

Comment thread src/windows/common/GuestDeviceManager.cpp
Copilot AI review requested due to automatic review settings June 8, 2026 14:53

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 19 out of 19 changed files in this pull request and generated 2 comments.

Comment thread src/windows/common/GuestDeviceManager.cpp
Comment thread src/linux/init/drvfs.cpp Outdated
@benhillis benhillis force-pushed the user/benhill/virtiofs_submount branch from b949ce2 to fb368d5 Compare June 8, 2026 15:32
Share Windows folders through aggregate virtio-fs PCI devices instead
of creating a separate device per share. Each share becomes a child of an
aggregate's synthetic root, addressed by a per-share subname derived from the
share GUID, so the guest and host agree on the device name without a return
channel.

Layers touched:
- guest (init/drvfs, config, util): mount aggregate virtio-fs children by
  subname.
- host (WslCoreVm, HcsVirtualMachine, GuestDeviceManager): lazily create the
  aggregate device on the first share and register subsequent shares as
  children via ExtendVirtioFsAggregate.
- wslc consumer (WSLCVirtualMachine): dedup shares by {path, readOnly} and
  mount them as children of the aggregate device.
- shared (stringshared, lxinitshared): subname derivation helper and the
  fixed aggregate tag constants.

ReadOnly is enforced host-side for WSLc Windows-folder shares. The device
host requires all children of one aggregate to share a single readonly
setting, so read-only shares are routed to a separate read-only aggregate
(c_wslcVirtioFsAggregateReadOnlyTag) created with the "ro" child option;
its virtio-fs backend rejects writes (EROFS) regardless of the guest's mount
options. Read-write shares continue to use c_wslcVirtioFsAggregateTag. The
guest selects the matching tag from the share's read-only flag, so no return
channel is needed.

Aggregate children are append-only for the VM lifetime: the devices are torn
down with the VM, so per-share RemoveShare intentionally drops only its
bookkeeping rather than the shared device (bounded VM-lifetime resource).

Test fixes for FAT-over-virtiofs (drvfs.c, lxtmount.c): the 6.18 fuse guest
driver has no case-insensitive dentry operations, so the FAT32
case-insensitive "first case" /proc/self/fd check is gated off for virtiofs
(like Plan 9). The FAT mount-point junction test is likewise not applicable
in VM mode, where a raw mount(-t drvfs) syscall returns ENODEV, so its Plan 9
exemption is extended to virtiofs. lxtmount MountCheckIsMount accepts the
virtiofs vfs access behavior.

SMB-over-virtiofs DrvFs variations (DrvFsTests.cpp, drvfs.c): enable the
DrvFsSmb test under virtiofs by removing the wslpath //localhost/C$ skip,
which now translates correctly. The SMB case-insensitive variation expects
the on-disk case to change after a case-only rename (FOO), matching SMB over
Plan 9, because NTFS honors the rename and Linux does not treat the mount as
case-insensitive.

WSLc Windows-mount read-only test (WSLCTests.cpp): aggregate children are
bind-mounts of a subdirectory of the shared aggregate root, so a child's
mount SOURCE is not a standalone virtio-fs source that can be remounted
fresh. The host-enforcement check now binds the share elsewhere, clears
read-only on the bind (asserting via findmnt that the bind really is rw),
and confirms the write still fails (EROFS) from the read-only aggregate.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 8, 2026 17:27
@benhillis benhillis force-pushed the user/benhill/virtiofs_submount branch from fb368d5 to 5b79ea9 Compare June 8, 2026 17:27

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 19 out of 19 changed files in this pull request and generated no new comments.

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.

2 participants