mirror of
https://github.com/microsoft/WSL.git
synced 2025-12-11 13:54:51 -06:00
Move the logic to mount the root VHD & basic filesystems to the service (#13726)
This commit is contained in:
parent
d63fee34f2
commit
14257f99de
@ -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});
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -3,8 +3,6 @@ LIBRARY wslaclient
|
|||||||
EXPORTS
|
EXPORTS
|
||||||
WslGetVersion
|
WslGetVersion
|
||||||
WslCreateVirtualMachine
|
WslCreateVirtualMachine
|
||||||
WslAttachDisk
|
|
||||||
WslMount
|
|
||||||
WslCreateLinuxProcess
|
WslCreateLinuxProcess
|
||||||
WslWaitForLinuxProcess
|
WslWaitForLinuxProcess
|
||||||
WslSignalLinuxProcess
|
WslSignalLinuxProcess
|
||||||
|
|||||||
@ -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();
|
||||||
|
|||||||
@ -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);
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user