-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Refactor the session creation logic to match the new API #13814
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor the session creation logic to match the new API #13814
Conversation
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…oft/WSL into user/ptrivedi/create-cont
…ptrivedi/create-cont
…crosoft/WSL into user/oneblue/create-container
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This pull request refactors the WSLA (Windows Subsystem for Linux API) session creation logic to simplify storage disk management, remove deprecated VM settings, integrate init script execution into the service, and introduce container support via nerdctl.
Key Changes:
- Consolidated session settings by removing
VIRTUAL_MACHINE_SETTINGSstructure and moving relevant fields intoWSLA_SESSION_SETTINGS - Added container creation capabilities through new
WSLAContainerandWSLAContainerLauncherclasses - Fixed critical inverted state validation logic in VM operations (AttachDisk, Fork, Shutdown, Signal)
- Introduced storage VHD management with automatic creation and formatting
- Switched test environment from full Linux distributions to busybox-based minimal rootfs
Reviewed changes
Copilot reviewed 23 out of 23 changed files in this pull request and generated 18 comments.
Show a summary per file
| File | Description |
|---|---|
| src/windows/wslaservice/inc/wslaservice.idl | Removed VIRTUAL_MACHINE_SETTINGS; consolidated into WSLA_SESSION_SETTINGS; added WSLAFeatureFlags enum; changed WSLA_PROCESS_OPTIONS.Executable to [unique]; added OpenSessionByName method |
| test/windows/WSLATests.cpp | Updated all tests to use new session settings API; changed shell from /bin/bash to /bin/sh for busybox compatibility; added CreateContainer test; created GetDefaultSessionSettings() helper |
| src/windows/wslaservice/exe/WSLAVirtualMachine.h | Introduced Settings struct to replace VIRTUAL_MACHINE_SETTINGS; removed GetDebugShellPipe method; added Mount public method |
| src/windows/wslaservice/exe/WSLAVirtualMachine.cpp | Fixed inverted m_running validation bugs; removed debug shell pipe support; moved DmesgHandle from ULONG to wil::unique_handle; added FeatureEnabled helper |
| src/windows/wslaservice/exe/WSLAUserSession.h/cpp | Updated CreateSession to accept only WSLA_SESSION_SETTINGS; added OpenSessionByName implementation |
| src/windows/wslaservice/exe/WSLASession.h/cpp | Refactored to create VM settings from session settings; added ConfigureStorage for automatic VHD creation/formatting; integrated init script execution |
| src/windows/wslaservice/exe/WSLAProcess.cpp | Added m_exitEvent.SetEvent() call in OnVmTerminated for proper cleanup |
| src/windows/wslaservice/exe/WSLAContainer.h/cpp | Implemented container creation via nerdctl with support for basic options (image, name, entrypoint, environment, stdin/tty handling) |
| src/windows/common/WSLAContainerLauncher.h/cpp | New client-side wrapper for launching containers through the WSLA API |
| src/windows/common/WSLAProcessLauncher.h/cpp | Added DEFAULT_MOVABLE macro usage for move semantics support |
| src/windows/common/WslCoreFilesystem.cpp | Changed VHD extension validation from WI_ASSERT to THROW_HR_IF for production safety |
| src/windows/common/WslClient.cpp | Updated WslaShell debug tool to use new session settings; added container launch support |
| src/shared/inc/defs.h | Added DEFAULT_MOVABLE macro for default move constructor/assignment |
| CMakeLists.txt | Fixed CMake conditional from DEFINED check to boolean check |
| msipackage/package.wix.in | Added wslarootfs.vhd to installer for x64 builds |
| THROW_HR_IF(E_INVALIDARG, Settings.RootVhdTypeOverride == nullptr); | ||
|
|
||
| vmSettings.RootVhd = Settings.RootVhdOverride; | ||
| vmSettings.RootVhdType = Settings.RootVhdTypeOverride; |
Copilot
AI
Dec 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The error condition checks if RootVhdTypeOverride is null when RootVhdOverride is not null. However, there's an asymmetry: when RootVhdOverride is null (line 81-83), a default VHD type of "squashfs" is used. Consider also providing a sensible default for RootVhdTypeOverride (e.g., "ext4") instead of requiring it to be specified, or document why it must be explicitly provided.
| THROW_HR_IF(E_INVALIDARG, Settings.RootVhdTypeOverride == nullptr); | |
| vmSettings.RootVhd = Settings.RootVhdOverride; | |
| vmSettings.RootVhdType = Settings.RootVhdTypeOverride; | |
| vmSettings.RootVhd = Settings.RootVhdOverride; | |
| vmSettings.RootVhdType = Settings.RootVhdTypeOverride != nullptr ? Settings.RootVhdTypeOverride : "ext4"; |
|
|
||
| // Note: fd/0 is opened by readlink to read the actual content of /proc/self/fd. | ||
| if (!PathMatchSpecA(result.Output[1].c_str(), "/proc/self/fd/0 /proc/self/fd/1 /proc/self/fd/2\nsocket:[*]\nsocket:[*]\n")) | ||
| if (!PathMatchSpecA(result.Output[1].c_str(), "/proc/self/fd/0 /proc/self/fd/1 /proc/self/fd/2\n")) |
Copilot
AI
Dec 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test expectation changed to no longer expect socket file descriptors in the output (removed socket:[*]\nsocket:[*]\n). This suggests a behavioral change where processes no longer have extra socket file descriptors open. Verify this is intentional and doesn't indicate a regression in socket handling or file descriptor management.
CMakeLists.txt
Outdated
| endif() | ||
|
|
||
| if (NOT DEFINED OFFICIAL_BUILD AND ${TARGET_PLATFORM} STREQUAL "x64") | ||
| if (NOT OFFICIAL_BUILD AND ${TARGET_PLATFORM} STREQUAL "x64") |
Copilot
AI
Dec 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The condition should use && (logical AND) instead of AND (which is not standard C++). While some compilers may define AND as a macro or alternative token, it's better to use the standard && operator for portability and clarity.
| }; | ||
|
|
||
| struct WSLA_PROCESS_OPTIONS | ||
| { |
Copilot
AI
Dec 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The [unique] attribute on Executable was added, but this could be a breaking API change. If existing callers pass a non-null Executable, this change should be safe. However, if the intention is to allow null executables (as suggested by the container launcher code), ensure all consumers handle this correctly. The container code at line 142-146 in WSLAContainer.cpp explicitly handles null executables, which is good.
| { | |
| { | |
| // May be NULL. Consumers must handle the case where Executable is not provided. |
| LPCSTR Image; | ||
| LPCSTR Name; | ||
| struct WSLA_PROCESS_OPTIONS* InitProcessOptions; | ||
| struct WSLA_PROCESS_OPTIONS InitProcessOptions; |
Copilot
AI
Dec 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The field changed from a pointer (struct WSLA_PROCESS_OPTIONS*) to a value type (struct WSLA_PROCESS_OPTIONS). This is a breaking API change. Ensure all callers have been updated to pass the structure by value instead of by pointer.
| THROW_HR_IF_MSG( | ||
| E_INVALIDARG, | ||
| options.InitProcessOptions.Environment[i][0] == L'-', | ||
| "Invlaid environment string: %hs", |
Copilot
AI
Dec 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo in error message: "Invlaid" should be "Invalid".
| "Invlaid environment string: %hs", | |
| "Invalid environment string: %hs", |
| THROW_HR_IF_MSG( | ||
| E_INVALIDARG, | ||
| options.InitProcessOptions.Environment[i][0] == L'-', | ||
| "Invlaid environment string: %hs", |
Copilot
AI
Dec 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The environment validation checks if the string starts with - but uses the wrong error message format specifier. The parameter options.InitProcessOptions.Environment[i] is declared as LPCSTR* (array of char pointers), so individual elements are LPCSTR (char*). However, the error message uses %hs which expects a char*, but this should work. The real issue is the error message says "Invlaid" (typo already noted) and "environment string" when it's checking for a dash prefix, which typically indicates an argument flag confusion. Consider clarifying the error message to explain why a dash prefix is invalid (e.g., "Environment variable must not start with '-'").
| "Invlaid environment string: %hs", | |
| "Invalid environment variable: %hs. Environment variable must not start with '-'", |
| This file contains the definition for WSLAContainerLauncher. | ||
| --*/ | ||
| #include "WSLAprocessLauncher.h" |
Copilot
AI
Dec 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent casing in include: should be "WSLAProcessLauncher.h" (capital P) to match the actual filename based on other includes in the codebase.
| #include "WSLAprocessLauncher.h" | |
| #include "WSLAProcessLauncher.h" |
| if (result.Code != expectedResult) | ||
| { | ||
| LogError( | ||
| "Comman didn't return expected code (%i). ExitCode: %i, Stdout: '%hs', Stderr: '%hs'", |
Copilot
AI
Dec 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo in error message: "Comman" should be "Command".
| "Comman didn't return expected code (%i). ExitCode: %i, Stdout: '%hs', Stderr: '%hs'", | |
| "Command didn't return expected code (%i). ExitCode: %i, Stdout: '%hs', Stderr: '%hs'", |
| "Failed to attach vhd: %ls", | ||
| m_storageVhdPath.c_str()); | ||
|
|
||
| // If the VHD wasn'found, create it. |
Copilot
AI
Dec 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo in comment: "wasn'found" should be "wasn't found".
| // If the VHD wasn'found, create it. | |
| // If the VHD wasn't found, create it. |
| { | ||
| THROW_HR_IF_MSG( | ||
| result, | ||
| result != HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) && result != HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why are we ignoring these failures?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, still seems odd to try to attach a disk that doesn't exist.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought about that vs explicitly checking if the file exists, my thinking was that they're equivalent, but in the case where the VHD does exists, this approach allows us to avoid a file access to validate that the VHD exists
| if (m_settings.DmesgHandle) | ||
| { | ||
| dmesgOutput.reset(wsl::windows::common::wslutil::DuplicateHandleFromCallingProcess(ULongToHandle(m_settings.DmesgOutput))); | ||
| dmesgOutput = std::move(m_settings.DmesgHandle); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can this whole condition be removed and just always move the dmesg handle? won't harm anythigng if it's empty.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, it can
| WSL_LOG("CreateWSLAVirtualMachine", TraceLoggingValue(json.c_str(), "json")); | ||
|
|
||
| m_computeSystem = hcs::CreateComputeSystem(m_vmIdString.c_str(), json.c_str()); | ||
| m_running = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Running is a poor name since the VM has not started yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it belong after StartComputeSystem?
(200+ line function, phew :) )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed. Moved after StartComputeSystem
| WSL_LOG("CreateWSLAVirtualMachine", TraceLoggingValue(json.c_str(), "json")); | ||
|
|
||
| m_computeSystem = hcs::CreateComputeSystem(m_vmIdString.c_str(), json.c_str()); | ||
| m_running = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it belong after StartComputeSystem?
(200+ line function, phew :) )
Summary of the Pull Request
** This change depends on: #13791 **
This change refactors the session creation logic to:
After this change, running wsl --wsla will open a shell in a VM already configured to run
nerdctl.--storagecan be passed to enable on disk storage, otherwise a tmpfs will be used to allow container creation.PR Checklist
Detailed Description of the Pull Request / Additional comments
Validation Steps Performed