mirror of
https://github.com/microsoft/WSL.git
synced 2025-12-10 00:44:55 -06:00
Merge
This commit is contained in:
commit
251a5bba8b
@ -379,10 +379,10 @@ if (DEFINED WSL_DEV_BINARY_PATH) # Development shortcut to make the package smal
|
||||
WSL_KERNEL_MODULES_PATH="${WSL_DEV_BINARY_PATH}/modules.vhd"
|
||||
WSL_DEV_INSTALL_PATH="${WSL_DEV_BINARY_PATH}"
|
||||
WSL_GPU_LIB_PATH="${WSL_DEV_BINARY_PATH}/lib")
|
||||
endif()
|
||||
|
||||
if (NOT OFFICIAL_BUILD AND ${TARGET_PLATFORM} STREQUAL "x64")
|
||||
add_compile_definitions(WSLA_TEST_DISTRO_PATH="${WSLA_TEST_DISTRO_SOURCE_DIR}/wslatestrootfs.vhd")
|
||||
if (NOT OFFICIAL_BUILD AND ${TARGET_PLATFORM} STREQUAL "x64")
|
||||
add_compile_definitions(WSLA_TEST_DISTRO_PATH="${WSLA_TEST_DISTRO_SOURCE_DIR}/wslatestrootfs.vhd")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Common include paths
|
||||
|
||||
@ -66,7 +66,7 @@ RunningWSLAContainer WSLAContainerLauncher::Launch(IWSLASession& Session)
|
||||
options.InitProcessOptions.Executable = nullptr;
|
||||
}
|
||||
|
||||
// TODO: Support volumes, ports, flags, shm size, etc.
|
||||
// TODO: Support volumes, ports, flags, shm size, container networking mode, etc.
|
||||
wil::com_ptr<IWSLAContainer> container;
|
||||
THROW_IF_FAILED(Session.CreateContainer(&options, &container));
|
||||
|
||||
|
||||
@ -11,7 +11,9 @@ Abstract:
|
||||
This file contains the definition for WSLAContainerLauncher.
|
||||
|
||||
--*/
|
||||
#include "WSLAprocessLauncher.h"
|
||||
|
||||
#pragma once
|
||||
#include "WSLAProcessLauncher.h"
|
||||
|
||||
namespace wsl::windows::common {
|
||||
|
||||
|
||||
@ -1556,6 +1556,7 @@ int WslaShell(_In_ std::wstring_view commandLine)
|
||||
parser.AddArgument(Integer(sessionSettings.CpuCount), L"--cpu");
|
||||
parser.AddArgument(Utf8String(rootVhdTypeOverride), L"--fstype");
|
||||
parser.AddArgument(storagePath, L"--storage");
|
||||
parser.AddArgument(Integer(reinterpret_cast<int&>(sessionSettings.NetworkingMode)), L"--networking-mode");
|
||||
parser.AddArgument(Utf8String(containerImage), L"--image");
|
||||
parser.AddArgument(debugShell, L"--debug-shell");
|
||||
parser.AddArgument(help, L"--help");
|
||||
@ -1564,19 +1565,30 @@ int WslaShell(_In_ std::wstring_view commandLine)
|
||||
if (help)
|
||||
{
|
||||
const auto usage = std::format(
|
||||
LR"({} --wsla [--vhd </path/to/vhd>] [--shell </path/to/shell>] [--memory <memory-mb>] [--cpu <cpus>] [--dns-tunneling] [--fstype <fstype>] [--container-vhd </path/to/vhd>] [--help])",
|
||||
LR"({} --wsla [--vhd </path/to/vhd>] [--shell </path/to/shell>] [--memory <memory-mb>] [--cpu <cpus>] [--dns-tunneling] [--networking-mode <mode>] [--fstype <fstype>] [--container-vhd </path/to/vhd>] [--help])",
|
||||
WSL_BINARY_NAME);
|
||||
|
||||
wprintf(L"%ls\n", usage.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (sessionSettings.NetworkingMode)
|
||||
{
|
||||
case WSLANetworkingMode::WSLANetworkingModeNone:
|
||||
case WSLANetworkingMode::WSLANetworkingModeNAT:
|
||||
case WSLANetworkingMode::WSLANetworkingModeVirtioProxy:
|
||||
break;
|
||||
default:
|
||||
THROW_HR(E_INVALIDARG);
|
||||
}
|
||||
|
||||
wil::com_ptr<IWSLAUserSession> userSession;
|
||||
THROW_IF_FAILED(CoCreateInstance(__uuidof(WSLAUserSession), nullptr, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&userSession)));
|
||||
wsl::windows::common::security::ConfigureForCOMImpersonation(userSession.get());
|
||||
|
||||
wil::com_ptr<IWSLAVirtualMachine> virtualMachine;
|
||||
wil::com_ptr<IWSLASession> session;
|
||||
|
||||
if (!rootVhdOverride.empty())
|
||||
{
|
||||
sessionSettings.RootVhdOverride = rootVhdOverride.c_str();
|
||||
|
||||
@ -116,7 +116,7 @@ std::vector<std::string> WSLAContainer::PrepareNerdctlRunCommand(const WSLA_CONT
|
||||
args.push_back(options.Name);
|
||||
if (options.ShmSize > 0)
|
||||
{
|
||||
args.push_back("--shm-size=" + std::to_string(options.ShmSize) + 'm');
|
||||
args.push_back(std::format("--shm-size={}m", options.ShmSize));
|
||||
}
|
||||
if (options.Flags & WSLA_CONTAINER_FLAG_ENABLE_GPU)
|
||||
{
|
||||
@ -133,7 +133,7 @@ std::vector<std::string> WSLAContainer::PrepareNerdctlRunCommand(const WSLA_CONT
|
||||
THROW_HR_IF_MSG(
|
||||
E_INVALIDARG,
|
||||
options.InitProcessOptions.Environment[i][0] == L'-',
|
||||
"Invlaid environment string: %hs",
|
||||
"Invalid environment string: %hs",
|
||||
options.InitProcessOptions.Environment[i]);
|
||||
|
||||
args.insert(args.end(), {"-e", options.InitProcessOptions.Environment[i]});
|
||||
|
||||
@ -78,7 +78,16 @@ WSLAVirtualMachine::Settings WSLASession::CreateVmSettings(const WSLA_SESSION_SE
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
#ifdef WSLA_TEST_DISTRO_PATH
|
||||
|
||||
vmSettings.RootVhd = TEXT(WSLA_TEST_DISTRO_PATH);
|
||||
|
||||
#else
|
||||
vmSettings.RootVhd = std::filesystem::path(common::wslutil::GetMsiPackagePath().value()) / L"wslarootfs.vhd";
|
||||
|
||||
#endif
|
||||
|
||||
vmSettings.RootVhdType = "squashfs";
|
||||
}
|
||||
|
||||
|
||||
@ -16,9 +16,9 @@ Abstract:
|
||||
#include <format>
|
||||
#include <filesystem>
|
||||
#include "hcs_schema.h"
|
||||
#include "VirtioNetworking.h"
|
||||
#include "NatNetworking.h"
|
||||
#include "WSLAUserSession.h"
|
||||
#include "DnsResolver.h"
|
||||
#include "ServiceProcessLauncher.h"
|
||||
|
||||
using namespace wsl::windows::common;
|
||||
@ -85,6 +85,12 @@ WSLAVirtualMachine::~WSLAVirtualMachine()
|
||||
|
||||
WSL_LOG("WSLATerminateVm", TraceLoggingValue(forceTerminate, "forced"), TraceLoggingValue(m_running, "running"));
|
||||
|
||||
// Shutdown DeviceHostProxy before resetting compute system
|
||||
if (m_guestDeviceManager)
|
||||
{
|
||||
m_guestDeviceManager->Shutdown();
|
||||
}
|
||||
|
||||
m_computeSystem.reset();
|
||||
|
||||
for (const auto& e : m_attachedDisks)
|
||||
@ -300,6 +306,13 @@ void WSLAVirtualMachine::Start()
|
||||
auto runtimeId = wsl::windows::common::hcs::GetRuntimeId(m_computeSystem.get());
|
||||
WI_ASSERT(IsEqualGUID(m_vmId, runtimeId));
|
||||
|
||||
// Initialize DeviceHostProxy for virtio device support.
|
||||
// N.B. This is currently only needed for VirtioProxy networking mode but would also be needed for virtiofs.
|
||||
if (m_settings.NetworkingMode == WSLANetworkingModeVirtioProxy)
|
||||
{
|
||||
m_guestDeviceManager = std::make_shared<GuestDeviceManager>(m_vmIdString, m_vmId);
|
||||
}
|
||||
|
||||
wsl::windows::common::hcs::RegisterCallback(m_computeSystem.get(), &s_OnExit, this);
|
||||
|
||||
wsl::windows::common::hcs::StartComputeSystem(m_computeSystem.get(), json.c_str());
|
||||
@ -428,59 +441,71 @@ CATCH_LOG();
|
||||
|
||||
void WSLAVirtualMachine::ConfigureNetworking()
|
||||
{
|
||||
if (m_settings.NetworkingMode == WSLANetworkingModeNone)
|
||||
switch (m_settings.NetworkingMode)
|
||||
{
|
||||
case WSLANetworkingModeNone:
|
||||
return;
|
||||
case WSLANetworkingModeNAT:
|
||||
case WSLANetworkingModeVirtioProxy:
|
||||
break;
|
||||
default:
|
||||
THROW_HR_MSG(E_INVALIDARG, "Invalid networking mode: %lu", m_settings.NetworkingMode);
|
||||
}
|
||||
else if (m_settings.NetworkingMode == WSLANetworkingModeNAT)
|
||||
|
||||
// Launch GNS
|
||||
std::vector<WSLA_PROCESS_FD> fds(1);
|
||||
fds[0].Fd = -1;
|
||||
fds[0].Type = WSLAFdType::WSLAFdTypeDefault;
|
||||
|
||||
std::vector<const char*> cmd{"/gns", LX_INIT_GNS_SOCKET_ARG};
|
||||
|
||||
// If DNS tunnelling is enabled, use an additional for its channel.
|
||||
if (FeatureEnabled(WslaFeatureFlagsDnsTunneling))
|
||||
{
|
||||
// Launch GNS
|
||||
std::vector<WSLA_PROCESS_FD> fds(1);
|
||||
fds[0].Fd = -1;
|
||||
fds[0].Type = WSLAFdType::WSLAFdTypeDefault;
|
||||
THROW_HR_IF_MSG(
|
||||
E_NOTIMPL,
|
||||
m_settings.NetworkingMode == WSLANetworkingModeVirtioProxy,
|
||||
"DNS tunneling not currently supported for VirtioProxy");
|
||||
|
||||
std::vector<const char*> cmd{"/gns", LX_INIT_GNS_SOCKET_ARG};
|
||||
fds.emplace_back(WSLA_PROCESS_FD{.Fd = -1, .Type = WSLAFdType::WSLAFdTypeDefault});
|
||||
THROW_IF_FAILED(wsl::core::networking::DnsResolver::LoadDnsResolverMethods());
|
||||
}
|
||||
|
||||
// If DNS tunnelling is enabled, use an additional for its channel.
|
||||
if (FeatureEnabled(WslaFeatureFlagsDnsTunneling))
|
||||
WSLA_PROCESS_OPTIONS options{};
|
||||
options.Executable = "/init";
|
||||
options.Fds = fds.data();
|
||||
options.FdsCount = static_cast<DWORD>(fds.size());
|
||||
|
||||
// Because the file descriptors numbers aren't known in advance, the command line needs to be generated after the file
|
||||
// descriptors are allocated.
|
||||
std::string socketFdArg;
|
||||
std::string dnsFdArg;
|
||||
int gnsChannelFd = -1;
|
||||
int dnsChannelFd = -1;
|
||||
auto prepareCommandLine = [&](const auto& sockets) {
|
||||
gnsChannelFd = sockets[0].Fd;
|
||||
socketFdArg = std::to_string(gnsChannelFd);
|
||||
cmd.emplace_back(socketFdArg.c_str());
|
||||
|
||||
if (sockets.size() > 1)
|
||||
{
|
||||
fds.emplace_back(WSLA_PROCESS_FD{.Fd = -1, .Type = WSLAFdType::WSLAFdTypeDefault});
|
||||
THROW_IF_FAILED(wsl::core::networking::DnsResolver::LoadDnsResolverMethods());
|
||||
dnsChannelFd = sockets[1].Fd;
|
||||
dnsFdArg = std::to_string(dnsChannelFd);
|
||||
cmd.emplace_back(LX_INIT_GNS_DNS_SOCKET_ARG);
|
||||
cmd.emplace_back(dnsFdArg.c_str());
|
||||
cmd.emplace_back(LX_INIT_GNS_DNS_TUNNELING_IP);
|
||||
cmd.emplace_back(LX_INIT_DNS_TUNNELING_IP_ADDRESS);
|
||||
}
|
||||
|
||||
WSLA_PROCESS_OPTIONS options{};
|
||||
options.Executable = "/init";
|
||||
options.Fds = fds.data();
|
||||
options.FdsCount = static_cast<DWORD>(fds.size());
|
||||
options.CommandLine = cmd.data();
|
||||
options.CommandLineCount = static_cast<DWORD>(cmd.size());
|
||||
};
|
||||
|
||||
// Because the file descriptors numbers aren't known in advance, the command line needs to be generated after the file
|
||||
// descriptors are allocated.
|
||||
|
||||
std::string socketFdArg;
|
||||
std::string dnsFdArg;
|
||||
int gnsChannelFd = -1;
|
||||
int dnsChannelFd = -1;
|
||||
auto prepareCommandLine = [&](const auto& sockets) {
|
||||
gnsChannelFd = sockets[0].Fd;
|
||||
socketFdArg = std::to_string(gnsChannelFd);
|
||||
cmd.emplace_back(socketFdArg.c_str());
|
||||
|
||||
if (sockets.size() > 1)
|
||||
{
|
||||
dnsChannelFd = sockets[1].Fd;
|
||||
dnsFdArg = std::to_string(dnsChannelFd);
|
||||
cmd.emplace_back(LX_INIT_GNS_DNS_SOCKET_ARG);
|
||||
cmd.emplace_back(dnsFdArg.c_str());
|
||||
cmd.emplace_back(LX_INIT_GNS_DNS_TUNNELING_IP);
|
||||
cmd.emplace_back(LX_INIT_DNS_TUNNELING_IP_ADDRESS);
|
||||
}
|
||||
|
||||
options.CommandLine = cmd.data();
|
||||
options.CommandLineCount = static_cast<DWORD>(cmd.size());
|
||||
};
|
||||
|
||||
auto process = CreateLinuxProcess(options, nullptr, prepareCommandLine);
|
||||
auto process = CreateLinuxProcess(options, nullptr, prepareCommandLine);
|
||||
auto gnsChannel = wsl::core::GnsChannel(wil::unique_socket{(SOCKET)process->GetStdHandle(gnsChannelFd).release()});
|
||||
|
||||
if (m_settings.NetworkingMode == WSLANetworkingModeNAT)
|
||||
{
|
||||
// TODO: refactor this to avoid using wsl config
|
||||
static wsl::core::Config config(nullptr);
|
||||
|
||||
@ -493,18 +518,18 @@ void WSLAVirtualMachine::ConfigureNetworking()
|
||||
m_networkEngine = std::make_unique<wsl::core::NatNetworking>(
|
||||
m_computeSystem.get(),
|
||||
wsl::core::NatNetworking::CreateNetwork(config),
|
||||
wil::unique_socket{(SOCKET)process->GetStdHandle(gnsChannelFd).release()},
|
||||
std::move(gnsChannel),
|
||||
config,
|
||||
dnsChannelFd != -1 ? wil::unique_socket{(SOCKET)process->GetStdHandle(dnsChannelFd).release()} : wil::unique_socket{});
|
||||
|
||||
m_networkEngine->Initialize();
|
||||
|
||||
LaunchPortRelay();
|
||||
}
|
||||
else
|
||||
{
|
||||
THROW_HR_MSG(E_INVALIDARG, "Invalid networking mode: %lu", m_settings.NetworkingMode);
|
||||
m_networkEngine = std::make_unique<wsl::core::VirtioNetworking>(std::move(gnsChannel), true, m_guestDeviceManager, m_userToken);
|
||||
}
|
||||
|
||||
m_networkEngine->Initialize();
|
||||
|
||||
LaunchPortRelay();
|
||||
}
|
||||
|
||||
void CALLBACK WSLAVirtualMachine::s_OnExit(_In_ HCS_EVENT* Event, _In_opt_ void* Context)
|
||||
|
||||
@ -16,6 +16,8 @@ Abstract:
|
||||
#include "INetworkingEngine.h"
|
||||
#include "hcs.hpp"
|
||||
#include "Dmesg.h"
|
||||
#include "DnsResolver.h"
|
||||
#include "GuestDeviceManager.h"
|
||||
#include "WSLAApi.h"
|
||||
#include "WSLAProcess.h"
|
||||
|
||||
@ -134,7 +136,7 @@ private:
|
||||
int m_coldDiscardShiftSize{};
|
||||
bool m_running = false;
|
||||
PSID m_userSid{};
|
||||
wil::unique_handle m_userToken;
|
||||
wil::shared_handle m_userToken;
|
||||
std::wstring m_debugShellPipe;
|
||||
|
||||
std::mutex m_trackedProcessesLock;
|
||||
@ -147,6 +149,7 @@ private:
|
||||
bool m_vmSavedStateCaptured = false;
|
||||
bool m_crashLogCaptured = false;
|
||||
|
||||
std::shared_ptr<GuestDeviceManager> m_guestDeviceManager;
|
||||
std::shared_ptr<DmesgCollector> m_dmesgCollector;
|
||||
wil::unique_event m_vmExitEvent{wil::EventOptions::ManualReset};
|
||||
wil::unique_event m_vmTerminatingEvent{wil::EventOptions::ManualReset};
|
||||
|
||||
@ -215,7 +215,8 @@ interface IWSLAVirtualMachine : IUnknown
|
||||
typedef enum _WSLANetworkingMode
|
||||
{
|
||||
WSLANetworkingModeNone,
|
||||
WSLANetworkingModeNAT
|
||||
WSLANetworkingModeNAT,
|
||||
WSLANetworkingModeVirtioProxy
|
||||
} WSLANetworkingMode;
|
||||
|
||||
typedef enum _WSLAFeatureFlags
|
||||
@ -317,7 +318,7 @@ interface IWSLAUserSession : IUnknown
|
||||
HRESULT CreateSession([in] const struct WSLA_SESSION_SETTINGS* Settings, [out]IWSLASession** Session);
|
||||
HRESULT ListSessions([out, size_is(, *SessionsCount)] struct WSLA_SESSION_INFORMATION** Sessions, [out] ULONG* SessionsCount);
|
||||
HRESULT OpenSession([in] ULONG Id, [out]IWSLASession** Session);
|
||||
HRESULT OpenSessionByName([in] LPCWSTR DisplayName, [out]IWSLASession** Session);
|
||||
HRESULT OpenSessionByName([in] LPCWSTR DisplayName, [out] IWSLASession** Session);
|
||||
|
||||
// TODO: Do we need 'TerminateSession()' ?
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user