Move the logic to mount the root VHD & basic filesystems to the service (#13726)

This commit is contained in:
Blue 2025-11-15 00:58:58 +00:00 committed by GitHub
parent d63fee34f2
commit 14257f99de
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 61 additions and 146 deletions

View File

@ -1574,21 +1574,13 @@ int WslaShell(_In_ std::wstring_view commandLine)
wil::com_ptr<IWSLAVirtualMachine> virtualMachine; wil::com_ptr<IWSLAVirtualMachine> virtualMachine;
WSLA_SESSION_SETTINGS sessionSettings{L"my-display-name"}; WSLA_SESSION_SETTINGS sessionSettings{L"my-display-name"};
wil::com_ptr<IWSLASession> session; wil::com_ptr<IWSLASession> session;
settings.RootVhd = vhd.c_str();
settings.RootVhdType = fsType.c_str();
THROW_IF_FAILED(userSession->CreateSession(&sessionSettings, &settings, &session)); THROW_IF_FAILED(userSession->CreateSession(&sessionSettings, &settings, &session));
THROW_IF_FAILED(session->GetVirtualMachine(&virtualMachine)); THROW_IF_FAILED(session->GetVirtualMachine(&virtualMachine));
wsl::windows::common::security::ConfigureForCOMImpersonation(userSession.get()); wsl::windows::common::security::ConfigureForCOMImpersonation(userSession.get());
wil::unique_cotaskmem_ansistring diskDevice;
ULONG Lun{};
THROW_IF_FAILED(virtualMachine->AttachDisk(vhd.c_str(), true, &diskDevice, &Lun));
THROW_IF_FAILED(virtualMachine->Mount(diskDevice.get(), "/mnt", fsType.c_str(), "ro", WslMountFlagsChroot | WslMountFlagsWriteableOverlayFs));
THROW_IF_FAILED(virtualMachine->Mount(nullptr, "/dev", "devtmpfs", "", 0));
THROW_IF_FAILED(virtualMachine->Mount(nullptr, "/sys", "sysfs", "", 0));
THROW_IF_FAILED(virtualMachine->Mount(nullptr, "/proc", "proc", "", 0));
THROW_IF_FAILED(virtualMachine->Mount(nullptr, "/dev/pts", "devpts", "noatime,nosuid,noexec,gid=5,mode=620", 0));
wsl::windows::common::WSLAProcessLauncher launcher{shell, {shell}, {"TERM=xterm-256color"}, ProcessFlags::None}; wsl::windows::common::WSLAProcessLauncher launcher{shell, {shell}, {"TERM=xterm-256color"}, ProcessFlags::None};
launcher.AddFd(WSLA_PROCESS_FD{.Fd = 0, .Type = WslFdTypeTerminalInput}); launcher.AddFd(WSLA_PROCESS_FD{.Fd = 0, .Type = WslFdTypeTerminalInput});
launcher.AddFd(WSLA_PROCESS_FD{.Fd = 1, .Type = WslFdTypeTerminalOutput}); launcher.AddFd(WSLA_PROCESS_FD{.Fd = 1, .Type = WslFdTypeTerminalOutput});

View File

@ -91,26 +91,6 @@ try
} }
CATCH_RETURN(); CATCH_RETURN();
HRESULT WslAttachDisk(WslVirtualMachineHandle VirtualMachine, const WslDiskAttachSettings* Settings, WslAttachedDiskInformation* AttachedDisk)
{
wil::unique_cotaskmem_ansistring device;
RETURN_IF_FAILED(reinterpret_cast<IWSLAVirtualMachine*>(VirtualMachine)
->AttachDisk(Settings->WindowsPath, Settings->ReadOnly, &device, &AttachedDisk->ScsiLun));
auto deviceSize = strlen(device.get());
WI_VERIFY(deviceSize < sizeof(WslAttachedDiskInformation::Device));
strncpy(AttachedDisk->Device, device.get(), sizeof(WslAttachedDiskInformation::Device));
return S_OK;
}
HRESULT WslMount(WslVirtualMachineHandle VirtualMachine, const WslMountSettings* Settings)
{
return reinterpret_cast<IWSLAVirtualMachine*>(VirtualMachine)
->Mount(Settings->Device, Settings->Target, Settings->Type, Settings->Options, Settings->Flags);
}
HRESULT WslCreateLinuxProcess(WslVirtualMachineHandle VirtualMachine, WslCreateProcessSettings* UserSettings, int32_t* Pid) HRESULT WslCreateLinuxProcess(WslVirtualMachineHandle VirtualMachine, WslCreateProcessSettings* UserSettings, int32_t* Pid)
{ {
return S_OK; return S_OK;

View File

@ -96,14 +96,6 @@ struct WslDiskAttachSettings
bool ReadOnly; bool ReadOnly;
}; };
struct WslAttachedDiskInformation
{
ULONG ScsiLun;
char Device[10];
};
HRESULT WslAttachDisk(WslVirtualMachineHandle VirtualMachine, const struct WslDiskAttachSettings* Settings, struct WslAttachedDiskInformation* AttachedDisk);
enum WslMountFlags enum WslMountFlags
{ {
WslMountFlagsNone = 0, WslMountFlagsNone = 0,
@ -111,17 +103,6 @@ enum WslMountFlags
WslMountFlagsWriteableOverlayFs = 2, WslMountFlagsWriteableOverlayFs = 2,
}; };
struct WslMountSettings
{
const char* Device;
const char* Target;
const char* Type;
const char* Options;
uint32_t Flags;
};
HRESULT WslMount(WslVirtualMachineHandle VirtualMachine, const struct WslMountSettings* Settings);
enum WslFdType enum WslFdType
{ {
WslFdTypeDefault = 0, WslFdTypeDefault = 0,

View File

@ -3,8 +3,6 @@ LIBRARY wslaclient
EXPORTS EXPORTS
WslGetVersion WslGetVersion
WslCreateVirtualMachine WslCreateVirtualMachine
WslAttachDisk
WslMount
WslCreateLinuxProcess WslCreateLinuxProcess
WslWaitForLinuxProcess WslWaitForLinuxProcess
WslSignalLinuxProcess WslSignalLinuxProcess

View File

@ -331,15 +331,8 @@ void WSLAVirtualMachine::Start()
#endif #endif
wil::unique_cotaskmem_ansistring device; auto [_, device] = AttachDisk(kernelModulesPath.c_str(), true);
ULONG lun{}; Mount(m_initChannel, device.c_str(), "", "ext4", "ro", WSLA_MOUNT::KernelModules);
THROW_IF_FAILED(AttachDisk(kernelModulesPath.c_str(), true, &device, &lun));
THROW_HR_IF_MSG(
E_FAIL,
MountImpl(m_initChannel, device.get(), "", "ext4", "ro", WSLA_MOUNT::KernelModules) != 0,
"Failed to mount the kernel modules from: %hs",
device.get());
// Configure GPU if requested. // Configure GPU if requested.
if (m_settings.EnableGPU) if (m_settings.EnableGPU)
@ -358,7 +351,9 @@ void WSLAVirtualMachine::Start()
wsl::windows::common::hcs::ModifyComputeSystem(m_computeSystem.get(), wsl::shared::ToJsonW(gpuRequest).c_str()); wsl::windows::common::hcs::ModifyComputeSystem(m_computeSystem.get(), wsl::shared::ToJsonW(gpuRequest).c_str());
} }
auto [_, __, childChannel] = Fork(WSLA_FORK::Thread); ConfigureMounts();
auto [__, ___, childChannel] = Fork(WSLA_FORK::Thread);
WSLA_WATCH_PROCESSES watchMessage{}; WSLA_WATCH_PROCESSES watchMessage{};
childChannel.SendMessage(watchMessage); childChannel.SendMessage(watchMessage);
@ -368,6 +363,19 @@ void WSLAVirtualMachine::Start()
m_processExitThread = std::thread(std::bind(&WSLAVirtualMachine::WatchForExitedProcesses, this, std::move(childChannel))); m_processExitThread = std::thread(std::bind(&WSLAVirtualMachine::WatchForExitedProcesses, this, std::move(childChannel)));
} }
void WSLAVirtualMachine::ConfigureMounts()
{
auto [_, device] = AttachDisk(m_settings.RootVhd, true);
Mount(m_initChannel, device.c_str(), "/mnt", m_settings.RootVhdType, "ro", WslMountFlagsChroot | WslMountFlagsWriteableOverlayFs);
Mount(m_initChannel, nullptr, "/dev", "devtmpfs", "", 0);
Mount(m_initChannel, nullptr, "/sys", "sysfs", "", 0);
Mount(m_initChannel, nullptr, "/proc", "proc", "", 0);
Mount(m_initChannel, nullptr, "/dev/pts", "devpts", "noatime,nosuid,noexec,gid=5,mode=620", 0);
// TODO: Mount storage VHD here.
}
void WSLAVirtualMachine::WatchForExitedProcesses(wsl::shared::SocketChannel& Channel) void WSLAVirtualMachine::WatchForExitedProcesses(wsl::shared::SocketChannel& Channel)
try try
{ {
@ -566,10 +574,11 @@ void WSLAVirtualMachine::OnCrash(_In_ const HCS_EVENT* Event)
} }
} }
HRESULT WSLAVirtualMachine::AttachDisk(_In_ PCWSTR Path, _In_ BOOL ReadOnly, _Out_ LPSTR* Device, _Out_ ULONG* Lun) std::pair<ULONG, std::string> WSLAVirtualMachine::AttachDisk(_In_ PCWSTR Path, _In_ BOOL ReadOnly)
try
{ {
*Device = nullptr; ULONG Lun{};
std::string Device;
auto result = wil::ResultFromException([&]() { auto result = wil::ResultFromException([&]() {
std::lock_guard lock{m_lock}; std::lock_guard lock{m_lock};
THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), m_running); THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), m_running);
@ -588,17 +597,16 @@ try
grantDiskAccess(); grantDiskAccess();
} }
*Lun = 0; while (m_attachedDisks.find(Lun) != m_attachedDisks.end())
while (m_attachedDisks.find(*Lun) != m_attachedDisks.end())
{ {
(*Lun)++; Lun++;
} }
bool vhdAdded = false; bool vhdAdded = false;
auto cleanup = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&]() { auto cleanup = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&]() {
if (vhdAdded) if (vhdAdded)
{ {
wsl::windows::common::hcs::RemoveScsiDisk(m_computeSystem.get(), *Lun); wsl::windows::common::hcs::RemoveScsiDisk(m_computeSystem.get(), Lun);
} }
if (disk.AccessGranted) if (disk.AccessGranted)
@ -608,12 +616,12 @@ try
}); });
auto result = auto result =
wil::ResultFromException([&]() { wsl::windows::common::hcs::AddVhd(m_computeSystem.get(), Path, *Lun, ReadOnly); }); wil::ResultFromException([&]() { wsl::windows::common::hcs::AddVhd(m_computeSystem.get(), Path, Lun, ReadOnly); });
if (result == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED) && !disk.AccessGranted) if (result == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED) && !disk.AccessGranted)
{ {
grantDiskAccess(); grantDiskAccess();
wsl::windows::common::hcs::AddVhd(m_computeSystem.get(), Path, *Lun, ReadOnly); wsl::windows::common::hcs::AddVhd(m_computeSystem.get(), Path, Lun, ReadOnly);
} }
else else
{ {
@ -625,7 +633,7 @@ try
WSLA_GET_DISK message{}; WSLA_GET_DISK message{};
message.Header.MessageSize = sizeof(message); message.Header.MessageSize = sizeof(message);
message.Header.MessageType = WSLA_GET_DISK::Type; message.Header.MessageType = WSLA_GET_DISK::Type;
message.ScsiLun = *Lun; message.ScsiLun = Lun;
const auto& response = m_initChannel.Transaction(message); const auto& response = m_initChannel.Transaction(message);
THROW_HR_IF_MSG(E_FAIL, response.Result != 0, "Failed to attach disk, init returned: %lu", response.Result); THROW_HR_IF_MSG(E_FAIL, response.Result != 0, "Failed to attach disk, init returned: %lu", response.Result);
@ -633,35 +641,19 @@ try
cleanup.release(); cleanup.release();
disk.Device = response.Buffer; disk.Device = response.Buffer;
m_attachedDisks.emplace(*Lun, std::move(disk)); Device = disk.Device;
m_attachedDisks.emplace(Lun, std::move(disk));
*Device = wil::make_unique_ansistring<wil::unique_cotaskmem_ansistring>(response.Buffer).release();
}); });
WSL_LOG( WSL_LOG(
"WSLAAttachDisk", "WSLAAttachDisk",
TraceLoggingValue(Path, "Path"), TraceLoggingValue(Path, "Path"),
TraceLoggingValue(ReadOnly, "ReadOnly"), TraceLoggingValue(ReadOnly, "ReadOnly"),
TraceLoggingValue(*Device == nullptr ? "<null>" : *Device, "Device"), TraceLoggingValue(Device.c_str(), "Device"),
TraceLoggingValue(result, "Result")); TraceLoggingValue(result, "Result"));
return result; return {Lun, Device};
} }
CATCH_RETURN();
HRESULT WSLAVirtualMachine::Mount(_In_ LPCSTR Source, _In_ LPCSTR Target, _In_ LPCSTR Type, _In_ LPCSTR Options, _In_ ULONG Flags)
try
{
THROW_HR_IF(E_INVALIDARG, WI_IsAnyFlagSet(Flags, ~(WslMountFlagsChroot | WslMountFlagsWriteableOverlayFs)));
std::lock_guard lock{m_lock};
THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), m_running);
THROW_HR_IF(E_FAIL, MountImpl(m_initChannel, Source, Target, Type, Options, Flags) != 0);
return S_OK;
}
CATCH_RETURN();
HRESULT WSLAVirtualMachine::Unmount(_In_ const char* Path) HRESULT WSLAVirtualMachine::Unmount(_In_ const char* Path)
try try
@ -893,7 +885,7 @@ Microsoft::WRL::ComPtr<WSLAProcess> WSLAVirtualMachine::CreateLinuxProcessImpl(
return process; return process;
} }
int32_t WSLAVirtualMachine::MountImpl(shared::SocketChannel& Channel, LPCSTR Source, LPCSTR Target, LPCSTR Type, LPCSTR Options, ULONG Flags) void WSLAVirtualMachine::Mount(shared::SocketChannel& Channel, LPCSTR Source, LPCSTR Target, LPCSTR Type, LPCSTR Options, ULONG Flags)
{ {
static_assert(WslMountFlagsNone == WSLA_MOUNT::None); static_assert(WslMountFlagsNone == WSLA_MOUNT::None);
static_assert(WslMountFlagsChroot == WSLA_MOUNT::Chroot); static_assert(WslMountFlagsChroot == WSLA_MOUNT::Chroot);
@ -925,7 +917,7 @@ int32_t WSLAVirtualMachine::MountImpl(shared::SocketChannel& Channel, LPCSTR Sou
TraceLoggingValue(Flags, "Flags"), TraceLoggingValue(Flags, "Flags"),
TraceLoggingValue(response.Result, "Result")); TraceLoggingValue(response.Result, "Result"));
return response.Result; THROW_HR_IF(E_FAIL, response.Result != 0);
} }
int32_t WSLAVirtualMachine::ExpectClosedChannelOrError(wsl::shared::SocketChannel& Channel) int32_t WSLAVirtualMachine::ExpectClosedChannelOrError(wsl::shared::SocketChannel& Channel)
@ -1175,7 +1167,7 @@ try
auto mountOptions = auto mountOptions =
std::format("msize={},trans=fd,rfdno={},wfdno={},aname={},cache=mmap", LX_INIT_UTILITY_VM_PLAN9_BUFFER_SIZE, fd, fd, shareNameUtf8); std::format("msize={},trans=fd,rfdno={},wfdno={},aname={},cache=mmap", LX_INIT_UTILITY_VM_PLAN9_BUFFER_SIZE, fd, fd, shareNameUtf8);
THROW_HR_IF(E_FAIL, MountImpl(channel, shareNameUtf8.c_str(), LinuxPath, "9p", mountOptions.c_str(), Flags) != 0); Mount(channel, shareNameUtf8.c_str(), LinuxPath, "9p", mountOptions.c_str(), Flags);
deleteOnFailure.release(); deleteOnFailure.release();
return S_OK; return S_OK;
@ -1250,7 +1242,7 @@ try
options += ":" + inboxLibMountPoint.value(); options += ":" + inboxLibMountPoint.value();
} }
RETURN_IF_FAILED(Mount("none", LibrariesMountPoint, "overlay", options.c_str(), Flags)); Mount(m_initChannel, "none", LibrariesMountPoint, "overlay", options.c_str(), Flags);
return S_OK; return S_OK;
} }
CATCH_RETURN(); CATCH_RETURN();

View File

@ -36,8 +36,6 @@ public:
void Start(); void Start();
void OnSessionTerminating(); void OnSessionTerminating();
IFACEMETHOD(AttachDisk(_In_ PCWSTR Path, _In_ BOOL ReadOnly, _Out_ LPSTR* Device, _Out_ ULONG* Lun)) override;
IFACEMETHOD(Mount(_In_ LPCSTR Source, _In_ LPCSTR Target, _In_ LPCSTR Type, _In_ LPCSTR Options, _In_ ULONG Flags)) override;
IFACEMETHOD(CreateLinuxProcess(_In_ const WSLA_PROCESS_OPTIONS* Options, _Out_ IWSLAProcess** Process, _Out_ int* Errno)) override; IFACEMETHOD(CreateLinuxProcess(_In_ const WSLA_PROCESS_OPTIONS* Options, _Out_ IWSLAProcess** Process, _Out_ int* Errno)) override;
IFACEMETHOD(WaitPid(_In_ LONG Pid, _In_ ULONGLONG TimeoutMs, _Out_ ULONG* State, _Out_ int* Code)) override; IFACEMETHOD(WaitPid(_In_ LONG Pid, _In_ ULONGLONG TimeoutMs, _Out_ ULONG* State, _Out_ int* Code)) override;
IFACEMETHOD(Signal(_In_ LONG Pid, _In_ int Signal)) override; IFACEMETHOD(Signal(_In_ LONG Pid, _In_ int Signal)) override;
@ -62,12 +60,15 @@ private:
using TPrepareCommandLine = std::function<void(const std::vector<ConnectedSocket>&)>; using TPrepareCommandLine = std::function<void(const std::vector<ConnectedSocket>&)>;
static int32_t MountImpl(wsl::shared::SocketChannel& Channel, LPCSTR Source, _In_ LPCSTR Target, _In_ LPCSTR Type, _In_ LPCSTR Options, _In_ ULONG Flags); std::pair<ULONG, std::string> AttachDisk(_In_ PCWSTR Path, _In_ BOOL ReadOnly);
static void Mount(wsl::shared::SocketChannel& Channel, LPCSTR Source, _In_ LPCSTR Target, _In_ LPCSTR Type, _In_ LPCSTR Options, _In_ ULONG Flags);
static void CALLBACK s_OnExit(_In_ HCS_EVENT* Event, _In_opt_ void* Context); static void CALLBACK s_OnExit(_In_ HCS_EVENT* Event, _In_opt_ void* Context);
static bool ParseTtyInformation( static bool ParseTtyInformation(
const WSLA_PROCESS_FD* Fds, ULONG FdCount, const WSLA_PROCESS_FD** TtyInput, const WSLA_PROCESS_FD** TtyOutput, const WSLA_PROCESS_FD** TtyControl); const WSLA_PROCESS_FD* Fds, ULONG FdCount, const WSLA_PROCESS_FD** TtyInput, const WSLA_PROCESS_FD** TtyOutput, const WSLA_PROCESS_FD** TtyControl);
void ConfigureNetworking(); void ConfigureNetworking();
void ConfigureMounts();
void OnExit(_In_ const HCS_EVENT* Event); void OnExit(_In_ const HCS_EVENT* Event);
void OnCrash(_In_ const HCS_EVENT* Event); void OnCrash(_In_ const HCS_EVENT* Event);

View File

@ -166,8 +166,6 @@ interface IWSLAProcess : IUnknown
] ]
interface IWSLAVirtualMachine : IUnknown interface IWSLAVirtualMachine : IUnknown
{ {
HRESULT AttachDisk([in] LPCWSTR Path, [in] BOOL ReadOnly, [out] LPSTR* Device, [out] ULONG* Lun);
HRESULT Mount([in, unique] LPCSTR Source, [in] LPCSTR Target, [in] LPCSTR Type, [in] LPCSTR Options, [in] ULONG Flags);
HRESULT CreateLinuxProcess([in] const struct WSLA_PROCESS_OPTIONS* Options, [out] IWSLAProcess** Process, [out] int* Errno); HRESULT CreateLinuxProcess([in] const struct WSLA_PROCESS_OPTIONS* Options, [out] IWSLAProcess** Process, [out] int* Errno);
HRESULT WaitPid([in] LONG Pid, [in] ULONGLONG TimeoutMs, [out] ULONG* State, [out] int* Code); HRESULT WaitPid([in] LONG Pid, [in] ULONGLONG TimeoutMs, [out] ULONG* State, [out] int* Code);
HRESULT Signal([in] LONG Pid, [in] int Signal); HRESULT Signal([in] LONG Pid, [in] int Signal);
@ -194,6 +192,8 @@ struct _VIRTUAL_MACHINE_SETTINGS { // TODO: Delete once the new API is wired.
BOOL EnableDebugShell; BOOL EnableDebugShell;
BOOL EnableEarlyBootDmesg; BOOL EnableEarlyBootDmesg;
BOOL EnableGPU; BOOL EnableGPU;
LPCWSTR RootVhd; // Temporary option to provide the root VHD. TODO: Remove once runtime VHD is available.
LPCSTR RootVhdType; // Temporary option to provide the root VHD. TODO: Remove once runtime VHD is available.
} VIRTUAL_MACHINE_SETTINGS; } VIRTUAL_MACHINE_SETTINGS;

View File

@ -52,8 +52,10 @@ class WSLATests
return true; return true;
} }
wil::com_ptr<IWSLASession> CreateSession(const VIRTUAL_MACHINE_SETTINGS& vmSettings, const std::optional<std::wstring>& vhd = {}) wil::com_ptr<IWSLASession> CreateSession(VIRTUAL_MACHINE_SETTINGS& vmSettings)
{ {
vmSettings.RootVhdType = "ext4";
wil::com_ptr<IWSLAUserSession> userSession; wil::com_ptr<IWSLAUserSession> userSession;
VERIFY_SUCCEEDED(CoCreateInstance(__uuidof(WSLAUserSession), nullptr, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&userSession))); VERIFY_SUCCEEDED(CoCreateInstance(__uuidof(WSLAUserSession), nullptr, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&userSession)));
wsl::windows::common::security::ConfigureForCOMImpersonation(userSession.get()); wsl::windows::common::security::ConfigureForCOMImpersonation(userSession.get());
@ -62,23 +64,6 @@ class WSLATests
wil::com_ptr<IWSLASession> session; wil::com_ptr<IWSLASession> session;
VERIFY_SUCCEEDED(userSession->CreateSession(&settings, &vmSettings, &session)); VERIFY_SUCCEEDED(userSession->CreateSession(&settings, &vmSettings, &session));
// TODO: remove once the VM is wired to mount its rootfs inside WSLASession
wil::com_ptr<IWSLAVirtualMachine> virtualMachine;
VERIFY_SUCCEEDED(session->GetVirtualMachine(&virtualMachine));
wsl::windows::common::security::ConfigureForCOMImpersonation(virtualMachine.get());
wil::unique_cotaskmem_ansistring diskDevice;
ULONG Lun{};
THROW_IF_FAILED(virtualMachine->AttachDisk(vhd.value_or(testVhd).c_str(), true, &diskDevice, &Lun));
THROW_IF_FAILED(virtualMachine->Mount(diskDevice.get(), "/mnt", "ext4", "ro", WslMountFlagsChroot | WslMountFlagsWriteableOverlayFs));
THROW_IF_FAILED(virtualMachine->Mount(nullptr, "/dev", "devtmpfs", "", 0));
THROW_IF_FAILED(virtualMachine->Mount(nullptr, "/sys", "sysfs", "", 0));
THROW_IF_FAILED(virtualMachine->Mount(nullptr, "/proc", "proc", "", 0));
THROW_IF_FAILED(virtualMachine->Mount(nullptr, "/dev/pts", "devpts", "noatime,nosuid,noexec,gid=5,mode=620", 0));
return session; return session;
} }
@ -159,6 +144,7 @@ class WSLATests
settings.BootTimeoutMs = 30 * 1000; settings.BootTimeoutMs = 30 * 1000;
settings.DmesgOutput = (ULONG) reinterpret_cast<ULONG_PTR>(write.get()); settings.DmesgOutput = (ULONG) reinterpret_cast<ULONG_PTR>(write.get());
settings.EnableEarlyBootDmesg = earlyBootLogging; settings.EnableEarlyBootDmesg = earlyBootLogging;
settings.RootVhd = testVhd.c_str();
std::vector<char> dmesgContent; std::vector<char> dmesgContent;
auto readDmesg = [read = read.get(), &dmesgContent]() mutable { auto readDmesg = [read = read.get(), &dmesgContent]() mutable {
@ -275,6 +261,7 @@ class WSLATests
settings.DisplayName = L"WSLA"; settings.DisplayName = L"WSLA";
settings.MemoryMb = 2048; settings.MemoryMb = 2048;
settings.BootTimeoutMs = 30 * 1000; settings.BootTimeoutMs = 30 * 1000;
settings.RootVhd = testVhd.c_str();
auto session = CreateSession(settings); auto session = CreateSession(settings);
@ -330,6 +317,7 @@ class WSLATests
settings.MemoryMb = 2048; settings.MemoryMb = 2048;
settings.BootTimeoutMs = 30 * 1000; settings.BootTimeoutMs = 30 * 1000;
settings.NetworkingMode = WslNetworkingModeNAT; settings.NetworkingMode = WslNetworkingModeNAT;
settings.RootVhd = testVhd.c_str();
auto session = CreateSession(settings); auto session = CreateSession(settings);
@ -355,6 +343,7 @@ class WSLATests
settings.BootTimeoutMs = 30 * 1000; settings.BootTimeoutMs = 30 * 1000;
settings.NetworkingMode = WslNetworkingModeNAT; settings.NetworkingMode = WslNetworkingModeNAT;
settings.EnableDnsTunneling = true; settings.EnableDnsTunneling = true;
settings.RootVhd = testVhd.c_str();
auto session = CreateSession(settings); auto session = CreateSession(settings);
@ -381,6 +370,7 @@ class WSLATests
settings.DisplayName = L"WSLA"; settings.DisplayName = L"WSLA";
settings.MemoryMb = 2048; settings.MemoryMb = 2048;
settings.BootTimeoutMs = 30 * 1000; settings.BootTimeoutMs = 30 * 1000;
settings.RootVhd = testVhd.c_str();
auto session = CreateSession(settings); auto session = CreateSession(settings);
@ -493,6 +483,7 @@ class WSLATests
settings.MemoryMb = 2048; settings.MemoryMb = 2048;
settings.BootTimeoutMs = 30 * 1000; settings.BootTimeoutMs = 30 * 1000;
settings.NetworkingMode = WslNetworkingModeNAT; settings.NetworkingMode = WslNetworkingModeNAT;
settings.RootVhd = testVhd.c_str();
auto session = CreateSession(settings); auto session = CreateSession(settings);
@ -637,6 +628,7 @@ class WSLATests
settings.DisplayName = L"WSLA"; settings.DisplayName = L"WSLA";
settings.MemoryMb = 2048; settings.MemoryMb = 2048;
settings.BootTimeoutMs = 30 * 1000; settings.BootTimeoutMs = 30 * 1000;
settings.RootVhd = testVhd.c_str();
auto session = CreateSession(settings); auto session = CreateSession(settings);
@ -656,6 +648,7 @@ class WSLATests
settings.DisplayName = L"WSLA"; settings.DisplayName = L"WSLA";
settings.MemoryMb = 2048; settings.MemoryMb = 2048;
settings.BootTimeoutMs = 30 * 1000; settings.BootTimeoutMs = 30 * 1000;
settings.RootVhd = testVhd.c_str();
auto session = CreateSession(settings); auto session = CreateSession(settings);
@ -742,6 +735,7 @@ class WSLATests
settings.DisplayName = L"WSLA"; settings.DisplayName = L"WSLA";
settings.MemoryMb = 2048; settings.MemoryMb = 2048;
settings.BootTimeoutMs = 30 * 1000; settings.BootTimeoutMs = 30 * 1000;
settings.RootVhd = testVhd.c_str();
auto session = CreateSession(settings); auto session = CreateSession(settings);
auto result = ExpectCommandResult( auto result = ExpectCommandResult(
@ -856,6 +850,7 @@ class WSLATests
settings.DisplayName = L"WSLA"; settings.DisplayName = L"WSLA";
settings.MemoryMb = 2048; settings.MemoryMb = 2048;
settings.BootTimeoutMs = 30 * 1000; settings.BootTimeoutMs = 30 * 1000;
settings.RootVhd = testVhd.c_str();
// Use the system distro vhd for modprobe & lsmod. // Use the system distro vhd for modprobe & lsmod.
@ -867,7 +862,9 @@ class WSLATests
auto rootfs = std::filesystem::path(wsl::windows::common::wslutil::GetMsiPackagePath().value()) / L"system.vhd"; auto rootfs = std::filesystem::path(wsl::windows::common::wslutil::GetMsiPackagePath().value()) / L"system.vhd";
#endif #endif
auto session = CreateSession(settings, rootfs); settings.RootVhd = rootfs.c_str();
auto session = CreateSession(settings);
// Sanity check. // Sanity check.
ExpectCommandResult(session.get(), {"/bin/bash", "-c", "lsmod | grep ^xsk_diag"}, 1); ExpectCommandResult(session.get(), {"/bin/bash", "-c", "lsmod | grep ^xsk_diag"}, 1);
@ -879,33 +876,6 @@ class WSLATests
ExpectCommandResult(session.get(), {"/bin/bash", "-c", "lsmod | grep ^xsk_diag"}, 0); ExpectCommandResult(session.get(), {"/bin/bash", "-c", "lsmod | grep ^xsk_diag"}, 0);
} }
TEST_METHOD(CreateSessionSmokeTest)
{
WSL2_TEST_ONLY();
wil::com_ptr<IWSLAUserSession> userSession;
VERIFY_SUCCEEDED(CoCreateInstance(__uuidof(WSLAUserSession), nullptr, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&userSession)));
wsl::windows::common::security::ConfigureForCOMImpersonation(userSession.get());
WSLA_SESSION_SETTINGS settings{L"my-display-name"};
wil::com_ptr<IWSLASession> session;
VIRTUAL_MACHINE_SETTINGS vmSettings{};
vmSettings.BootTimeoutMs = 30 * 1000;
vmSettings.DisplayName = L"WSLA";
vmSettings.MemoryMb = 2048;
vmSettings.CpuCount = 4;
vmSettings.NetworkingMode = WslNetworkingModeNone;
vmSettings.EnableDebugShell = true;
VERIFY_SUCCEEDED(userSession->CreateSession(&settings, &vmSettings, &session));
wil::unique_cotaskmem_string returnedDisplayName;
VERIFY_SUCCEEDED(session->GetDisplayName(&returnedDisplayName));
VERIFY_ARE_EQUAL(returnedDisplayName.get(), std::wstring(L"my-display-name"));
}
TEST_METHOD(CreateRootNamespaceProcess) TEST_METHOD(CreateRootNamespaceProcess)
{ {
WSL2_TEST_ONLY(); WSL2_TEST_ONLY();
@ -915,6 +885,7 @@ class WSLATests
settings.DisplayName = L"WSLA"; settings.DisplayName = L"WSLA";
settings.MemoryMb = 2048; settings.MemoryMb = 2048;
settings.BootTimeoutMs = 30 * 1000; settings.BootTimeoutMs = 30 * 1000;
settings.RootVhd = testVhd.c_str();
auto session = CreateSession(settings); auto session = CreateSession(settings);