Fix various issues

This commit is contained in:
Blue 2025-11-25 16:57:45 -08:00
parent 3b5c028af5
commit 2a4f8d0bdd
10 changed files with 70 additions and 18 deletions

View File

@ -1551,6 +1551,7 @@ int WslaShell(_In_ std::wstring_view commandLine)
std::wstring containerRootVhd;
std::string containerImage;
bool help = false;
std::wstring debugShell;
ArgumentParser parser(std::wstring{commandLine}, WSL_BINARY_NAME);
parser.AddArgument(vhd, L"--vhd");
@ -1561,6 +1562,7 @@ int WslaShell(_In_ std::wstring_view commandLine)
parser.AddArgument(Utf8String(fsType), L"--fstype");
parser.AddArgument(containerRootVhd, L"--container-vhd");
parser.AddArgument(Utf8String(containerImage), L"--image");
parser.AddArgument(debugShell, L"--debug-shell");
parser.AddArgument(help, L"--help");
parser.Parse();
@ -1596,16 +1598,24 @@ int WslaShell(_In_ std::wstring_view commandLine)
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(session->GetVirtualMachine(&virtualMachine));
wsl::windows::common::security::ConfigureForCOMImpersonation(userSession.get());
if (!containerRootVhd.empty())
if (!debugShell.empty())
{
wsl::windows::common::WSLAProcessLauncher initProcessLauncher{shell, {shell, "/etc/lsw-init.sh"}};
auto initProcess = initProcessLauncher.Launch(*session);
THROW_HR_IF(E_FAIL, initProcess.WaitAndCaptureOutput().Code != 0);
THROW_IF_FAILED(userSession->OpenSessionByName(debugShell.c_str(), &session));
}
else
{
THROW_IF_FAILED(userSession->CreateSession(&sessionSettings, &settings, &session));
THROW_IF_FAILED(session->GetVirtualMachine(&virtualMachine));
wsl::windows::common::security::ConfigureForCOMImpersonation(userSession.get());
if (!containerRootVhd.empty())
{
wsl::windows::common::WSLAProcessLauncher initProcessLauncher{shell, {shell, "/etc/lsw-init.sh"}};
auto initProcess = initProcessLauncher.Launch(*session);
THROW_HR_IF(E_FAIL, initProcess.WaitAndCaptureOutput().Code != 0);
}
}
std::optional<wil::com_ptr<IWSLAContainer>> container;

View File

@ -143,7 +143,8 @@ static const std::map<HRESULT, LPCWSTR> g_commonErrors{
X_WIN32(ERROR_OPERATION_ABORTED),
X_WIN32(WSAECONNREFUSED),
X_WIN32(ERROR_BAD_PATHNAME),
X(WININET_E_TIMEOUT)};
X(WININET_E_TIMEOUT),
X_WIN32(ERROR_INVALID_SID)};
#undef X

View File

@ -44,6 +44,8 @@ void WSLAProcess::OnVmTerminated()
{
m_state = WslaProcessStateSignalled;
m_exitedCode = 9; // SIGKILL
m_exitEvent.SetEvent();
}
}

View File

@ -60,6 +60,11 @@ HRESULT WSLASession::GetDisplayName(LPWSTR* DisplayName)
return S_OK;
}
const std::wstring& WSLASession::DisplayName() const
{
return m_displayName;
}
HRESULT WSLASession::PullImage(LPCWSTR Image, const WSLA_REGISTRY_AUTHENTICATION_INFORMATION* RegistryInformation, IProgressCallback* ProgressCallback)
{
return E_NOTIMPL;

View File

@ -27,6 +27,7 @@ public:
~WSLASession();
IFACEMETHOD(GetDisplayName)(LPWSTR* DisplayName) override;
const std::wstring& DisplayName() const;
// Image management.
IFACEMETHOD(PullImage)(_In_ LPCWSTR Image, _In_ const WSLA_REGISTRY_AUTHENTICATION_INFORMATION* RegistryInformation, _In_ IProgressCallback* ProgressCallback) override;

View File

@ -47,8 +47,7 @@ PSID WSLAUserSessionImpl::GetUserSid() const
return m_tokenInfo->User.Sid;
}
HRESULT wsl::windows::service::wsla::WSLAUserSessionImpl::CreateSession(
const WSLA_SESSION_SETTINGS* Settings, const VIRTUAL_MACHINE_SETTINGS* VmSettings, IWSLASession** WslaSession)
HRESULT WSLAUserSessionImpl::CreateSession(const WSLA_SESSION_SETTINGS* Settings, const VIRTUAL_MACHINE_SETTINGS* VmSettings, IWSLASession** WslaSession)
{
auto session = wil::MakeOrThrow<WSLASession>(*Settings, *this, *VmSettings);
@ -63,6 +62,23 @@ HRESULT wsl::windows::service::wsla::WSLAUserSessionImpl::CreateSession(
return S_OK;
}
HRESULT WSLAUserSessionImpl::OpenSessionByName(LPCWSTR DisplayName, IWSLASession** Session)
{
std::lock_guard lock(m_wslaSessionsLock);
// TODO: Check for duplicate on session creation.
for (auto& e : m_sessions)
{
if (e->DisplayName() == DisplayName)
{
THROW_IF_FAILED(e->QueryInterface(__uuidof(IWSLASession), (void**)Session));
return S_OK;
}
}
return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
}
wsl::windows::service::wsla::WSLAUserSession::WSLAUserSession(std::weak_ptr<WSLAUserSessionImpl>&& Session) :
m_session(std::move(Session))
{
@ -92,7 +108,18 @@ HRESULT wsl::windows::service::wsla::WSLAUserSession::ListSessions(WSLA_SESSION_
{
return E_NOTIMPL;
}
HRESULT wsl::windows::service::wsla::WSLAUserSession::OpenSession(ULONG Id, IWSLASession** Session)
{
return E_NOTIMPL;
}
HRESULT wsl::windows::service::wsla::WSLAUserSession::OpenSessionByName(LPCWSTR DisplayName, IWSLASession** Session)
try
{
auto session = m_session.lock();
RETURN_HR_IF(RPC_E_DISCONNECTED, !session);
return session->OpenSessionByName(DisplayName, Session);
}
CATCH_RETURN();

View File

@ -30,6 +30,7 @@ public:
PSID GetUserSid() const;
HRESULT CreateSession(const WSLA_SESSION_SETTINGS* Settings, const VIRTUAL_MACHINE_SETTINGS* VmSettings, IWSLASession** WslaSession);
HRESULT OpenSessionByName(_In_ LPCWSTR DisplayName, _Out_ IWSLASession** Session);
void OnSessionTerminated(WSLASession* Session);
@ -55,6 +56,7 @@ public:
IFACEMETHOD(CreateSession)(const WSLA_SESSION_SETTINGS* WslaSessionSettings, const VIRTUAL_MACHINE_SETTINGS* VmSettings, IWSLASession** WslaSession) override;
IFACEMETHOD(ListSessions)(_Out_ WSLA_SESSION_INFORMATION** Sessions, _Out_ ULONG* SessionsCount) override;
IFACEMETHOD(OpenSession)(_In_ ULONG Id, _Out_ IWSLASession** Session) override;
IFACEMETHOD(OpenSessionByName)(_In_ LPCWSTR DisplayName, _Out_ IWSLASession** Session) override;
private:
std::weak_ptr<WSLAUserSessionImpl> m_session;

View File

@ -50,11 +50,15 @@ HRESULT WSLAUserSessionFactory::CreateInstance(_In_ IUnknown* pUnkOuter, _In_ RE
THROW_HR_IF(CO_E_SERVER_STOPPING, !g_sessions.has_value());
auto session = std::find_if(g_sessions->begin(), g_sessions->end(), [&tokenInfo](auto it) {
return EqualSid(it->GetUserSid(), &tokenInfo->User.Sid);
return EqualSid(it->GetUserSid(), tokenInfo->User.Sid);
});
if (session == g_sessions->end())
{
wil::unique_hlocal_string sid;
THROW_IF_WIN32_BOOL_FALSE(ConvertSidToStringSid(tokenInfo->User.Sid, &sid));
WSL_LOG("WSLAUserSession created", TraceLoggingValue(sid.get(), "sid"));
session = g_sessions->insert(g_sessions->end(), std::make_shared<WSLAUserSessionImpl>(userToken.get(), std::move(tokenInfo)));
}

View File

@ -319,6 +319,7 @@ interface IWSLAUserSession : IUnknown
HRESULT CreateSession([in] const struct WSLA_SESSION_SETTINGS* Settings, [in] const VIRTUAL_MACHINE_SETTINGS* VmSettings, [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);
// TODO: Do we need 'TerminateSession()' ?
}

View File

@ -1167,7 +1167,7 @@ class WSLATests
// TODO: Remove once the proper rootfs VHD is available.
ExpectCommandResult(session.get(), {"/etc/lsw-init.sh"}, 0);
// Test a simple container start.
/*// Test a simple container start.
{
WSLAContainerLauncher launcher("debian:latest", "test-simple", "echo", {"OK"});
auto container = launcher.Launch(*session);
@ -1178,16 +1178,15 @@ class WSLATests
// Validate that env is correctly wired.
{
WSLAContainerLauncher launcher("debian:latest", "test-env", "/bin/bash", {"-c", "echo $testenv"}, {{"testenv=testvalue"}});
auto container = launcher.Launch(*session);
auto process = container.GetInitProcess();
WSLAContainerLauncher launcher("debian:latest", "test-env", "/bin/bash", {"-c", "echo $testenv"},
{{"testenv=testvalue"}}); auto container = launcher.Launch(*session); auto process = container.GetInitProcess();
ValidateProcessOutput(process, {{1, "testvalue\n"}});
}
}*/
// Validate that starting containers work with the default entrypoint.
// TODO: This is hanging. Need wsladbg to see why cat seems to be stuck.
// TODO: This is hanging. nerdctl run seems to hang with -i is passed outside of a TTY context.
/*
{
WSLAContainerLauncher launcher(