mirror of
https://github.com/microsoft/WSL.git
synced 2025-12-10 17:47:59 -06:00
Save state
This commit is contained in:
parent
c69c83b0ab
commit
c826c20c8d
@ -2,7 +2,7 @@ set(SOURCES
|
|||||||
application.manifest
|
application.manifest
|
||||||
main.rc
|
main.rc
|
||||||
ServiceMain.cpp
|
ServiceMain.cpp
|
||||||
ServiceProcessLauncher.h
|
ServiceProcessLauncher.cpp
|
||||||
WSLAContainer.cpp
|
WSLAContainer.cpp
|
||||||
WSLAProcess.cpp
|
WSLAProcess.cpp
|
||||||
WSLASession.cpp
|
WSLASession.cpp
|
||||||
@ -12,7 +12,8 @@ set(SOURCES
|
|||||||
)
|
)
|
||||||
|
|
||||||
set(HEADERS
|
set(HEADERS
|
||||||
ServiceProcessLauncher.cpp
|
ServiceProcessLauncher.h
|
||||||
|
WeakRefContainer.h
|
||||||
WSLAContainer.h
|
WSLAContainer.h
|
||||||
WSLAProcess.h
|
WSLAProcess.h
|
||||||
WSLASession.h
|
WSLASession.h
|
||||||
|
|||||||
@ -16,15 +16,37 @@ Abstract:
|
|||||||
#include "WSLAContainer.h"
|
#include "WSLAContainer.h"
|
||||||
#include "WSLAProcess.h"
|
#include "WSLAProcess.h"
|
||||||
|
|
||||||
|
using wsl::windows::service::wsla::WeakReference;
|
||||||
using wsl::windows::service::wsla::WSLAContainer;
|
using wsl::windows::service::wsla::WSLAContainer;
|
||||||
|
|
||||||
constexpr const char* nerdctlPath = "/usr/bin/nerdctl";
|
constexpr const char* nerdctlPath = "/usr/bin/nerdctl";
|
||||||
|
|
||||||
// Constants for required default arguments for "nerdctl run..."
|
// Constants for required default arguments for "nerdctl run..."
|
||||||
static std::vector<std::string> defaultNerdctlRunArgs{//"--pull=never", // TODO: Uncomment once PullImage() is implemented.
|
static std::vector<std::string> defaultNerdctlRunArgs{
|
||||||
"--net=host", // TODO: default for now, change later
|
//"--pull=never", // TODO: Uncomment once PullImage() is implemented.
|
||||||
"--ulimit",
|
"--net=host", // TODO: default for now, change later
|
||||||
"nofile=65536:65536"};
|
"--ulimit",
|
||||||
|
"nofile=65536:65536"};
|
||||||
|
|
||||||
|
WSLAContainer::WSLAContainer(WSLAVirtualMachine* parentVM, ServiceRunningProcess&& containerProcess, const char* name, const char* image) :
|
||||||
|
WeakReference<WSLAContainer>(), m_parentVM(parentVM), m_containerProcess(std::move(containerProcess)), m_name(name), m_image(image)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
WSLAContainer::~WSLAContainer()
|
||||||
|
{
|
||||||
|
OnDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WSLAContainer::GetName(char Name[WSLA_MAX_CONTAINER_NAME_LENGTH + 1]) const noexcept
|
||||||
|
{
|
||||||
|
WI_VERIFY(strcpy_s(Name, sizeof(Name), m_name.c_str()) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WSLAContainer::GetImage(char Image[WSLA_MAX_IMAGE_NAME_LENGTH + 1]) const noexcept
|
||||||
|
{
|
||||||
|
WI_VERIFY(strcpy_s(Image, WSLA_MAX_IMAGE_NAME_LENGTH + 1, m_image.c_str()) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT WSLAContainer::Start()
|
HRESULT WSLAContainer::Start()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -24,13 +24,10 @@ class DECLSPEC_UUID("B1F1C4E3-C225-4CAE-AD8A-34C004DE1AE4") WSLAContainer
|
|||||||
: public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, IWSLAContainer, IFastRundown>
|
: public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, IWSLAContainer, IFastRundown>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WSLAContainer() = default; // TODO
|
WSLAContainer(WSLAVirtualMachine* parentVM, ServiceRunningProcess&& containerProcess, const char* name, const char* image);
|
||||||
WSLAContainer(WSLAVirtualMachine* parentVM, ServiceRunningProcess&& containerProcess) :
|
~WSLAContainer();
|
||||||
m_parentVM(parentVM), m_containerProcess(std::move(containerProcess))
|
|
||||||
{
|
NON_COPYABLE(WSLAContainer);
|
||||||
}
|
|
||||||
WSLAContainer(const WSLAContainer&) = delete;
|
|
||||||
WSLAContainer& operator=(const WSLAContainer&) = delete;
|
|
||||||
|
|
||||||
IFACEMETHOD(Start)() override;
|
IFACEMETHOD(Start)() override;
|
||||||
IFACEMETHOD(Stop)(_In_ int Signal, _In_ ULONG TimeoutMs) override;
|
IFACEMETHOD(Stop)(_In_ int Signal, _In_ ULONG TimeoutMs) override;
|
||||||
@ -39,10 +36,15 @@ public:
|
|||||||
IFACEMETHOD(GetInitProcess)(_Out_ IWSLAProcess** process) override;
|
IFACEMETHOD(GetInitProcess)(_Out_ IWSLAProcess** process) override;
|
||||||
IFACEMETHOD(Exec)(_In_ const WSLA_PROCESS_OPTIONS* Options, _Out_ IWSLAProcess** Process, _Out_ int* Errno) override;
|
IFACEMETHOD(Exec)(_In_ const WSLA_PROCESS_OPTIONS* Options, _Out_ IWSLAProcess** Process, _Out_ int* Errno) override;
|
||||||
|
|
||||||
|
void GetName(char Name[WSLA_MAX_IMAGE_NAME_LENGTH + 1]) const noexcept;
|
||||||
|
void GetImage(char Name[WSLA_MAX_CONTAINER_NAME_LENGTH + 1]) const noexcept;
|
||||||
|
|
||||||
static Microsoft::WRL::ComPtr<WSLAContainer> Create(const WSLA_CONTAINER_OPTIONS& Options, WSLAVirtualMachine& parentVM);
|
static Microsoft::WRL::ComPtr<WSLAContainer> Create(const WSLA_CONTAINER_OPTIONS& Options, WSLAVirtualMachine& parentVM);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ServiceRunningProcess m_containerProcess;
|
ServiceRunningProcess m_containerProcess;
|
||||||
|
std::string m_name;
|
||||||
|
std::string m_image;
|
||||||
WSLAVirtualMachine* m_parentVM = nullptr;
|
WSLAVirtualMachine* m_parentVM = nullptr;
|
||||||
|
|
||||||
static std::vector<std::string> PrepareNerdctlRunCommand(const WSLA_CONTAINER_OPTIONS& options, std::vector<std::string>&& inputOptions);
|
static std::vector<std::string> PrepareNerdctlRunCommand(const WSLA_CONTAINER_OPTIONS& options, std::vector<std::string>&& inputOptions);
|
||||||
|
|||||||
@ -220,8 +220,14 @@ try
|
|||||||
std::lock_guard lock{m_lock};
|
std::lock_guard lock{m_lock};
|
||||||
THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), !m_virtualMachine);
|
THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), !m_virtualMachine);
|
||||||
|
|
||||||
|
THROW_HR_IF(E_INVALIDARG, strlen(containerOptions->Name) > WSLA_MAX_CONTAINER_NAME_LENGTH);
|
||||||
|
THROW_HR_IF(E_INVALIDARG, strlen(containerOptions->Image) > WSLA_MAX_IMAGE_NAME_LENGTH);
|
||||||
|
|
||||||
// TODO: Log entrance into the function.
|
// TODO: Log entrance into the function.
|
||||||
auto container = WSLAContainer::Create(*containerOptions, *m_virtualMachine.Get());
|
auto container = WSLAContainer::Create(*containerOptions, *m_virtualMachine.Get());
|
||||||
|
|
||||||
|
m_containers.Add(container.Get());
|
||||||
|
|
||||||
THROW_IF_FAILED(container.CopyTo(__uuidof(IWSLAContainer), (void**)Container));
|
THROW_IF_FAILED(container.CopyTo(__uuidof(IWSLAContainer), (void**)Container));
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
@ -235,7 +241,16 @@ HRESULT WSLASession::OpenContainer(LPCWSTR Name, IWSLAContainer** Container)
|
|||||||
|
|
||||||
HRESULT WSLASession::ListContainers(WSLA_CONTAINER** Images, ULONG* Count)
|
HRESULT WSLASession::ListContainers(WSLA_CONTAINER** Images, ULONG* Count)
|
||||||
{
|
{
|
||||||
return E_NOTIMPL;
|
auto lockedElements = m_containers.Get();
|
||||||
|
|
||||||
|
auto output = wil::make_unique_cotaskmem<WSLA_CONTAINER[]>(lockedElements.elements.size());
|
||||||
|
size_t index = 0;
|
||||||
|
for (const auto &e: lockedElements.elements)
|
||||||
|
{
|
||||||
|
e->GetImage(output[index].Image);
|
||||||
|
e->GetName(output[index].Name);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT WSLASession::GetVirtualMachine(IWSLAVirtualMachine** VirtualMachine)
|
HRESULT WSLASession::GetVirtualMachine(IWSLAVirtualMachine** VirtualMachine)
|
||||||
|
|||||||
@ -16,6 +16,8 @@ Abstract:
|
|||||||
|
|
||||||
#include "wslaservice.h"
|
#include "wslaservice.h"
|
||||||
#include "WSLAVirtualMachine.h"
|
#include "WSLAVirtualMachine.h"
|
||||||
|
#include "WeakRefContainer.h"
|
||||||
|
#include "WSLAContainer.h"
|
||||||
|
|
||||||
namespace wsl::windows::service::wsla {
|
namespace wsl::windows::service::wsla {
|
||||||
|
|
||||||
@ -62,6 +64,7 @@ private:
|
|||||||
Microsoft::WRL::ComPtr<WSLAVirtualMachine> m_virtualMachine;
|
Microsoft::WRL::ComPtr<WSLAVirtualMachine> m_virtualMachine;
|
||||||
std::wstring m_displayName;
|
std::wstring m_displayName;
|
||||||
std::filesystem::path m_storageVhdPath;
|
std::filesystem::path m_storageVhdPath;
|
||||||
|
WeakRefContainer<WSLAContainer> m_containers;
|
||||||
std::mutex m_lock;
|
std::mutex m_lock;
|
||||||
|
|
||||||
// TODO: Add container tracking here. Could reuse m_lock for that.
|
// TODO: Add container tracking here. Could reuse m_lock for that.
|
||||||
|
|||||||
93
src/windows/wslaservice/exe/WeakRefContainer.h
Normal file
93
src/windows/wslaservice/exe/WeakRefContainer.h
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <wil/com.h>
|
||||||
|
#include <wil/cppwinrt.h>
|
||||||
|
|
||||||
|
namespace wsl::windows::service::wsla {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class WeakRefContainer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct LockedElements
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock;
|
||||||
|
std::unordered_set<T*>& elements;
|
||||||
|
};
|
||||||
|
|
||||||
|
WeakRefContainer(const WeakRefContainer&) = delete;
|
||||||
|
WeakRefContainer(WeakRefContainer&&) = delete;
|
||||||
|
|
||||||
|
WeakRefContainer& operator=(const WeakRefContainer&);
|
||||||
|
WeakRefContainer& operator=(WeakRefContainer&&);
|
||||||
|
|
||||||
|
WeakRefContainer() = default;
|
||||||
|
~WeakRefContainer()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> guard(m_lock);
|
||||||
|
|
||||||
|
for (const auto& e : m_elements)
|
||||||
|
{
|
||||||
|
e->SetContainer(nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Add(T* element)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> guard(m_lock);
|
||||||
|
|
||||||
|
element->SetContainer(this);
|
||||||
|
m_elements.insert(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Remove(T* element)
|
||||||
|
{
|
||||||
|
element->SetContainer(nullptr);
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> guard(m_lock);
|
||||||
|
m_elements.erase(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
LockedElements Get()
|
||||||
|
{
|
||||||
|
return {std::lock_guard<std::mutex>(m_lock), m_elements};
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unordered_set<T*> m_elements;
|
||||||
|
std::mutex m_lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class WeakReference
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NON_COPYABLE(WeakReference);
|
||||||
|
WeakReference() = default;
|
||||||
|
|
||||||
|
void SetContainer(WeakRefContainer<T>* container) noexcept
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> guard(m_lock);
|
||||||
|
m_container = container;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
WeakRefContainer<T>* m_container = nullptr;
|
||||||
|
|
||||||
|
void OnDestroy()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> guard(m_lock);
|
||||||
|
if (m_container != nullptr)
|
||||||
|
{
|
||||||
|
m_container->Remove(static_cast<T*>(this));
|
||||||
|
m_container = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::mutex m_lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace wsl::windows::service::wsla
|
||||||
@ -20,6 +20,12 @@ cpp_quote("#ifdef __cplusplus")
|
|||||||
cpp_quote("class DECLSPEC_UUID(\"a9b7a1b9-0671-405c-95f1-e0612cb4ce8f\") WSLAUserSession;")
|
cpp_quote("class DECLSPEC_UUID(\"a9b7a1b9-0671-405c-95f1-e0612cb4ce8f\") WSLAUserSession;")
|
||||||
cpp_quote("#endif")
|
cpp_quote("#endif")
|
||||||
|
|
||||||
|
#define WSLA_MAX_CONTAINER_NAME_LENGTH 255
|
||||||
|
#define WSLA_MAX_IMAGE_NAME_LENGTH 255
|
||||||
|
|
||||||
|
cpp_quote("#define WSLA_MAX_CONTAINER_NAME_LENGTH 255")
|
||||||
|
cpp_quote("#define WSLA_MAX_IMAGE_NAME_LENGTH 255")
|
||||||
|
|
||||||
typedef
|
typedef
|
||||||
struct _WSLA_VERSION {
|
struct _WSLA_VERSION {
|
||||||
ULONG Major;
|
ULONG Major;
|
||||||
@ -96,7 +102,7 @@ struct WSLA_REGISTRY_AUTHENTICATION_INFORMATION
|
|||||||
|
|
||||||
struct WSLA_IMAGE_INFORMATION
|
struct WSLA_IMAGE_INFORMATION
|
||||||
{
|
{
|
||||||
LPWSTR Name;
|
char Image[WSLA_MAX_IMAGE_NAME_LENGTH + 1];
|
||||||
LPWSTR Hash;
|
LPWSTR Hash;
|
||||||
ULONGLONG Size;
|
ULONGLONG Size;
|
||||||
ULONGLONG DownloadTimestamp;
|
ULONGLONG DownloadTimestamp;
|
||||||
@ -162,8 +168,8 @@ enum WSLA_CONTAINER_STATE
|
|||||||
|
|
||||||
struct WSLA_CONTAINER
|
struct WSLA_CONTAINER
|
||||||
{
|
{
|
||||||
LPWSTR Name;
|
char Name[WSLA_MAX_CONTAINER_NAME_LENGTH + 1];
|
||||||
LPWSTR Image;
|
char Image[WSLA_MAX_IMAGE_NAME_LENGTH + 1];
|
||||||
enum WSLA_CONTAINER_STATE State;
|
enum WSLA_CONTAINER_STATE State;
|
||||||
|
|
||||||
// TODO: Add creation timestamp and other fields that the command line tool might want to display.
|
// TODO: Add creation timestamp and other fields that the command line tool might want to display.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user