Expose the VM ID inside user distros (#13212)

* Add --vm-id to wslinfo usage string * Pass the VM id to init This change ensures that we pass the vm id to an instances init. The id is then set as an environment variable and can be accessed at runtime. * Expose VM id to wslinfo Add a new argument --vm-id to wslinfo so that the caller can retrieve the VM id by calling the binary. Although it is an environment variable, it can be useful here too to save additional string parsing from the caller.

Craig Gumbley committed Jul 4, 2025 at 01:30 UTC 4547e2a6f201434f676256c881791f76b05be152
5 files changed +38 -2
localization/strings/en-US/Resources.resw
+4
@@ -321,6 +321,9 @@ Please enable the "Windows Subsystem for Linux" optional component to use WSL1.<
321 --msal-proxy-path
322 Display the path to the MSAL proxy application.
323
324 + --vm-id
325 + Display the WSL VM ID.
326 +
327 --version
328 Display the version of the WSL package.
329
@@ -328,6 +331,7 @@ Please enable the "Windows Subsystem for Linux" optional component to use WSL1.<
331 Do not print a newline.</value>
332 <comment>{Locked="--networking-mode
333 "}{Locked="--msal-proxy-path
334 +"}{Locked="--vm-id
335 "}{Locked="--version
336 "}Command line arguments, file names and string inserts should not be translated</comment>
337 </data>
src/linux/init/main.cpp
+1 -1
@@ -2582,7 +2582,7 @@ void ProcessLaunchInitMessage(
2582 DISTRO_PATH,
2583 enableGuiApps,
2584 Config,
2585 - nullptr,
2585 + wsl::shared::string::FromSpan(Buffer, Message->VmIdOffset),
2586 wsl::shared::string::FromSpan(Buffer, Message->DistributionNameOffset),
2587 nullptr,
2588 wsl::shared::string::FromSpan(Buffer, Message->InstallPathOffset),
src/linux/init/wslinfo.cpp
+20 -1
@@ -23,12 +23,14 @@ Abstract:
23 #include "defs.h"
24 #include "Localization.h"
25 #include "CommandLine.h"
26 +#include "../../shared/inc/lxinitshared.h"
27
28 enum class WslInfoMode
29 {
30 GetNetworkingMode,
31 MsalProxyPath,
31 - WslVersion
32 + WslVersion,
33 + VMId
34 };
35
36 int WslInfoEntry(int Argc, char* Argv[])
@@ -65,6 +67,7 @@ Return Value:
67 parser.AddArgument(UniqueSetValue<WslInfoMode, WslInfoMode::MsalProxyPath>{Mode, Usage}, WSLINFO_MSAL_PROXY_PATH);
68 parser.AddArgument(UniqueSetValue<WslInfoMode, WslInfoMode::WslVersion>{Mode, Usage}, WSLINFO_WSL_VERSION);
69 parser.AddArgument(UniqueSetValue<WslInfoMode, WslInfoMode::WslVersion>{Mode, Usage}, WSLINFO_WSL_VERSION_LEGACY);
70 + parser.AddArgument(UniqueSetValue<WslInfoMode, WslInfoMode::VMId>{Mode, Usage}, WSLINFO_WSL_VMID);
71 parser.AddArgument(NoOp{}, WSLINFO_WSL_HELP);
72 parser.AddArgument(noNewLine, nullptr, WSLINFO_NO_NEWLINE);
73
@@ -144,6 +147,22 @@ Return Value:
147 {
148 std::cout << WSL_PACKAGE_VERSION;
149 }
150 + else if (Mode.value() == WslInfoMode::VMId)
151 + {
152 + auto value = UtilGetEnvironmentVariable(LX_WSL2_VM_ID_ENV);
153 + if (value.empty())
154 + {
155 + std::cerr << Localization::MessageNoValueFound() << "\n";
156 + return 1;
157 + }
158 +
159 + std::cout << value;
160 + }
161 + else
162 + {
163 + assert(false && "Unknown WslInfoMode");
164 + return 1;
165 + }
166
167 if (!noNewLine)
168 {
src/linux/init/wslinfo.h
+1
@@ -20,6 +20,7 @@ Abstract:
20 #define WSLINFO_NETWORKING_MODE "--networking-mode"
21 #define WSLINFO_WSL_VERSION "--version"
22 #define WSLINFO_WSL_VERSION_LEGACY "--wsl-version"
23 +#define WSLINFO_WSL_VMID "--vm-id"
24 #define WSLINFO_WSL_HELP "--help"
25 #define WSLINFO_NO_NEWLINE 'n'
26
test/windows/UnitTests.cpp
+12
@@ -842,6 +842,18 @@ class UnitTests
842 L"Invalid command line argument: --invalid\nPlease use 'wslinfo --help' to get a list of supported "
843 L"arguments.\n");
844 }
845 +
846 + if (LxsstuVmMode())
847 + {
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));
855 + VERIFY_ARE_EQUAL(err, L"");
856 + }
857 }
858
859 TEST_METHOD(WslPath)