Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,26 @@ FetchContent_Declare(nlohmannjson
FetchContent_MakeAvailable(nlohmannjson)
FetchContent_GetProperties(nlohmannjson SOURCE_DIR NLOHMAN_JSON_SOURCE_DIR)

set(BOOST_VERSION "1.90.0")
set(BOOST_TARBALL "boost_${BOOST_VERSION}")
string(REPLACE "." "_" BOOST_TARBALL "${BOOST_TARBALL}")

FetchContent_Declare(
boost_headers
URL https://archives.boost.io/release/${BOOST_VERSION}/source/${BOOST_TARBALL}.tar.gz
# URL_HASH SHA256=TODO
)

# Download & unpack to boost_headers_SOURCE_DIR (no add_subdirectory!)
FetchContent_GetProperties(boost_headers)
if(NOT boost_headers_POPULATED)
FetchContent_Populate(boost_headers)
endif()

# Path where Boost headers reside (root has 'boost/' folder)
include_directories(${boost_headers_SOURCE_DIR})


# Import modules
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
find_package(IDL REQUIRED)
Expand Down
6 changes: 6 additions & 0 deletions msipackage/package.wix.in
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,12 @@
<RegistryValue Value="WSLAProcess" Type="string" />
</RegistryKey>

<!-- WSLAContainerProcess -->
<RegistryKey Root="HKCR" Key="CLSID\{3A5DB29D-6D1D-4619-B89D-578EB34C8E52}">
<RegistryValue Name="AppId" Value="{E9B79997-57E3-4201-AECC-6A464E530DD2}" Type="string" />
<RegistryValue Value="WSLAContainerProcess" Type="string" />
</RegistryKey>

<!-- WSLAUserSession -->
<RegistryKey Root="HKCR" Key="CLSID\{a9b7a1b9-0671-405c-95f1-e0612cb4ce8f}">
<RegistryValue Name="AppId" Value="{E9B79997-57E3-4201-AECC-6A464E530DD2}" Type="string" />
Expand Down
2 changes: 1 addition & 1 deletion nuget.config
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
</packageRestore>
<packageSources>
<clear />
<add key="WSL" value="https://pkgs.dev.azure.com/shine-oss/wsl/_packaging/WslDependencies/nuget/v3/index.json" />
<add key="WSL" value="C:\\Users\\piboulay\\repos\\Wsl-deps\\wsla-rootfs" />
</packageSources>
<disabledPackageSources>
<!-- Override any User and Computer NuGet package settings to guarantee
Expand Down
2 changes: 1 addition & 1 deletion packages.config
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<package id="Microsoft.WSL.LinuxSdk" version="1.20.0" targetFramework="native" />
<package id="Microsoft.WSL.TestData" version="0.1.0" />
<package id="Microsoft.WSL.TestDistro" version="2.5.7-47" />
<package id="Microsoft.WSL.WslaRootfs" version="0.1.2" />
<package id="Microsoft.WSL.WslaRootfs" version="0.1.3" />
<package id="Microsoft.WSLg" version="1.0.71" />
<package id="Microsoft.Xaml.Behaviors.WinUI.Managed" version="3.0.0" />
<package id="StrawberryPerl" version="5.32.1.1" />
Expand Down
103 changes: 102 additions & 1 deletion src/linux/init/WSLAInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,107 @@ void HandleMessageImpl(wsl::shared::SocketChannel& Channel, const WSLA_OPEN& Mes
result = 0;
}

void HandleMessageImpl(wsl::shared::SocketChannel& Channel, const WSLA_UNIX_CONNECT& Message, const gsl::span<gsl::byte>& Buffer)
{
// Make sure to close the channel since no more messages can be processed after this.
auto closeChannel = wil::scope_exit([&]() { Channel.Close(); });

int result = -1;

auto sendResult = wil::scope_exit([&]() { Channel.SendResultMessage(result); });

wil::unique_fd socket;

const auto* path = wsl::shared::string::FromSpan(Buffer, Message.PathOffset);
THROW_ERRNO_IF(EINVAL, path == nullptr);

try
{
socket = UtilConnectUnix(path);
result = 0;
}
catch (...)
{
result = wil::ResultFromCaughtException();
}

if (result != 0)
{
return;
}

sendResult.reset();

// Relay data between the two sockets.
pollfd pollDescriptors[2];
pollDescriptors[0].fd = socket.get();
pollDescriptors[0].events = POLLIN;
pollDescriptors[1].fd = Channel.Socket();
pollDescriptors[1].events = POLLIN;

std::vector<gsl::byte> relayBuffer;
while (true)
{
auto result = poll(pollDescriptors, COUNT_OF(pollDescriptors), -1);
THROW_LAST_ERROR_IF(result < 0);

if (pollDescriptors[0].revents & (POLLIN | POLLHUP | POLLERR))
{
auto bytesRead = UtilReadBuffer(pollDescriptors[0].fd, relayBuffer);
if (bytesRead < 0)
{
LOG_ERROR("read failed {}", errno);
break;
}
else if (bytesRead == 0)
{
// Unix socket has been closed.
pollDescriptors[0].fd = -1;
break;
}
else
{
auto bytesWritten = write(Channel.Socket(), relayBuffer.data(), bytesRead);
if (bytesWritten < 0)
{
LOG_ERROR("write failed {}", errno);
break;
}
}
}

if (pollDescriptors[1].revents & (POLLIN | POLLHUP | POLLERR))
{
auto bytesRead = UtilReadBuffer(pollDescriptors[1].fd, relayBuffer);
if (bytesRead < 0)
{
LOG_ERROR("read failed {}", errno);
break;
}
else if (bytesRead == 0)
{
// hvsocket has been closed.
pollDescriptors[1].fd = -1;

// Shutdown the write side of the socket. This is required so docker know when stdin is EOF for instance.
if (shutdown(socket.get(), SHUT_WR) < 0)
{
LOG_ERROR("shutdown({}, SHUT_WR) failed {}", socket.get(), errno);
}
}
else
{
auto bytesWritten = write(socket.get(), relayBuffer.data(), bytesRead);
if (bytesWritten < 0)
{
LOG_ERROR("write failed {}", errno);
break;
}
}
}
}
}

void HandleMessageImpl(wsl::shared::SocketChannel& Channel, const WSLA_TTY_RELAY& Message, const gsl::span<gsl::byte>&)
{
THROW_LAST_ERROR_IF(fcntl(Message.TtyMaster, F_SETFL, O_NONBLOCK) < 0);
Expand Down Expand Up @@ -766,7 +867,7 @@ void ProcessMessage(wsl::shared::SocketChannel& Channel, LX_MESSAGE_TYPE Type, c
{
try
{
HandleMessage<WSLA_GET_DISK, WSLA_MOUNT, WSLA_EXEC, WSLA_FORK, WSLA_CONNECT, WSLA_WAITPID, WSLA_SIGNAL, WSLA_TTY_RELAY, WSLA_PORT_RELAY, WSLA_OPEN, WSLA_UNMOUNT, WSLA_DETACH, WSLA_ACCEPT, WSLA_WATCH_PROCESSES>(
HandleMessage<WSLA_GET_DISK, WSLA_MOUNT, WSLA_EXEC, WSLA_FORK, WSLA_CONNECT, WSLA_WAITPID, WSLA_SIGNAL, WSLA_TTY_RELAY, WSLA_PORT_RELAY, WSLA_OPEN, WSLA_UNMOUNT, WSLA_DETACH, WSLA_ACCEPT, WSLA_WATCH_PROCESSES, WSLA_UNIX_CONNECT>(
Channel, Type, Buffer);
}
catch (...)
Expand Down
1 change: 1 addition & 0 deletions src/shared/inc/JsonUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ T FromJson(const char* Value)

#ifdef WIN32

WSL_LOG("InvalidJson", TraceLoggingValue(Value, "JsonValue"), TraceLoggingValue(e.what(), "Error"));
THROW_HR_WITH_USER_ERROR(WSL_E_INVALID_JSON, wsl::shared::Localization::MessageInvalidJson(e.what()));

#else
Expand Down
5 changes: 5 additions & 0 deletions src/shared/inc/SocketChannel.h
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,11 @@ class SocketChannel
return m_socket.get();
}

auto Release()
{
return std::move(m_socket);
}

bool Connected() const
{
return m_socket.get() >= 0;
Expand Down
18 changes: 17 additions & 1 deletion src/shared/inc/lxinitshared.h
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,8 @@ typedef enum _LX_MESSAGE_TYPE
LxMessageWSLADetach,
LxMessageWSLATerminalChanged,
LxMessageWSLAWatchProcesses,
LxMessageWSLAProcessExited
LxMessageWSLAProcessExited,
LxMessageWSLAUnixConnect,
} LX_MESSAGE_TYPE,
*PLX_MESSAGE_TYPE;

Expand Down Expand Up @@ -509,6 +510,7 @@ inline auto ToString(LX_MESSAGE_TYPE messageType)
X(LxMessageWSLATerminalChanged)
X(LxMessageWSLAWatchProcesses)
X(LxMessageWSLAProcessExited)
X(LxMessageWSLAUnixConnect)

default:
return "<unexpected LX_MESSAGE_TYPE>";
Expand Down Expand Up @@ -1881,6 +1883,20 @@ struct WSLA_PROCESS_EXITED
PRETTY_PRINT(FIELD(Header), FIELD(Pid), FIELD(Code), FIELD(Signaled));
};

struct WSLA_UNIX_CONNECT
{
static inline auto Type = LxMessageWSLAUnixConnect;
using TResponse = RESULT_MESSAGE<int32_t>;

DECLARE_MESSAGE_CTOR(WSLA_UNIX_CONNECT);

MESSAGE_HEADER Header;
unsigned int PathOffset;
char Buffer[];

PRETTY_PRINT(FIELD(Header), STRING_FIELD(PathOffset));
};

typedef struct _LX_MINI_INIT_IMPORT_RESULT
{
static inline auto Type = LxMiniInitMessageImportResult;
Expand Down
1 change: 1 addition & 0 deletions src/windows/common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ set(SOURCES

set(HEADERS
../../../generated/Localization.h
../inc/docker_schema.h
../inc/lxssbusclient.h
../inc/lxssclient.h
../inc/LxssDynamicFunction.h
Expand Down
21 changes: 21 additions & 0 deletions src/windows/common/WSLAContainerLauncher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,19 @@ void wsl::windows::common::WSLAContainerLauncher::AddVolume(const std::wstring&
}

std::pair<HRESULT, std::optional<RunningWSLAContainer>> WSLAContainerLauncher::LaunchNoThrow(IWSLASession& Session)
{
auto [result, container] = CreateNoThrow(Session);
if (FAILED(result))
{
return std::make_pair(result, std::optional<RunningWSLAContainer>{});
}

result = container.value().Get().Start();

return std::make_pair(result, std::move(container));
}

std::pair<HRESULT, std::optional<RunningWSLAContainer>> WSLAContainerLauncher::CreateNoThrow(IWSLASession& Session)
{
WSLA_CONTAINER_OPTIONS options{};
options.Image = m_image.c_str();
Expand Down Expand Up @@ -114,4 +127,12 @@ RunningWSLAContainer WSLAContainerLauncher::Launch(IWSLASession& Session)
THROW_IF_FAILED(result);

return std::move(container.value());
}

wsl::windows::common::docker_schema::InspectContainer wsl::windows::common::RunningWSLAContainer::Inspect()
{
wil::unique_cotaskmem_ansistring output;
THROW_IF_FAILED(m_container->Inspect(&output));

return wsl::shared::FromJson<docker_schema::InspectContainer>(output.get());
}
4 changes: 4 additions & 0 deletions src/windows/common/WSLAContainerLauncher.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Module Name:

#pragma once
#include "WSLAProcessLauncher.h"
#include "docker_schema.h"

namespace wsl::windows::common {

Expand All @@ -28,6 +29,7 @@ class RunningWSLAContainer
WSLA_CONTAINER_STATE State();
ClientRunningWSLAProcess GetInitProcess();
void Reset();
docker_schema::InspectContainer Inspect();

private:
wil::com_ptr<IWSLAContainer> m_container;
Expand All @@ -52,6 +54,8 @@ class WSLAContainerLauncher : private WSLAProcessLauncher
void AddVolume(const std::wstring& HostPath, const std::string& ContainerPath, bool ReadOnly);
void AddPort(uint16_t WindowsPort, uint16_t ContainerPort, int Family);

std::pair<HRESULT, std::optional<RunningWSLAContainer>> CreateNoThrow(IWSLASession& Session);

RunningWSLAContainer Launch(IWSLASession& Session);
std::pair<HRESULT, std::optional<RunningWSLAContainer>> LaunchNoThrow(IWSLASession& Session);

Expand Down
Loading
Loading