Skip to content

Commit 6423313

Browse files
benhillisBen HillisCopilot
authored
Switch wslinfo --vm-id to not rely on presence of VM ID environment variable (#13318)
* Switch WSLg to use wslinfo --vm-id instead of relying on environment variable * DO NOT MERGE: bad WSLg nuget * dead code removal * always send response to LxInitMessageQueryVmId message * add back invalid WslInfoMode error * remove unneeded wsl2 check * use temporary workaround until WSLg update is ready * unit test update * Update string compare Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent b89e1f5 commit 6423313

File tree

9 files changed

+113
-33
lines changed

9 files changed

+113
-33
lines changed

src/linux/init/WslDistributionConfig.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ struct WslDistributionConfig
7979
bool GuiAppsEnabled = false;
8080
std::optional<int> FeatureFlags = 0;
8181
std::optional<LX_MINI_INIT_NETWORKING_MODE> NetworkingMode = LxMiniInitNetworkingModeNone;
82+
std::optional<std::string> VmId;
8283

8384
//
8485
// Global state for boot state. The socket is used to delay-start the distro init process

src/linux/init/config.cpp

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,18 @@ try
436436
ResponseChannel.SendResultMessage<uint8_t>(static_cast<uint8_t>(Config.NetworkingMode.value()));
437437
break;
438438

439+
case LxInitMessageQueryVmId:
440+
{
441+
wsl::shared::MessageWriter<LX_INIT_QUERY_VM_ID> Response(LxInitMessageQueryVmId);
442+
if (Config.VmId.has_value())
443+
{
444+
Response.WriteString(Config.VmId.value());
445+
}
446+
447+
ResponseChannel.SendMessage<LX_INIT_QUERY_VM_ID>(Response.Span());
448+
break;
449+
}
450+
439451
default:
440452
LOG_ERROR("unexpected message {}", Header->MessageType);
441453
break;
@@ -1662,17 +1674,6 @@ Return Value:
16621674
ConfigAppendNtPath(Environment, Buffer);
16631675
}
16641676

1665-
//
1666-
// If the VM ID environment variable is present, add it to the environment
1667-
// block.
1668-
//
1669-
1670-
auto VmId = getenv(LX_WSL2_VM_ID_ENV);
1671-
if (VmId)
1672-
{
1673-
Environment.AddVariable(LX_WSL2_VM_ID_ENV, VmId);
1674-
}
1675-
16761677
return Environment;
16771678
}
16781679

src/linux/init/init.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2239,13 +2239,27 @@ Return Value:
22392239
unsetenv(LX_WSL2_DISTRO_READ_ONLY_ENV);
22402240
}
22412241

2242-
const auto Value = getenv(LX_WSL2_NETWORKING_MODE_ENV);
2242+
auto Value = getenv(LX_WSL2_NETWORKING_MODE_ENV);
22432243
if (Value != nullptr)
22442244
{
22452245
Config.NetworkingMode = static_cast<LX_MINI_INIT_NETWORKING_MODE>(std::atoi(Value));
22462246
unsetenv(LX_WSL2_NETWORKING_MODE_ENV);
22472247
}
22482248

2249+
Value = getenv(LX_WSL2_VM_ID_ENV);
2250+
if (Value != nullptr)
2251+
{
2252+
Config.VmId = Value;
2253+
2254+
// Unset the environment variable for user distros.
2255+
// TODO: this can be removed when WSLg is updated to use `wslinfo --vm-id` instead of the environment variable.
2256+
Value = getenv(LX_WSL2_SYSTEM_DISTRO);
2257+
if (!Value || strcmp(Value, "1") != 0)
2258+
{
2259+
unsetenv(LX_WSL2_VM_ID_ENV);
2260+
}
2261+
}
2262+
22492263
//
22502264
// If the boot.systemd option is specified in /etc/wsl.conf, launch the distro init process as pid 1.
22512265
// WSL init and session leaders continue as children of the distro init process.

src/linux/init/main.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1827,6 +1827,11 @@ try
18271827
AddEnvironmentVariable(LX_WSL2_USER_PROFILE, UserProfile);
18281828
AddEnvironmentVariable(LX_WSL2_NETWORKING_MODE_ENV, std::to_string(static_cast<int>(Config.NetworkingMode)).c_str());
18291829

1830+
if (UserProfile)
1831+
{
1832+
AddEnvironmentVariable(LX_WSL2_SYSTEM_DISTRO, "1");
1833+
}
1834+
18301835
if (DistroInitPid.has_value())
18311836
{
18321837
AddEnvironmentVariable(LX_WSL2_DISTRO_INIT_PID, std::to_string(static_cast<int>(DistroInitPid.value())).c_str());

src/linux/init/util.cpp

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,25 +1201,20 @@ std::optional<LX_MINI_INIT_NETWORKING_MODE> UtilGetNetworkingMode(void)
12011201
12021202
Routine Description:
12031203
1204-
This routine gets the feature flags, either directly, from an environment
1205-
variable, or by querying it from the init process.
1204+
This routine queries the networking mode from the init process.
12061205
12071206
Arguments:
12081207
12091208
None.
12101209
12111210
Return Value:
12121211
1213-
The feature flags.
1212+
The networking mode if successful, std::nullopt otherwise.
12141213
12151214
--*/
12161215

12171216
try
12181217
{
1219-
//
1220-
// Query init for the value.
1221-
//
1222-
12231218
wsl::shared::SocketChannel channel{UtilConnectUnix(WSL_INIT_INTEROP_SOCKET), "wslinfo"};
12241219
THROW_LAST_ERROR_IF(channel.Socket() < 0);
12251220

@@ -1297,6 +1292,40 @@ Return Value:
12971292
return Result;
12981293
}
12991294

1295+
std::string UtilGetVmId(void)
1296+
1297+
/*++
1298+
1299+
Routine Description:
1300+
1301+
This routine queries the VM ID from the init process.
1302+
1303+
Arguments:
1304+
1305+
None.
1306+
1307+
Return Value:
1308+
1309+
The VM ID if successful, an empty string otherwise.
1310+
1311+
--*/
1312+
1313+
try
1314+
{
1315+
wsl::shared::SocketChannel channel{UtilConnectUnix(WSL_INIT_INTEROP_SOCKET), "wslinfo"};
1316+
THROW_LAST_ERROR_IF(channel.Socket() < 0);
1317+
1318+
wsl::shared::MessageWriter<LX_INIT_QUERY_VM_ID> Message(LxInitMessageQueryVmId);
1319+
channel.SendMessage<LX_INIT_QUERY_VM_ID>(Message.Span());
1320+
1321+
return channel.ReceiveMessage<LX_INIT_QUERY_VM_ID>().Buffer;
1322+
}
1323+
catch (...)
1324+
{
1325+
LOG_CAUGHT_EXCEPTION();
1326+
return {};
1327+
}
1328+
13001329
void UtilInitGroups(const char* User, gid_t Gid)
13011330

13021331
/*++

src/linux/init/util.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,8 @@ std::optional<LX_MINI_INIT_NETWORKING_MODE> UtilGetNetworkingMode(void);
227227

228228
pid_t UtilGetPpid(pid_t Pid);
229229

230+
std::string UtilGetVmId(void);
231+
230232
void UtilInitGroups(const char* User, gid_t Gid);
231233

232234
void UtilInitializeMessageBuffer(std::vector<gsl::byte>& Buffer);

src/linux/init/wslinfo.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -149,14 +149,21 @@ Return Value:
149149
}
150150
else if (Mode.value() == WslInfoMode::VMId)
151151
{
152-
auto value = UtilGetEnvironmentVariable(LX_WSL2_VM_ID_ENV);
153-
if (value.empty())
152+
if (UtilIsUtilityVm())
154153
{
155-
std::cerr << Localization::MessageNoValueFound() << "\n";
156-
return 1;
157-
}
154+
auto vmId = UtilGetVmId();
155+
if (vmId.empty())
156+
{
157+
std::cerr << Localization::MessageNoValueFound() << "\n";
158+
return 1;
159+
}
158160

159-
std::cout << value;
161+
std::cout << vmId;
162+
}
163+
else
164+
{
165+
std::cout << "wsl1";
166+
}
160167
}
161168
else
162169
{

src/shared/inc/lxinitshared.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ Module Name:
255255
#define LX_WSL2_SHARED_MEMORY_OB_DIRECTORY "WSL2_SHARED_MEMORY_OB_DIRECTORY"
256256
#define LX_WSL2_INSTALL_PATH "WSL2_INSTALL_PATH"
257257
#define LX_WSL2_SAFE_MODE "WSL2_SAFE_MODE"
258+
#define LX_WSL2_SYSTEM_DISTRO "WSL2_SYSTEM_DISTRO"
258259
#define LX_WSL2_USER_PROFILE "WSL2_USER_PROFILE"
259260
#define LX_WSL2_VM_ID_ENV "WSL2_VM_ID"
260261
#define LX_WSL_PID_ENV "WSL2_PID"
@@ -304,6 +305,7 @@ typedef enum _LX_MESSAGE_TYPE
304305
LxInitMessageCreateLoginSession,
305306
LxInitMessageStopPlan9Server,
306307
LxInitMessageQueryNetworkingMode,
308+
LxInitMessageQueryVmId,
307309
LxInitCreateProcess,
308310
LxInitOobeResult,
309311
LxMiniInitMessageLaunchInit,
@@ -1496,6 +1498,16 @@ typedef struct _LX_INIT_OOBE_RESULT
14961498
PRETTY_PRINT(FIELD(Header), FIELD(Result), FIELD(DefaultUid));
14971499
} LX_INIT_OOBE_RESULT, *PLX_INIT_OOBE_RESULT;
14981500

1501+
typedef struct _LX_INIT_QUERY_VM_ID
1502+
{
1503+
static inline auto Type = LxInitMessageQueryVmId;
1504+
1505+
MESSAGE_HEADER Header;
1506+
char Buffer[];
1507+
1508+
PRETTY_PRINT(FIELD(Header), FIELD(Buffer));
1509+
} LX_INIT_QUERY_VM_ID, *PLX_INIT_QUERY_VM_ID;
1510+
14991511
template <>
15001512
struct std::formatter<LX_MESSAGE_TYPE, char>
15011513
{

test/windows/UnitTests.cpp

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -843,16 +843,25 @@ class UnitTests
843843
L"arguments.\n");
844844
}
845845

846-
if (LxsstuVmMode())
847846
{
848-
// Get the VM ID from the distro and validate that it not null.
849-
auto [vmId, vmIdErr] = LxsstuLaunchWslAndCaptureOutput(L"env | grep 'WSL2_VM_ID' | awk -F= '{print $2}'");
850-
VERIFY_ARE_NOT_EQUAL(vmId, L"");
851-
852-
// Ensure that the response from wslinfo matches the VM id from the distros environment
853-
auto [out, err] = LxsstuLaunchWslAndCaptureOutput(L"wslinfo --vm-id");
854-
VERIFY_ARE_EQUAL(out, std::format(L"{}", vmId));
847+
auto [out, err] = LxsstuLaunchWslAndCaptureOutput(L"wslinfo --vm-id -n");
855848
VERIFY_ARE_EQUAL(err, L"");
849+
if (LxsstuVmMode())
850+
{
851+
// Ensure that the response from wslinfo has the VM ID.
852+
auto guid = wsl::shared::string::ToGuid(out);
853+
VERIFY_IS_TRUE(guid.has_value());
854+
VERIFY_IS_FALSE(IsEqualGUID(guid.value(), GUID_NULL));
855+
856+
// Validate that the VM ID is not propagated to user commands.
857+
std::tie(out, err) = LxsstuLaunchWslAndCaptureOutput(L"echo -n \"$WSL2_VM_ID\"");
858+
VERIFY_ARE_EQUAL(out, L"");
859+
VERIFY_ARE_EQUAL(err, L"");
860+
}
861+
else
862+
{
863+
VERIFY_ARE_EQUAL(out, L"wsl1");
864+
}
856865
}
857866
}
858867

0 commit comments

Comments
 (0)