mirror of
https://github.com/SerenityOS/serenity
synced 2026-05-08 16:12:23 +02:00
Instead of creating a new resource that has its own ID number and work with it directly, we can create a file that describes the unshared resource, execute ioctl calls on it and only enter into it in the end, essentially creating the resource only during the last call instead of the previous method of creation of a resource when "attaching" to that resource. We can enter a resource for current program execution, after the exec syscall, or both. That change allows userspace to create a resource and attach to it only in the new program, which makes it more comfortable to do cleanups or track the new process, outside of the created container. It should be noted that until this commit, we entered a resource without detaching the old one, essentially leaking the attach counter of a resource. While this bug didn't have severe effects, it was obvious that a proper cleanup userspace code later on wouldn't work in that situation anyway, so this commit changes the way we work, and the terminology of entering a resource is actually to **replace** it. These changes essentially open an opportunity to extend runc to be a container manager rather being launcher of a containerized environment, which makes it possible to do all sorts of nice cleanups and tracking of containers' states.
78 lines
2.7 KiB
C++
78 lines
2.7 KiB
C++
/*
|
|
* Copyright (c) 2026, Liav A. <liavalb@hotmail.co.il>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <AK/StdLibExtras.h>
|
|
#include <AK/StringView.h>
|
|
#include <Kernel/API/Ioctl.h>
|
|
#include <Kernel/API/POSIX/errno.h>
|
|
#include <Kernel/API/Syscall.h>
|
|
#include <Kernel/FileSystem/OpenFileDescription.h>
|
|
#include <Kernel/FileSystem/UnsharedResourceFile.h>
|
|
#include <Kernel/FileSystem/VirtualFileSystem.h>
|
|
#include <Kernel/Library/StdLib.h>
|
|
#include <Kernel/Tasks/Process.h>
|
|
|
|
#include <Kernel/FileSystem/VFSRootContext.h>
|
|
#include <Kernel/Tasks/HostnameContext.h>
|
|
#include <Kernel/Tasks/ScopedProcessList.h>
|
|
|
|
namespace Kernel {
|
|
|
|
ErrorOr<NonnullRefPtr<UnsharedResourceFile>> UnsharedResourceFile::create(UnshareType type)
|
|
{
|
|
return TRY(adopt_nonnull_ref_or_enomem(new (nothrow) UnsharedResourceFile(type)));
|
|
}
|
|
|
|
UnsharedResourceFile::UnsharedResourceFile(UnshareType type)
|
|
: m_type(type)
|
|
{
|
|
}
|
|
|
|
ErrorOr<unsigned> UnsharedResourceFile::initialize_resource()
|
|
{
|
|
switch (m_type) {
|
|
case UnshareType::ScopedProcessList: {
|
|
auto scoped_process_list = TRY(ScopedProcessList::create());
|
|
return scoped_process_list->id().value();
|
|
}
|
|
case UnshareType::VFSRootContext: {
|
|
auto vfs_root_context = TRY(VFSRootContext::create_with_empty_ramfs(VFSRootContext::AddToGlobalContextList::Yes));
|
|
return vfs_root_context->id().value();
|
|
}
|
|
case UnshareType::HostnameContext: {
|
|
// NOTE: Technically, we create a new context, based on the
|
|
// contents of "previous" attached one.
|
|
// However, the process can change the hostname context during
|
|
// this call as we don't really hold a lock on it, but that's
|
|
// really a non-issue because it's not destructive or really harmful
|
|
// and if a process is so **eager** to blindly change hostname contexts
|
|
// with multiple fds, we should not be the ones to stop it from doing that.
|
|
auto current_context = Process::current().hostname_context();
|
|
FixedStringBuffer<UTSNAME_ENTRY_LEN - 1> hostname;
|
|
current_context->buffer().with([&hostname](auto& buffer) {
|
|
hostname.store_characters(buffer.representable_view());
|
|
});
|
|
auto hostname_context = TRY(HostnameContext::create_with_name(hostname.representable_view()));
|
|
return hostname_context->id().value();
|
|
}
|
|
}
|
|
return ENOTSUP;
|
|
}
|
|
|
|
UnsharedResourceFile::~UnsharedResourceFile() = default;
|
|
|
|
ErrorOr<void> UnsharedResourceFile::ioctl(OpenFileDescription&, unsigned, Userspace<void*>)
|
|
{
|
|
return ENOTSUP;
|
|
}
|
|
|
|
ErrorOr<NonnullOwnPtr<KString>> UnsharedResourceFile::pseudo_path(OpenFileDescription const&) const
|
|
{
|
|
return KString::try_create(":unshared-resource-file:"sv);
|
|
}
|
|
|
|
}
|