virtiofs: exit QueryVirtiofsMountSource early if virtiofs disabled (#14149)
Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
Ben Hillis committed
Feb 3, 2026 at 18:02 UTC
8ae97be65077126e4a29349d986e668c86412056
6 files changed
+71
-34
src/linux/init/config.cpp
+3
-8
@@ -679,12 +679,7 @@ try
679
//
680
681
Config.FeatureFlags = Message->FeatureFlags;
682
- char FeatureFlagsString[10];
683
- snprintf(FeatureFlagsString, sizeof(FeatureFlagsString), "%x", Config.FeatureFlags.value());
684
- if (setenv(WSL_FEATURE_FLAGS_ENV, FeatureFlagsString, 1) < 0)
685
- {
686
- LOG_ERROR("setenv failed {}", errno);
687
- }
682
+ UtilSetFeatureFlags(Config.FeatureFlags.value());
683
684
//
685
// Determine the default UID which can be specified in /etc/wsl.conf.
@@ -2413,7 +2408,7 @@ try
2408
2409
NewMountOptions = MountEntry.MountOptions;
2410
NewMountOptions += ',';
2416
- if (WSL_USE_VIRTIO_9P(Config))
2411
+ if (WSL_USE_VIRTIO_9P())
2412
{
2413
//
2414
// Check if the existing mount is a drvfs mount that needs to be remounted.
@@ -2446,7 +2441,7 @@ try
2441
NewMountOptions += ',';
2442
}
2443
2449
- MountPlan9Share(NewSource, MountEntry.MountPoint, NewMountOptions.c_str(), Message->Admin, Config);
2444
+ MountPlan9Share(NewSource, MountEntry.MountPoint, NewMountOptions.c_str(), Message->Admin);
2445
}
2446
else if (strcmp(MountEntry.FileSystemType, VIRTIO_FS_TYPE) == 0)
2447
{
src/linux/init/config.h
+2
-2
@@ -23,8 +23,8 @@ Abstract:
23
#include "SocketChannel.h"
24
#include "WslDistributionConfig.h"
25
26
-#define WSL_USE_VIRTIO_9P(_Config) (WI_IsFlagSet(UtilGetFeatureFlags((_Config)), LxInitFeatureVirtIo9p))
27
-#define WSL_USE_VIRTIO_FS(_Config) (WI_IsFlagSet(UtilGetFeatureFlags((_Config)), LxInitFeatureVirtIoFs))
26
+#define WSL_USE_VIRTIO_9P() (WI_IsFlagSet(UtilGetFeatureFlags(), LxInitFeatureVirtIo9p))
27
+#define WSL_USE_VIRTIO_FS() (WI_IsFlagSet(UtilGetFeatureFlags(), LxInitFeatureVirtIoFs))
28
#define WSLG_SHARED_FOLDER "wslg"
29
30
#define INIT_MAKE_SECURITY(_uid, _gid, _mode) {_uid, _gid, _mode}
src/linux/init/drvfs.cpp
+23
-6
@@ -298,7 +298,7 @@ try
298
{
299
return MountFilesystem(DRVFS_FS_TYPE, Source, Target, Options, ExitCode);
300
}
301
- else if (WSL_USE_VIRTIO_FS(Config))
301
+ else if (WSL_USE_VIRTIO_FS())
302
{
303
return MountVirtioFs(Source, Target, Options, Admin, Config, ExitCode);
304
}
@@ -349,7 +349,7 @@ Return Value:
349
return ExitCode;
350
}
351
352
-int MountPlan9Share(const char* Source, const char* Target, const char* Options, bool Admin, const wsl::linux::WslDistributionConfig& Config, int* ExitCode)
352
+int MountPlan9Share(const char* Source, const char* Target, const char* Options, bool Admin, int* ExitCode)
353
354
/*++
355
@@ -367,8 +367,6 @@ Arguments:
367
368
Admin - Supplies a boolean specifying if the admin share should be used.
369
370
- Config - Supplies the distribution configuration.
371
-
370
ExitCode - Supplies an optional pointer that receives the exit code.
371
372
Return Value:
@@ -379,7 +377,7 @@ Return Value:
377
378
{
379
std::string MountOptions;
382
- if (WSL_USE_VIRTIO_9P(Config))
380
+ if (WSL_USE_VIRTIO_9P())
381
{
382
Source = Admin ? LX_INIT_DRVFS_ADMIN_VIRTIO_TAG : LX_INIT_DRVFS_VIRTIO_TAG;
383
MountOptions = std::format("msize=262144,trans=virtio,{}", Options);
@@ -476,7 +474,7 @@ try
474
//
475
476
MountOptions += Plan9Options;
479
- if (MountPlan9Share(Source, Target, MountOptions.c_str(), Elevated, Config, ExitCode) < 0)
477
+ if (MountPlan9Share(Source, Target, MountOptions.c_str(), Elevated, ExitCode) < 0)
478
{
479
return -1;
480
}
@@ -515,6 +513,8 @@ Return Value:
513
514
try
515
{
516
+ assert(WSL_USE_VIRTIO_FS());
517
+
518
//
519
// Check whether to use the elevated or non-elevated virtiofs server.
520
//
@@ -596,6 +596,8 @@ Return Value:
596
597
try
598
{
599
+ assert(WSL_USE_VIRTIO_FS());
600
+
601
wsl::shared::MessageWriter<LX_INIT_REMOUNT_VIRTIOFS_SHARE_MESSAGE> RemountShare(LxInitMessageRemountVirtioFsDevice);
602
RemountShare->Admin = Admin;
603
RemountShare.WriteString(RemountShare->TagOffset, Tag);
@@ -643,6 +645,21 @@ Return Value:
645
646
try
647
{
648
+ if (!WSL_USE_VIRTIO_FS())
649
+ {
650
+ return {};
651
+ }
652
+
653
+ //
654
+ // Validate the tag is a GUID.
655
+ //
656
+
657
+ const auto Guid = wsl::shared::string::ToGuid(Tag);
658
+ if (!Guid)
659
+ {
660
+ return {};
661
+ }
662
+
663
wsl::shared::MessageWriter<LX_INIT_QUERY_VIRTIOFS_SHARE_MESSAGE> QueryShare(LxInitMessageQueryVirtioFsDevice);
664
QueryShare.WriteString(QueryShare->TagOffset, Tag);
665
src/linux/init/drvfs.h
+1
-1
@@ -23,7 +23,7 @@ int MountDrvfs(const char* Source, const char* Target, const char* Options, std:
23
24
int MountDrvfsEntry(int Argc, char* Argv[]);
25
26
-int MountPlan9Share(const char* Source, const char* Target, const char* Options, bool Admin, const wsl::linux::WslDistributionConfig& Config, int* ExitCode = nullptr);
26
+int MountPlan9Share(const char* Source, const char* Target, const char* Options, bool Admin, int* ExitCode = nullptr);
27
28
int MountPlan9(const char* Source, const char* Target, const char* Options, std::optional<bool> Admin, const wsl::linux::WslDistributionConfig& Config, int* ExitCode);
29
src/linux/init/util.cpp
+39
-16
@@ -53,6 +53,7 @@ Abstract:
53
#define WSL_MOUNT_OPTION_SEP ','
54
55
int g_IsVmMode = -1;
56
+static std::optional<int> g_CachedFeatureFlags;
57
static sigset_t g_originalSignals;
58
thread_local std::string g_threadName;
59
@@ -1119,7 +1120,7 @@ catch (...)
1120
return {};
1121
}
1122
1122
-int UtilGetFeatureFlags(const wsl::linux::WslDistributionConfig& Config)
1123
+int UtilGetFeatureFlags()
1124
1125
/*++
1126
@@ -1130,7 +1131,7 @@ Routine Description:
1131
1132
Arguments:
1133
1133
- Config - Supplies the distribution config.
1134
+ None.
1135
1136
Return Value:
1137
@@ -1143,21 +1144,11 @@ Return Value:
1144
// If feature flags are already known, return them.
1145
//
1146
1146
- static std::optional<int> g_CachedFeatureFlags;
1147
if (g_CachedFeatureFlags)
1148
{
1149
return *g_CachedFeatureFlags;
1150
}
1151
1152
- //
1153
- // If an error occurs, just return no features.
1154
- //
1155
-
1156
- if (Config.FeatureFlags.has_value())
1157
- {
1158
- return Config.FeatureFlags.value();
1159
- }
1160
-
1152
//
1153
// Check if the environment variable is present.
1154
//
@@ -1167,9 +1158,7 @@ Return Value:
1158
//
1159
1160
int FeatureFlags = LxInitFeatureNone;
1170
-
1161
const char* FeatureFlagEnv = getenv(WSL_FEATURE_FLAGS_ENV);
1172
-
1162
if (FeatureFlagEnv != nullptr)
1163
{
1164
FeatureFlags = strtol(FeatureFlagEnv, nullptr, 16);
@@ -1177,7 +1166,7 @@ Return Value:
1166
else
1167
{
1168
//
1180
- // Query init for the value.
1169
+ // Query init for the value. If an error occurs, just return no features.
1170
//
1171
1172
wsl::shared::SocketChannel channel{UtilConnectUnix(WSL_INIT_INTEROP_SOCKET), "wslinfo"};
@@ -1194,10 +1183,44 @@ Return Value:
1183
FeatureFlags = channel.ReceiveMessage<RESULT_MESSAGE<int32_t>>().Result;
1184
}
1185
1197
- g_CachedFeatureFlags = FeatureFlags;
1186
+ UtilSetFeatureFlags(FeatureFlags, FeatureFlagEnv == nullptr);
1187
return FeatureFlags;
1188
}
1189
1190
+void UtilSetFeatureFlags(int FeatureFlags, bool UpdateEnv)
1191
+
1192
+/*++
1193
+
1194
+Routine Description:
1195
+
1196
+ This routine sets the feature flags and updates the cached value and environment variable.
1197
+
1198
+Arguments:
1199
+
1200
+ FeatureFlags - Supplies the feature flags to set.
1201
+
1202
+ UpdateEnv - Supplies a boolean that indicates whether the environment variable should be updated.
1203
+
1204
+Return Value:
1205
+
1206
+ None.
1207
+
1208
+--*/
1209
+
1210
+try
1211
+{
1212
+ g_CachedFeatureFlags = FeatureFlags;
1213
+ if (UpdateEnv)
1214
+ {
1215
+ auto FeatureFlagsString = std::format("{:x}", FeatureFlags);
1216
+ if (setenv(WSL_FEATURE_FLAGS_ENV, FeatureFlagsString.c_str(), 1) < 0)
1217
+ {
1218
+ LOG_ERROR("setenv({}, {}, 1) failed {}", WSL_FEATURE_FLAGS_ENV, FeatureFlagsString, errno);
1219
+ }
1220
+ }
1221
+}
1222
+CATCH_LOG()
1223
+
1224
std::optional<LX_MINI_INIT_NETWORKING_MODE> UtilGetNetworkingMode(void)
1225
1226
/*++
src/linux/init/util.h
+3
-1
@@ -223,7 +223,9 @@ std::optional<std::string> UtilGetEnv(const char* Name, char* Environment);
223
224
std::string UtilGetEnvironmentVariable(const char* Name);
225
226
-int UtilGetFeatureFlags(const wsl::linux::WslDistributionConfig& Config);
226
+int UtilGetFeatureFlags();
227
+
228
+void UtilSetFeatureFlags(int FeatureFlags, bool UpdateEnv = true);
229
230
std::optional<LX_MINI_INIT_NETWORKING_MODE> UtilGetNetworkingMode(void);
231