Skip to content

Add openvmm as vmm backend option for wslc vms#40629

Draft
damanm24 wants to merge 4 commits into
masterfrom
user/damanmulye/rfc-wslc-openvmm
Draft

Add openvmm as vmm backend option for wslc vms#40629
damanm24 wants to merge 4 commits into
masterfrom
user/damanmulye/rfc-wslc-openvmm

Conversation

@damanm24

Copy link
Copy Markdown
Contributor

This PR adds OpenVMM as a possible VMM backing WSLC VMs.

This feature is gated on both a compile time gate and a WSLC feature flag. Non-exhaustive list of changes made to implement this:

  1. Bump WSL.DeviceHost nuget package which now includes: OpenVMM and a corresponding VMService.proto file (used to generate protobuf C++ files to allow the wslc service to orchestrate VM management via ttRPC
  2. Implemented a ttrpc client that can communicate with OpenVMM's RPC server to configure and orchestrate the VM backing the WSLC session.
  3. WSLCInit handles a new WSLC_CONFIGURE_NETWORKING message that allows us to configure networking within the VM using OpenVMM's consomme networking stack.
  4. Introduced a new OpenVmmVirtualMachine class that implements the IWSLCVirtualMachine allowing users to switch between traditional HCS VMs and OpenVMM VMs.
  5. Extended SocketChannel class to support non-overlapped I/O which is not supported when using AF_UNIX sockets. This is required to bridge the connection between the mini_init process from the guest to the wslcservice.

Copilot AI review requested due to automatic review settings May 22, 2026 22:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces an optional OpenVMM-backed virtual machine implementation for WSLC sessions, including the plumbing needed to orchestrate VM lifecycle and networking via ttrpc/protobuf, plus Windows-side socket I/O adjustments to support AF_UNIX-based vsock bridging.

Changes:

  • Add an OpenVMM-based IWSLCVirtualMachine implementation and a minimal ttrpc client/envelope codec for vmservice RPCs.
  • Add a new Consomme networking mode and a new mini_init message to configure guest networking for that backend.
  • Extend socket handling to support non-overlapped (blocking) I/O paths required by Windows AF_UNIX sockets, and wire service/session code to use a backend-agnostic “connect/accept vsock port” VM API.

Reviewed changes

Copilot reviewed 30 out of 30 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
src/windows/wslcsession/WSLCVirtualMachine.h Expose underlying VM interface pointer; adjust crash dump collection signature.
src/windows/wslcsession/WSLCVirtualMachine.cpp Route vsock/crashdump connections through VM backend; add Consomme guest network setup; AF_UNIX crashdump relay path.
src/windows/wslcsession/WSLCSession.cpp Adjust Docker client wiring and add mount-format-retry behavior for pre-attached disks.
src/windows/wslcsession/DockerHTTPClient.h Detect socket family for Boost.Asio stream protocol assignment (HV socket vs AF_UNIX).
src/windows/wslcsession/DockerHTTPClient.cpp Use VM backend to connect to per-request vsock ports.
src/windows/wslc/CMakeLists.txt Add OpenVMM protobuf generation hook for wslc library when enabled.
src/windows/service/inc/wslc.idl Add Consomme networking mode; extend VM interface with vsock/crashdump connection methods.
src/windows/service/exe/WSLCSessionManager.cpp Choose VM backend (OpenVMM vs HCS) based on user setting; adjust settings for OpenVMM constraints.
src/windows/service/exe/TtrpcEnvelopeCodec.h Define ttrpc header/envelope codec interface.
src/windows/service/exe/TtrpcEnvelopeCodec.cpp Implement ttrpc request encoding and response decoding.
src/windows/service/exe/TtrpcClient.h Define minimal ttrpc client + VM configuration helpers.
src/windows/service/exe/TtrpcClient.cpp Implement AF_UNIX ttrpc transport, request/response handling, and vmservice RPC wrappers.
src/windows/service/exe/OpenVmmVirtualMachine.h Define OpenVMM-backed IWSLCVirtualMachine implementation.
src/windows/service/exe/OpenVmmVirtualMachine.cpp Implement OpenVMM process launch, vsock bridge listeners, ttrpc orchestration, and disk management.
src/windows/service/exe/HcsVirtualMachine.h Extend HCS backend declaration to implement new vsock/crashdump methods.
src/windows/service/exe/HcsVirtualMachine.cpp Implement new vsock/crashdump methods; create crashdump listen socket.
src/windows/service/exe/CMakeLists.txt Conditionally include OpenVMM sources, proto generation, and compile defs.
src/windows/common/WSLCUserSettings.h Add user setting key for enabling OpenVMM backend.
src/windows/common/WSLCUserSettings.cpp Update default settings template and validator for OpenVMM option.
src/windows/common/ConsommeNetworking.h Add Consomme networking engine and associated constants.
src/windows/common/ConsommeNetworking.cpp Implement Consomme networking engine stubs and initial config fill.
src/windows/common/CMakeLists.txt Add ConsommeNetworking sources; add ATL include-dir discovery logic.
src/shared/inc/SocketChannel.h Add AF_UNIX detection and blocking send/receive paths for non-overlapped sockets on Windows.
src/shared/inc/lxinitshared.h Add WSLC_CONFIGURE_NETWORKING message type and payload.
src/linux/init/WSLCInit.cpp Handle WSLC_CONFIGURE_NETWORKING by configuring guest network + resolv.conf; register handler.
packages.config Bump Microsoft.WSL.DeviceHost nuget version to include OpenVMM + proto.
msipackage/package.wix.in Add openvmm.exe to MSI payload.
msipackage/CMakeLists.txt Add OpenVMM-related DeviceHost binaries to packaging dependencies when enabled.
CMakeLists.txt Add INCLUDE_OPENVMM option; conditionally fetch/build protobuf; add proto generation helper function.
cgmanifest.json Add protobuf component metadata for CG compliance.

Comment on lines +601 to 603
wil::unique_socket socket;
THROW_IF_FAILED(m_vm->ConnectToVsockPort(port, reinterpret_cast<HANDLE*>(&socket)));

Comment on lines 617 to 619
ConnectedSocket socket;
socket.Socket = wsl::windows::common::hvsocket::Connect(m_vmId, response.Result, m_vmTerminatingEvent.get(), m_initChannelTimeout);
THROW_IF_FAILED(m_vm->ConnectToVsockPort(response.Result, reinterpret_cast<HANDLE*>(&socket.Socket)));

Comment on lines +1259 to 1267
wil::unique_socket socket;
HRESULT hr = m_vm->AcceptCrashDumpConnection(reinterpret_cast<HANDLE*>(&socket));
if (hr == E_ABORT)
{
// VM is exiting.
break;
}
THROW_IF_FAILED(hr);

Comment on lines +1326 to +1338
constexpr size_t bufferSize = 65536;
std::vector<char> buf(bufferSize);
for (;;)
{
int bytesRead = ::recv(channel.Socket(), buf.data(), static_cast<int>(buf.size()), 0);
if (bytesRead <= 0)
{
break;
}

DWORD bytesWritten{};
THROW_IF_WIN32_BOOL_FALSE(WriteFile(file.get(), buf.data(), static_cast<DWORD>(bytesRead), &bytesWritten, nullptr));
}
Comment on lines +610 to 613
// Connect the new socket via the VM interface.
wil::unique_socket connSocket;
THROW_IF_FAILED(m_vm->ConnectToVsockPort(response.Port, reinterpret_cast<HANDLE*>(&connSocket)));
wsl::shared::SocketChannel newChannel{
Comment on lines 481 to +497
HRESULT RemoveShare([in] REFGUID ShareId);

// Returns an event that is signaled when the VM exits (graceful or forced).
HRESULT GetTerminationEvent([out, system_handle(sh_event)] HANDLE* Event);

// Connects to a vsock port in the VM. Returns a socket handle.
// For HCS VMs, this uses hvsocket (supports overlapped I/O).
// For OpenVMM VMs, this uses the hybrid_vsock Unix domain socket bridge.
// AF_UNIX sockets do not support overlapped I/O
HRESULT ConnectToVsockPort([in] ULONG Port, [out, system_handle(sh_socket)] HANDLE* Socket);

// Accepts a crash dump connection from the VM. Blocks until a crash dump
// connection arrives or the VM exits. Returns E_ABORT if the VM exits
// before a connection is received.
// For HCS VMs, this uses an HV socket listener on the crash dump port.
// For OpenVMM VMs, this uses the hybrid_vsock Unix domain socket bridge.
HRESULT AcceptCrashDumpConnection([out, system_handle(sh_socket)] HANDLE* Socket);
Comment on lines +797 to +804
HRESULT HcsVirtualMachine::ConnectToVsockPort(_In_ ULONG Port, _Out_ HANDLE* Socket)
try
{
auto socket = wsl::windows::common::hvsocket::Connect(m_vmId, Port);
*Socket = reinterpret_cast<HANDLE>(socket.release());
return S_OK;
}
CATCH_RETURN()
Comment on lines +287 to +289
// OpenVMM provides networking via its built-in consomme backend.
// Use ConsommeNetworking mode so the session process skips GNS but
// still configures the networking engine and port relay.
Comment on lines +726 to +737
// Try to reap the child. If WSLC_WATCH_PROCESSES already reaped it, we
// get ECHILD which is fine — the pipe close confirms the child exited.
int status = -1;
if (TEMP_FAILURE_RETRY(waitpid(childPid, &status, 0)) < 0)
{
if (errno == ECHILD)
{
// Child was already reaped by the WatchProcesses handler.
// The pipe confirmed it exited, so treat as success.
status = 0;
}
else
Comment on lines +131 to +133
// Set socket timeouts to prevent blocking forever if OpenVMM hangs.
setsockopt(m_socket, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast<const char*>(&c_socketTimeoutMs), sizeof(c_socketTimeoutMs));
setsockopt(m_socket, SOL_SOCKET, SO_SNDTIMEO, reinterpret_cast<const char*>(&c_socketTimeoutMs), sizeof(c_socketTimeoutMs));
Comment thread msipackage/CMakeLists.txt
endforeach()

if (INCLUDE_OPENVMM)
set(WSL_DEVICE_HOST_BINARIES wsldevicehost.dll;openvmm.exe)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wsldevicehost.dll should be included all the time.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe that's an existing issue?

Transaction.SendResultMessage(result < 0 ? errno : 0);
}

void HandleMessageImpl(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we probably want to use the existing GNS implementation to do network configuration. it should support all of this stuff.

set_target_properties(common PROPERTIES FOLDER windows)
target_include_directories(common PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/../service/mc/${TARGET_PLATFORM}/${CMAKE_BUILD_TYPE})

# ATL headers (atlsafe.h) are needed by precomp.h but not automatically included

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this needed?


// Disable features not yet supported by the OpenVMM backend.
WI_ClearFlag(m_featureFlags, WslcFeatureFlagsGPU);
WI_ClearFlag(m_featureFlags, WslcFeatureFlagsVirtioFs);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does openvmm use for host shares if not virtiofs?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants