Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions src/linux/init/WSLCInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Module Name:
#include "message.h"
#include "localhost.h"
#include "common.h"
#include "drvfs.h"
#include <utmp.h>
#include <unistd.h>
#include <sys/wait.h>
Expand Down Expand Up @@ -652,8 +653,22 @@ void HandleMessageImpl(
// Chroot without OverlayFs is not supported — the chroot logic depends on the overlay target path.
THROW_ERRNO_IF(EINVAL, WI_IsFlagSet(Message.Flags, WSLC_MOUNT::Chroot) && !WI_IsFlagSet(Message.Flags, WSLC_MOUNT::OverlayFs));

auto type = readField(Message.TypeIndex);
THROW_LAST_ERROR_IF(UtilMount(source, target, type, options.MountFlags, options.StringOptions.c_str(), c_defaultRetryTimeout) < 0);
const char* type = readField(Message.TypeIndex);
const char* subname = readField(Message.SubnameIndex);
if (*subname != '\0' && strcmp(type, "virtiofs") == 0)
{
//
// Windows-folder share routed through the single aggregate
// virtio-fs device: bind-mount the child identified by Subname
// instead of mounting a dedicated device. The helper re-parses
// the raw option string itself, so pass it through unparsed.
//
THROW_LAST_ERROR_IF(MountVirtioFsAggregateChild(source, subname, target, readField(Message.OptionsIndex)) < 0);
}
else
{
THROW_LAST_ERROR_IF(UtilMount(source, target, type, options.MountFlags, options.StringOptions.c_str(), c_defaultRetryTimeout) < 0);
}

// Workaround for a Linux bug where virtiofs permissions aren't properly propagated when an overlay is mounted on top of a virtiofs share before the permissions have been fetched.
// TODO: Remove once fixed upstream.
Expand Down
55 changes: 48 additions & 7 deletions src/linux/init/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1706,10 +1706,23 @@ Return Value:
while (MountEnum.Next())
{
//
// Do not consider bind mounts.
// Skip non-root mounts (bind mounts), with one exception: aggregate
// virtio-fs shares are always bind-mounts from the aggregate device's
// synthetic-root child, so virtiofs entries with Root != "/" are
// legitimate drvfs mounts whose subname is encoded in Root.
//

if (strcmp(MountEnum.Current().Root, "/") != 0)
const bool IsVirtioFs = (strcmp(MountEnum.Current().FileSystemType, VIRTIO_FS_TYPE) == 0);
if (!IsVirtioFs && strcmp(MountEnum.Current().Root, "/") != 0)
{
continue;
}

//
// The aggregate-device root mounts under VIRTIOFS_AGGREGATE_ROOT_DIR
// are internal infrastructure (not user-visible drvfs targets); skip.
//
if (IsVirtioFs && wsl::shared::string::StartsWith(MountEnum.Current().MountPoint, VIRTIOFS_AGGREGATE_ROOT_DIR "/"))
{
continue;
}
Expand All @@ -1732,9 +1745,15 @@ Return Value:
MountSource = MountEnum.Current().Source;
UtilCanonicalisePathSeparator(MountSource, PATH_SEP_NT);
}
else if (strcmp(MountEnum.Current().FileSystemType, VIRTIO_FS_TYPE) == 0)
else if (IsVirtioFs)
{
MountSource = QueryVirtiofsMountSource(MountEnum.Current().Source);
//
// For aggregate shares, derive the subname from Root (strip leading "/").
// Legacy direct-mount shares have Root == "/" → empty subname.
//
const char* Root = MountEnum.Current().Root;
const char* Subname = (Root && Root[0] == '/') ? Root + 1 : (Root ? Root : "");
MountSource = QueryVirtiofsMountSource(MountEnum.Current().Source, Subname);
}
else
{
Expand Down Expand Up @@ -2327,10 +2346,26 @@ try
//
// Bind mounts which have a root other than / are currently not supported.
//
// TODO_LX: Support bind mounts.
//
// Skip non-root mounts (bind mounts), except for aggregate virtio-fs
// shares which are themselves bind-mounts from the aggregate device's
// synthetic-root child. For those, Root encodes "/<subname>".
//
// TODO_LX: Support arbitrary bind mounts.
//

if (strcmp(MountEntry.Root, "/") != 0)
const bool IsVirtioFs = (strcmp(MountEntry.FileSystemType, VIRTIO_FS_TYPE) == 0);
if (!IsVirtioFs && strcmp(MountEntry.Root, "/") != 0)
{
continue;
}

//
// The aggregate-device root mounts under VIRTIOFS_AGGREGATE_ROOT_DIR
// are internal infrastructure (not user-visible drvfs targets); skip
// them so they're not torn down and remounted incorrectly.
//
if (IsVirtioFs && wsl::shared::string::StartsWith(MountEntry.MountPoint, VIRTIOFS_AGGREGATE_ROOT_DIR "/"))
{
continue;
}
Expand Down Expand Up @@ -2447,7 +2482,13 @@ try
}
else if (strcmp(MountEntry.FileSystemType, VIRTIO_FS_TYPE) == 0)
{
RemountVirtioFs(MountEntry.Source, MountEntry.MountPoint, MountEntry.MountOptions, Message->Admin);
//
// Derive aggregate-child subname from Root ("/<subname>", or "/"
// for legacy direct-mount shares).
//
const char* Root = MountEntry.Root;
const char* Subname = (Root && Root[0] == '/') ? Root + 1 : (Root ? Root : "");
RemountVirtioFs(MountEntry.Source, Subname, MountEntry.MountPoint, MountEntry.MountOptions, Message->Admin);
}
else
{
Expand Down
Loading
Loading