aggregate virtiofs: share multiple Windows folders via a single device#40729
Draft
benhillis wants to merge 1 commit into
Draft
aggregate virtiofs: share multiple Windows folders via a single device#40729benhillis wants to merge 1 commit into
benhillis wants to merge 1 commit into
Conversation
Contributor
There was a problem hiding this comment.
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 viasubname, 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. |
d38ffce to
3419dca
Compare
3419dca to
d99449b
Compare
d99449b to
fb368d5
Compare
b949ce2 to
fb368d5
Compare
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>
fb368d5 to
5b79ea9
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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:
ExtendVirtioFsAggregate.{path, readOnly}and mount them as children of the aggregate device.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 therochild option; its virtio-fs backend rejects writes (EROFS) regardless of the guest's mount options. Read-write shares continue to usec_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
RemoveSharedrops 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
rwvia findmnt, and confirms writes still fail (EROFS) from the read-only aggregate.Depends on the openvmm backend change: microsoft/openvmm#3681