From beef109d005dbd9366e372e362c502eef4afed4f Mon Sep 17 00:00:00 2001 From: Ben Hillis Date: Mon, 2 Feb 2026 15:36:34 -0800 Subject: [PATCH] virtiofs: exit QueryVirtiofsMountSource early if virtiofs disabled --- src/linux/init/config.cpp | 11 +++----- src/linux/init/config.h | 4 +-- src/linux/init/drvfs.cpp | 29 ++++++++++++++++----- src/linux/init/drvfs.h | 2 +- src/linux/init/util.cpp | 55 +++++++++++++++++++++++++++------------ src/linux/init/util.h | 4 ++- 6 files changed, 71 insertions(+), 34 deletions(-) diff --git a/src/linux/init/config.cpp b/src/linux/init/config.cpp index d0133ba7..5f6d29db 100644 --- a/src/linux/init/config.cpp +++ b/src/linux/init/config.cpp @@ -679,12 +679,7 @@ try // Config.FeatureFlags = Message->FeatureFlags; - char FeatureFlagsString[10]; - snprintf(FeatureFlagsString, sizeof(FeatureFlagsString), "%x", Config.FeatureFlags.value()); - if (setenv(WSL_FEATURE_FLAGS_ENV, FeatureFlagsString, 1) < 0) - { - LOG_ERROR("setenv failed {}", errno); - } + UtilSetFeatureFlags(Config.FeatureFlags.value()); // // Determine the default UID which can be specified in /etc/wsl.conf. @@ -2413,7 +2408,7 @@ try NewMountOptions = MountEntry.MountOptions; NewMountOptions += ','; - if (WSL_USE_VIRTIO_9P(Config)) + if (WSL_USE_VIRTIO_9P()) { // // Check if the existing mount is a drvfs mount that needs to be remounted. @@ -2446,7 +2441,7 @@ try NewMountOptions += ','; } - MountPlan9Share(NewSource, MountEntry.MountPoint, NewMountOptions.c_str(), Message->Admin, Config); + MountPlan9Share(NewSource, MountEntry.MountPoint, NewMountOptions.c_str(), Message->Admin); } else if (strcmp(MountEntry.FileSystemType, VIRTIO_FS_TYPE) == 0) { diff --git a/src/linux/init/config.h b/src/linux/init/config.h index d8c63f11..bec5d71c 100644 --- a/src/linux/init/config.h +++ b/src/linux/init/config.h @@ -23,8 +23,8 @@ Abstract: #include "SocketChannel.h" #include "WslDistributionConfig.h" -#define WSL_USE_VIRTIO_9P(_Config) (WI_IsFlagSet(UtilGetFeatureFlags((_Config)), LxInitFeatureVirtIo9p)) -#define WSL_USE_VIRTIO_FS(_Config) (WI_IsFlagSet(UtilGetFeatureFlags((_Config)), LxInitFeatureVirtIoFs)) +#define WSL_USE_VIRTIO_9P() (WI_IsFlagSet(UtilGetFeatureFlags(), LxInitFeatureVirtIo9p)) +#define WSL_USE_VIRTIO_FS() (WI_IsFlagSet(UtilGetFeatureFlags(), LxInitFeatureVirtIoFs)) #define WSLG_SHARED_FOLDER "wslg" #define INIT_MAKE_SECURITY(_uid, _gid, _mode) {_uid, _gid, _mode} diff --git a/src/linux/init/drvfs.cpp b/src/linux/init/drvfs.cpp index 22be756d..94355717 100644 --- a/src/linux/init/drvfs.cpp +++ b/src/linux/init/drvfs.cpp @@ -298,7 +298,7 @@ try { return MountFilesystem(DRVFS_FS_TYPE, Source, Target, Options, ExitCode); } - else if (WSL_USE_VIRTIO_FS(Config)) + else if (WSL_USE_VIRTIO_FS()) { return MountVirtioFs(Source, Target, Options, Admin, Config, ExitCode); } @@ -349,7 +349,7 @@ Return Value: return ExitCode; } -int MountPlan9Share(const char* Source, const char* Target, const char* Options, bool Admin, const wsl::linux::WslDistributionConfig& Config, int* ExitCode) +int MountPlan9Share(const char* Source, const char* Target, const char* Options, bool Admin, int* ExitCode) /*++ @@ -367,8 +367,6 @@ Arguments: Admin - Supplies a boolean specifying if the admin share should be used. - Config - Supplies the distribution configuration. - ExitCode - Supplies an optional pointer that receives the exit code. Return Value: @@ -379,7 +377,7 @@ Return Value: { std::string MountOptions; - if (WSL_USE_VIRTIO_9P(Config)) + if (WSL_USE_VIRTIO_9P()) { Source = Admin ? LX_INIT_DRVFS_ADMIN_VIRTIO_TAG : LX_INIT_DRVFS_VIRTIO_TAG; MountOptions = std::format("msize=262144,trans=virtio,{}", Options); @@ -476,7 +474,7 @@ try // MountOptions += Plan9Options; - if (MountPlan9Share(Source, Target, MountOptions.c_str(), Elevated, Config, ExitCode) < 0) + if (MountPlan9Share(Source, Target, MountOptions.c_str(), Elevated, ExitCode) < 0) { return -1; } @@ -515,6 +513,8 @@ Return Value: try { + assert(WSL_USE_VIRTIO_FS()); + // // Check whether to use the elevated or non-elevated virtiofs server. // @@ -596,6 +596,8 @@ Return Value: try { + assert(WSL_USE_VIRTIO_FS()); + wsl::shared::MessageWriter RemountShare(LxInitMessageRemountVirtioFsDevice); RemountShare->Admin = Admin; RemountShare.WriteString(RemountShare->TagOffset, Tag); @@ -643,6 +645,21 @@ Return Value: try { + if (!WSL_USE_VIRTIO_FS()) + { + return {}; + } + + // + // Validate the tag is a GUID. + // + + const auto Guid = wsl::shared::string::ToGuid(Tag); + if (!Guid) + { + return {}; + } + wsl::shared::MessageWriter QueryShare(LxInitMessageQueryVirtioFsDevice); QueryShare.WriteString(QueryShare->TagOffset, Tag); diff --git a/src/linux/init/drvfs.h b/src/linux/init/drvfs.h index 2f83e544..682e08d1 100644 --- a/src/linux/init/drvfs.h +++ b/src/linux/init/drvfs.h @@ -23,7 +23,7 @@ int MountDrvfs(const char* Source, const char* Target, const char* Options, std: int MountDrvfsEntry(int Argc, char* Argv[]); -int MountPlan9Share(const char* Source, const char* Target, const char* Options, bool Admin, const wsl::linux::WslDistributionConfig& Config, int* ExitCode = nullptr); +int MountPlan9Share(const char* Source, const char* Target, const char* Options, bool Admin, int* ExitCode = nullptr); int MountPlan9(const char* Source, const char* Target, const char* Options, std::optional Admin, const wsl::linux::WslDistributionConfig& Config, int* ExitCode); diff --git a/src/linux/init/util.cpp b/src/linux/init/util.cpp index 1a782e2d..3cc0ae4c 100644 --- a/src/linux/init/util.cpp +++ b/src/linux/init/util.cpp @@ -53,6 +53,7 @@ Abstract: #define WSL_MOUNT_OPTION_SEP ',' int g_IsVmMode = -1; +static std::optional g_CachedFeatureFlags; static sigset_t g_originalSignals; thread_local std::string g_threadName; @@ -1119,7 +1120,7 @@ catch (...) return {}; } -int UtilGetFeatureFlags(const wsl::linux::WslDistributionConfig& Config) +int UtilGetFeatureFlags() /*++ @@ -1130,7 +1131,7 @@ Routine Description: Arguments: - Config - Supplies the distribution config. + None. Return Value: @@ -1143,21 +1144,11 @@ Return Value: // If feature flags are already known, return them. // - static std::optional g_CachedFeatureFlags; if (g_CachedFeatureFlags) { return *g_CachedFeatureFlags; } - // - // If an error occurs, just return no features. - // - - if (Config.FeatureFlags.has_value()) - { - return Config.FeatureFlags.value(); - } - // // Check if the environment variable is present. // @@ -1167,9 +1158,7 @@ Return Value: // int FeatureFlags = LxInitFeatureNone; - const char* FeatureFlagEnv = getenv(WSL_FEATURE_FLAGS_ENV); - if (FeatureFlagEnv != nullptr) { FeatureFlags = strtol(FeatureFlagEnv, nullptr, 16); @@ -1177,7 +1166,7 @@ Return Value: else { // - // Query init for the value. + // Query init for the value. If an error occurs, just return no features. // wsl::shared::SocketChannel channel{UtilConnectUnix(WSL_INIT_INTEROP_SOCKET), "wslinfo"}; @@ -1194,10 +1183,44 @@ Return Value: FeatureFlags = channel.ReceiveMessage>().Result; } - g_CachedFeatureFlags = FeatureFlags; + UtilSetFeatureFlags(FeatureFlags, FeatureFlagEnv == nullptr); return FeatureFlags; } +void UtilSetFeatureFlags(int FeatureFlags, bool UpdateEnv) + +/*++ + +Routine Description: + + This routine sets the feature flags and updates the cached value and environment variable. + +Arguments: + + FeatureFlags - Supplies the feature flags to set. + + UpdateEnv - Supplies a boolean that indicates whether the environment variable should be updated. + +Return Value: + + None. + +--*/ + +try +{ + g_CachedFeatureFlags = FeatureFlags; + if (UpdateEnv) + { + auto FeatureFlagsString = std::format("{:x}", FeatureFlags); + if (setenv(WSL_FEATURE_FLAGS_ENV, FeatureFlagsString.c_str(), 1) < 0) + { + LOG_ERROR("setenv({}, {}, 1) failed {}", WSL_FEATURE_FLAGS_ENV, FeatureFlagsString, errno); + } + } +} +CATCH_LOG() + std::optional UtilGetNetworkingMode(void) /*++ diff --git a/src/linux/init/util.h b/src/linux/init/util.h index f7b168df..892500b1 100644 --- a/src/linux/init/util.h +++ b/src/linux/init/util.h @@ -223,7 +223,9 @@ std::optional UtilGetEnv(const char* Name, char* Environment); std::string UtilGetEnvironmentVariable(const char* Name); -int UtilGetFeatureFlags(const wsl::linux::WslDistributionConfig& Config); +int UtilGetFeatureFlags(); + +void UtilSetFeatureFlags(int FeatureFlags, bool UpdateEnv = true); std::optional UtilGetNetworkingMode(void);