Kernel: Introduce global variables and stats in /sys/kernel directory

The ProcFS is an utter mess currently, so let's start move things that
are not related to processes-info. To ensure it's done in a sane manner,
we start by duplicating all /proc/ global nodes to the /sys/kernel/
directory, then we will move Userland to use the new directory so the
old directory nodes can be removed from the /proc directory.
This commit is contained in:
Liav A 2022-10-14 20:51:51 +03:00 committed by Andrew Kaster
parent db2e1bfa02
commit a91589c09b
Notes: sideshowbarker 2024-07-17 07:25:39 +09:00
58 changed files with 2122 additions and 1 deletions

View file

@ -151,6 +151,33 @@ set(KERNEL_SOURCES
FileSystem/SysFS/Subsystems/Firmware/BIOS/Directory.cpp
FileSystem/SysFS/Subsystems/Firmware/Directory.cpp
FileSystem/SysFS/Subsystems/Firmware/PowerStateSwitch.cpp
FileSystem/SysFS/Subsystems/Kernel/CommandLine.cpp
FileSystem/SysFS/Subsystems/Kernel/Interrupts.cpp
FileSystem/SysFS/Subsystems/Kernel/Processes.cpp
FileSystem/SysFS/Subsystems/Kernel/CPUInfo.cpp
FileSystem/SysFS/Subsystems/Kernel/Keymap.cpp
FileSystem/SysFS/Subsystems/Kernel/Profile.cpp
FileSystem/SysFS/Subsystems/Kernel/Directory.cpp
FileSystem/SysFS/Subsystems/Kernel/LoadBase.cpp
FileSystem/SysFS/Subsystems/Kernel/SystemMode.cpp
FileSystem/SysFS/Subsystems/Kernel/DiskUsage.cpp
FileSystem/SysFS/Subsystems/Kernel/Log.cpp
FileSystem/SysFS/Subsystems/Kernel/SystemStatistics.cpp
FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.cpp
FileSystem/SysFS/Subsystems/Kernel/MemoryStatus.cpp
FileSystem/SysFS/Subsystems/Kernel/Uptime.cpp
FileSystem/SysFS/Subsystems/Kernel/Network/Adapters.cpp
FileSystem/SysFS/Subsystems/Kernel/Network/ARP.cpp
FileSystem/SysFS/Subsystems/Kernel/Network/Directory.cpp
FileSystem/SysFS/Subsystems/Kernel/Network/Local.cpp
FileSystem/SysFS/Subsystems/Kernel/Network/Route.cpp
FileSystem/SysFS/Subsystems/Kernel/Network/TCP.cpp
FileSystem/SysFS/Subsystems/Kernel/Network/UDP.cpp
FileSystem/SysFS/Subsystems/Kernel/Variables/BooleanVariable.cpp
FileSystem/SysFS/Subsystems/Kernel/Variables/CapsLockRemap.cpp
FileSystem/SysFS/Subsystems/Kernel/Variables/Directory.cpp
FileSystem/SysFS/Subsystems/Kernel/Variables/DumpKmallocStack.cpp
FileSystem/SysFS/Subsystems/Kernel/Variables/UBSANDeadly.cpp
FileSystem/TmpFS.cpp
FileSystem/VirtualFileSystem.cpp
Firmware/BIOS.cpp

View file

@ -14,7 +14,9 @@
#include <Kernel/Sections.h>
#include <Kernel/kstdio.h>
static Kernel::Spinlock g_console_lock { LockRank::None };
namespace Kernel {
Spinlock g_console_lock { LockRank::None };
UNMAP_AFTER_INIT NonnullLockRefPtr<ConsoleDevice> ConsoleDevice::must_create()
{
@ -60,3 +62,5 @@ void ConsoleDevice::put_char(char ch)
dbgputchar(ch);
m_logbuffer.enqueue(ch);
}
}

View file

@ -12,6 +12,8 @@
namespace Kernel {
extern Spinlock g_console_lock;
class ConsoleDevice final : public CharacterDevice {
friend class DeviceManagement;

View file

@ -9,6 +9,7 @@
#include <Kernel/FileSystem/SysFS/Subsystems/Bus/Directory.h>
#include <Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/Directory.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Devices/Directory.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Directory.h>
#include <Kernel/Sections.h>
namespace Kernel {
@ -23,10 +24,12 @@ SysFSRootDirectory::SysFSRootDirectory()
auto buses_directory = SysFSBusDirectory::must_create(*this);
auto device_identifiers_directory = SysFSDeviceIdentifiersDirectory::must_create(*this);
auto devices_directory = SysFSDevicesDirectory::must_create(*this);
auto global_kernel_stats_directory = SysFSGlobalKernelStatsDirectory::must_create(*this);
MUST(m_child_components.with([&](auto& list) -> ErrorOr<void> {
list.append(buses_directory);
list.append(device_identifiers_directory);
list.append(devices_directory);
list.append(global_kernel_stats_directory);
return {};
}));
m_buses_directory = buses_directory;

View file

@ -0,0 +1,83 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/JsonObjectSerializer.h>
#include <Kernel/Arch/x86/ProcessorInfo.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/CPUInfo.h>
#include <Kernel/Sections.h>
namespace Kernel {
UNMAP_AFTER_INIT SysFSCPUInformation::SysFSCPUInformation(SysFSDirectory const& parent_directory)
: SysFSGlobalInformation(parent_directory)
{
}
UNMAP_AFTER_INIT NonnullLockRefPtr<SysFSCPUInformation> SysFSCPUInformation::must_create(SysFSDirectory const& parent_directory)
{
return adopt_lock_ref_if_nonnull(new (nothrow) SysFSCPUInformation(parent_directory)).release_nonnull();
}
ErrorOr<void> SysFSCPUInformation::try_generate(KBufferBuilder& builder)
{
auto array = TRY(JsonArraySerializer<>::try_create(builder));
TRY(Processor::try_for_each(
[&](Processor& proc) -> ErrorOr<void> {
auto& info = proc.info();
auto obj = TRY(array.add_object());
TRY(obj.add("processor"sv, proc.id()));
TRY(obj.add("vendor_id"sv, info.vendor_id_string()));
TRY(obj.add("family"sv, info.display_family()));
if (!info.hypervisor_vendor_id_string().is_null())
TRY(obj.add("hypervisor_vendor_id"sv, info.hypervisor_vendor_id_string()));
auto features_array = TRY(obj.add_array("features"sv));
auto keep_empty = SplitBehavior::KeepEmpty;
ErrorOr<void> result; // FIXME: Make this nicer
info.features_string().for_each_split_view(' ', keep_empty, [&](StringView feature) {
if (result.is_error())
return;
result = features_array.add(feature);
});
TRY(result);
TRY(features_array.finish());
TRY(obj.add("model"sv, info.display_model()));
TRY(obj.add("stepping"sv, info.stepping()));
TRY(obj.add("type"sv, info.type()));
TRY(obj.add("brand"sv, info.brand_string()));
auto caches = TRY(obj.add_object("caches"sv));
auto add_cache_info = [&](StringView name, ProcessorInfo::Cache const& cache) -> ErrorOr<void> {
auto cache_object = TRY(caches.add_object(name));
TRY(cache_object.add("size"sv, cache.size));
TRY(cache_object.add("line_size"sv, cache.line_size));
TRY(cache_object.finish());
return {};
};
if (info.l1_data_cache().has_value())
TRY(add_cache_info("l1_data"sv, *info.l1_data_cache()));
if (info.l1_instruction_cache().has_value())
TRY(add_cache_info("l1_instruction"sv, *info.l1_instruction_cache()));
if (info.l2_cache().has_value())
TRY(add_cache_info("l2"sv, *info.l2_cache()));
if (info.l3_cache().has_value())
TRY(add_cache_info("l3"sv, *info.l3_cache()));
TRY(caches.finish());
TRY(obj.finish());
return {};
}));
TRY(array.finish());
return {};
}
}

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.h>
#include <Kernel/KBufferBuilder.h>
#include <Kernel/Library/LockRefPtr.h>
#include <Kernel/UserOrKernelBuffer.h>
namespace Kernel {
class SysFSCPUInformation final : public SysFSGlobalInformation {
public:
virtual StringView name() const override { return "cpuinfo"sv; }
static NonnullLockRefPtr<SysFSCPUInformation> must_create(SysFSDirectory const& parent_directory);
private:
SysFSCPUInformation(SysFSDirectory const& parent_directory);
virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override;
};
}

View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <Kernel/CommandLine.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/CommandLine.h>
#include <Kernel/Sections.h>
namespace Kernel {
UNMAP_AFTER_INIT NonnullLockRefPtr<SysFSCommandLine> SysFSCommandLine::must_create(SysFSDirectory const& parent_directory)
{
return adopt_lock_ref_if_nonnull(new (nothrow) SysFSCommandLine(parent_directory)).release_nonnull();
}
UNMAP_AFTER_INIT SysFSCommandLine::SysFSCommandLine(SysFSDirectory const& parent_directory)
: SysFSGlobalInformation(parent_directory)
{
}
ErrorOr<void> SysFSCommandLine::try_generate(KBufferBuilder& builder)
{
TRY(builder.append(kernel_command_line().string()));
TRY(builder.append('\n'));
return {};
}
}

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.h>
#include <Kernel/KBufferBuilder.h>
#include <Kernel/Library/LockRefPtr.h>
#include <Kernel/UserOrKernelBuffer.h>
namespace Kernel {
class SysFSCommandLine final : public SysFSGlobalInformation {
public:
virtual StringView name() const override { return "cmdline"sv; }
static NonnullLockRefPtr<SysFSCommandLine> must_create(SysFSDirectory const& parent_directory);
private:
SysFSCommandLine(SysFSDirectory const& parent_directory);
virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override;
};
}

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Error.h>
#include <AK/Try.h>
#include <Kernel/FileSystem/SysFS/Component.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/CPUInfo.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/CommandLine.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Directory.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/DiskUsage.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Interrupts.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Keymap.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/LoadBase.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Log.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/MemoryStatus.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Directory.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Processes.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Profile.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/SystemMode.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/SystemStatistics.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Uptime.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/Directory.h>
namespace Kernel {
UNMAP_AFTER_INIT NonnullLockRefPtr<SysFSGlobalKernelStatsDirectory> SysFSGlobalKernelStatsDirectory::must_create(SysFSRootDirectory const& root_directory)
{
auto global_kernel_stats_directory = adopt_lock_ref_if_nonnull(new (nothrow) SysFSGlobalKernelStatsDirectory(root_directory)).release_nonnull();
MUST(global_kernel_stats_directory->m_child_components.with([&](auto& list) -> ErrorOr<void> {
list.append(SysFSDiskUsage::must_create(*global_kernel_stats_directory));
list.append(SysFSMemoryStatus::must_create(*global_kernel_stats_directory));
list.append(SysFSSystemStatistics::must_create(*global_kernel_stats_directory));
list.append(SysFSOverallProcesses::must_create(*global_kernel_stats_directory));
list.append(SysFSCPUInformation::must_create(*global_kernel_stats_directory));
list.append(SysFSKernelLog::must_create(*global_kernel_stats_directory));
list.append(SysFSInterrupts::must_create(*global_kernel_stats_directory));
list.append(SysFSKeymap::must_create(*global_kernel_stats_directory));
list.append(SysFSUptime::must_create(*global_kernel_stats_directory));
list.append(SysFSCommandLine::must_create(*global_kernel_stats_directory));
list.append(SysFSSystemMode::must_create(*global_kernel_stats_directory));
list.append(SysFSProfile::must_create(*global_kernel_stats_directory));
list.append(SysFSKernelLoadBase::must_create(*global_kernel_stats_directory));
list.append(SysFSGlobalNetworkStatsDirectory::must_create(*global_kernel_stats_directory));
list.append(SysFSGlobalKernelVariablesDirectory::must_create(*global_kernel_stats_directory));
return {};
}));
return global_kernel_stats_directory;
}
UNMAP_AFTER_INIT SysFSGlobalKernelStatsDirectory::SysFSGlobalKernelStatsDirectory(SysFSDirectory const& root_directory)
: SysFSDirectory(root_directory)
{
}
}

View file

@ -0,0 +1,24 @@
/*
* Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
#include <Kernel/FileSystem/SysFS/Component.h>
#include <Kernel/FileSystem/SysFS/RootDirectory.h>
namespace Kernel {
class SysFSGlobalKernelStatsDirectory : public SysFSDirectory {
public:
static NonnullLockRefPtr<SysFSGlobalKernelStatsDirectory> must_create(SysFSRootDirectory const&);
virtual StringView name() const override { return "kernel"sv; }
private:
explicit SysFSGlobalKernelStatsDirectory(SysFSDirectory const&);
};
}

View file

@ -0,0 +1,56 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/JsonObjectSerializer.h>
#include <Kernel/FileSystem/FileBackedFileSystem.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/DiskUsage.h>
#include <Kernel/FileSystem/VirtualFileSystem.h>
#include <Kernel/Sections.h>
namespace Kernel {
UNMAP_AFTER_INIT NonnullLockRefPtr<SysFSDiskUsage> SysFSDiskUsage::must_create(SysFSDirectory const& parent_directory)
{
return adopt_lock_ref_if_nonnull(new (nothrow) SysFSDiskUsage(parent_directory)).release_nonnull();
}
UNMAP_AFTER_INIT SysFSDiskUsage::SysFSDiskUsage(SysFSDirectory const& parent_directory)
: SysFSGlobalInformation(parent_directory)
{
}
ErrorOr<void> SysFSDiskUsage::try_generate(KBufferBuilder& builder)
{
auto array = TRY(JsonArraySerializer<>::try_create(builder));
TRY(VirtualFileSystem::the().for_each_mount([&array](auto& mount) -> ErrorOr<void> {
auto& fs = mount.guest_fs();
auto fs_object = TRY(array.add_object());
TRY(fs_object.add("class_name"sv, fs.class_name()));
TRY(fs_object.add("total_block_count"sv, fs.total_block_count()));
TRY(fs_object.add("free_block_count"sv, fs.free_block_count()));
TRY(fs_object.add("total_inode_count"sv, fs.total_inode_count()));
TRY(fs_object.add("free_inode_count"sv, fs.free_inode_count()));
auto mount_point = TRY(mount.absolute_path());
TRY(fs_object.add("mount_point"sv, mount_point->view()));
TRY(fs_object.add("block_size"sv, static_cast<u64>(fs.block_size())));
TRY(fs_object.add("readonly"sv, fs.is_readonly()));
TRY(fs_object.add("mount_flags"sv, mount.flags()));
if (fs.is_file_backed()) {
auto pseudo_path = TRY(static_cast<const FileBackedFileSystem&>(fs).file_description().pseudo_path());
TRY(fs_object.add("source"sv, pseudo_path->view()));
} else {
TRY(fs_object.add("source"sv, "none"));
}
TRY(fs_object.finish());
return {};
}));
TRY(array.finish());
return {};
}
}

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.h>
#include <Kernel/KBufferBuilder.h>
#include <Kernel/Library/LockRefPtr.h>
#include <Kernel/UserOrKernelBuffer.h>
namespace Kernel {
class SysFSDiskUsage final : public SysFSGlobalInformation {
public:
virtual StringView name() const override { return "df"sv; }
static NonnullLockRefPtr<SysFSDiskUsage> must_create(SysFSDirectory const& parent_directory);
private:
SysFSDiskUsage(SysFSDirectory const& parent_directory);
virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override;
};
}

View file

@ -0,0 +1,62 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.h>
namespace Kernel {
ErrorOr<size_t> SysFSGlobalInformation::read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, OpenFileDescription* description) const
{
dbgln_if(SYSFS_DEBUG, "SysFSGlobalInformation @ {}: read_bytes offset: {} count: {}", name(), offset, count);
VERIFY(offset >= 0);
VERIFY(buffer.user_or_kernel_ptr());
if (!description)
return Error::from_errno(EIO);
MutexLocker locker(m_refresh_lock);
if (!description->data()) {
dbgln("SysFSGlobalInformation: Do not have cached data!");
return Error::from_errno(EIO);
}
auto& typed_cached_data = static_cast<SysFSInodeData&>(*description->data());
auto& data_buffer = typed_cached_data.buffer;
if (!data_buffer || (size_t)offset >= data_buffer->size())
return 0;
ssize_t nread = min(static_cast<off_t>(data_buffer->size() - offset), static_cast<off_t>(count));
TRY(buffer.write(data_buffer->data() + offset, nread));
return nread;
}
SysFSGlobalInformation::SysFSGlobalInformation(SysFSDirectory const& parent_directory)
: SysFSComponent(parent_directory)
{
}
ErrorOr<void> SysFSGlobalInformation::refresh_data(OpenFileDescription& description) const
{
MutexLocker lock(m_refresh_lock);
auto& cached_data = description.data();
if (!cached_data) {
cached_data = adopt_own_if_nonnull(new (nothrow) SysFSInodeData);
if (!cached_data)
return ENOMEM;
}
auto builder = TRY(KBufferBuilder::try_create());
TRY(const_cast<SysFSGlobalInformation&>(*this).try_generate(builder));
auto& typed_cached_data = static_cast<SysFSInodeData&>(*cached_data);
typed_cached_data.buffer = builder.build();
if (!typed_cached_data.buffer)
return ENOMEM;
return {};
}
}

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Error.h>
#include <AK/Try.h>
#include <AK/Types.h>
#include <Kernel/FileSystem/FileSystem.h>
#include <Kernel/FileSystem/OpenFileDescription.h>
#include <Kernel/FileSystem/SysFS/Component.h>
#include <Kernel/KBufferBuilder.h>
#include <Kernel/Library/LockRefPtr.h>
#include <Kernel/Locking/Mutex.h>
#include <Kernel/UserOrKernelBuffer.h>
namespace Kernel {
class SysFSGlobalInformation : public SysFSComponent {
public:
virtual ErrorOr<size_t> read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, OpenFileDescription* description) const override;
protected:
explicit SysFSGlobalInformation(SysFSDirectory const& parent_directory);
virtual ErrorOr<void> refresh_data(OpenFileDescription&) const override;
virtual ErrorOr<void> try_generate(KBufferBuilder&) = 0;
mutable Mutex m_refresh_lock;
};
}

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/JsonObjectSerializer.h>
#include <Kernel/Arch/InterruptManagement.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Interrupts.h>
#include <Kernel/Sections.h>
namespace Kernel {
UNMAP_AFTER_INIT SysFSInterrupts::SysFSInterrupts(SysFSDirectory const& parent_directory)
: SysFSGlobalInformation(parent_directory)
{
}
UNMAP_AFTER_INIT NonnullLockRefPtr<SysFSInterrupts> SysFSInterrupts::must_create(SysFSDirectory const& parent_directory)
{
return adopt_lock_ref_if_nonnull(new (nothrow) SysFSInterrupts(parent_directory)).release_nonnull();
}
ErrorOr<void> SysFSInterrupts::try_generate(KBufferBuilder& builder)
{
auto array = TRY(JsonArraySerializer<>::try_create(builder));
ErrorOr<void> result; // FIXME: Make this nicer
InterruptManagement::the().enumerate_interrupt_handlers([&array, &result](GenericInterruptHandler& handler) {
if (result.is_error())
return;
result = ([&]() -> ErrorOr<void> {
auto obj = TRY(array.add_object());
TRY(obj.add("purpose"sv, handler.purpose()));
TRY(obj.add("interrupt_line"sv, handler.interrupt_number()));
TRY(obj.add("controller"sv, handler.controller()));
TRY(obj.add("cpu_handler"sv, 0)); // FIXME: Determine the responsible CPU for each interrupt handler.
TRY(obj.add("device_sharing"sv, (unsigned)handler.sharing_devices_count()));
TRY(obj.add("call_count"sv, (unsigned)handler.get_invoking_count()));
TRY(obj.finish());
return {};
})();
});
TRY(result);
TRY(array.finish());
return {};
}
}

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.h>
#include <Kernel/KBufferBuilder.h>
#include <Kernel/Library/LockRefPtr.h>
#include <Kernel/UserOrKernelBuffer.h>
namespace Kernel {
class SysFSInterrupts final : public SysFSGlobalInformation {
public:
virtual StringView name() const override { return "interrupts"sv; }
static NonnullLockRefPtr<SysFSInterrupts> must_create(SysFSDirectory const& parent_directory);
private:
explicit SysFSInterrupts(SysFSDirectory const& parent_directory);
virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override;
};
}

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/JsonObjectSerializer.h>
#include <Kernel/Devices/HID/HIDManagement.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Keymap.h>
#include <Kernel/Sections.h>
namespace Kernel {
UNMAP_AFTER_INIT SysFSKeymap::SysFSKeymap(SysFSDirectory const& parent_directory)
: SysFSGlobalInformation(parent_directory)
{
}
UNMAP_AFTER_INIT NonnullLockRefPtr<SysFSKeymap> SysFSKeymap::must_create(SysFSDirectory const& parent_directory)
{
return adopt_lock_ref_if_nonnull(new (nothrow) SysFSKeymap(parent_directory)).release_nonnull();
}
ErrorOr<void> SysFSKeymap::try_generate(KBufferBuilder& builder)
{
auto json = TRY(JsonObjectSerializer<>::try_create(builder));
TRY(HIDManagement::the().keymap_data().with([&](auto const& keymap_data) {
return json.add("keymap"sv, keymap_data.character_map_name->view());
}));
TRY(json.finish());
return {};
}
}

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.h>
#include <Kernel/KBufferBuilder.h>
#include <Kernel/Library/LockRefPtr.h>
#include <Kernel/UserOrKernelBuffer.h>
namespace Kernel {
class SysFSKeymap final : public SysFSGlobalInformation {
public:
virtual StringView name() const override { return "keymap"sv; }
static NonnullLockRefPtr<SysFSKeymap> must_create(SysFSDirectory const& parent_directory);
private:
explicit SysFSKeymap(SysFSDirectory const& parent_directory);
virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override;
};
}

View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/LoadBase.h>
#include <Kernel/Process.h>
#include <Kernel/Sections.h>
namespace Kernel {
UNMAP_AFTER_INIT SysFSKernelLoadBase::SysFSKernelLoadBase(SysFSDirectory const& parent_directory)
: SysFSGlobalInformation(parent_directory)
{
}
UNMAP_AFTER_INIT NonnullLockRefPtr<SysFSKernelLoadBase> SysFSKernelLoadBase::must_create(SysFSDirectory const& parent_directory)
{
return adopt_lock_ref_if_nonnull(new (nothrow) SysFSKernelLoadBase(parent_directory)).release_nonnull();
}
ErrorOr<void> SysFSKernelLoadBase::try_generate(KBufferBuilder& builder)
{
auto current_process_credentials = Process::current().credentials();
if (!current_process_credentials->is_superuser())
return EPERM;
return builder.appendff("{}", kernel_load_base);
}
mode_t SysFSKernelLoadBase::permissions() const
{
// Note: The kernel load address should not be exposed to non-root users
// as it will help defeat KASLR.
return S_IRUSR;
}
}

View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.h>
#include <Kernel/KBufferBuilder.h>
#include <Kernel/Library/LockRefPtr.h>
#include <Kernel/UserOrKernelBuffer.h>
namespace Kernel {
class SysFSKernelLoadBase final : public SysFSGlobalInformation {
public:
virtual StringView name() const override { return "load_base"sv; }
static NonnullLockRefPtr<SysFSKernelLoadBase> must_create(SysFSDirectory const& parent_directory);
private:
explicit SysFSKernelLoadBase(SysFSDirectory const& parent_directory);
virtual mode_t permissions() const override;
virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override;
};
}

View file

@ -0,0 +1,39 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <Kernel/Devices/ConsoleDevice.h>
#include <Kernel/Devices/DeviceManagement.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Log.h>
#include <Kernel/Sections.h>
namespace Kernel {
UNMAP_AFTER_INIT SysFSKernelLog::SysFSKernelLog(SysFSDirectory const& parent_directory)
: SysFSGlobalInformation(parent_directory)
{
}
UNMAP_AFTER_INIT NonnullLockRefPtr<SysFSKernelLog> SysFSKernelLog::must_create(SysFSDirectory const& parent_directory)
{
return adopt_lock_ref_if_nonnull(new (nothrow) SysFSKernelLog(parent_directory)).release_nonnull();
}
mode_t SysFSKernelLog::permissions() const
{
return S_IRUSR;
}
ErrorOr<void> SysFSKernelLog::try_generate(KBufferBuilder& builder)
{
VERIFY(DeviceManagement::the().is_console_device_attached());
SpinlockLocker lock(g_console_lock);
for (char ch : DeviceManagement::the().console_device().logbuffer()) {
TRY(builder.append(ch));
}
return {};
}
}

View file

@ -0,0 +1,29 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.h>
#include <Kernel/KBufferBuilder.h>
#include <Kernel/Library/LockRefPtr.h>
#include <Kernel/UserOrKernelBuffer.h>
namespace Kernel {
class SysFSKernelLog final : public SysFSGlobalInformation {
public:
virtual StringView name() const override { return "dmesg"sv; }
static NonnullLockRefPtr<SysFSKernelLog> must_create(SysFSDirectory const& parent_directory);
virtual mode_t permissions() const override;
private:
explicit SysFSKernelLog(SysFSDirectory const& parent_directory);
virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override;
};
}

View file

@ -0,0 +1,44 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/JsonObjectSerializer.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/MemoryStatus.h>
#include <Kernel/Memory/MemoryManager.h>
#include <Kernel/Sections.h>
namespace Kernel {
UNMAP_AFTER_INIT SysFSMemoryStatus::SysFSMemoryStatus(SysFSDirectory const& parent_directory)
: SysFSGlobalInformation(parent_directory)
{
}
UNMAP_AFTER_INIT NonnullLockRefPtr<SysFSMemoryStatus> SysFSMemoryStatus::must_create(SysFSDirectory const& parent_directory)
{
return adopt_lock_ref_if_nonnull(new (nothrow) SysFSMemoryStatus(parent_directory)).release_nonnull();
}
ErrorOr<void> SysFSMemoryStatus::try_generate(KBufferBuilder& builder)
{
kmalloc_stats stats;
get_kmalloc_stats(stats);
auto system_memory = MM.get_system_memory_info();
auto json = TRY(JsonObjectSerializer<>::try_create(builder));
TRY(json.add("kmalloc_allocated"sv, stats.bytes_allocated));
TRY(json.add("kmalloc_available"sv, stats.bytes_free));
TRY(json.add("physical_allocated"sv, system_memory.physical_pages_used));
TRY(json.add("physical_available"sv, system_memory.physical_pages - system_memory.physical_pages_used));
TRY(json.add("physical_committed"sv, system_memory.physical_pages_committed));
TRY(json.add("physical_uncommitted"sv, system_memory.physical_pages_uncommitted));
TRY(json.add("kmalloc_call_count"sv, stats.kmalloc_call_count));
TRY(json.add("kfree_call_count"sv, stats.kfree_call_count));
TRY(json.finish());
return {};
}
}

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.h>
#include <Kernel/KBufferBuilder.h>
#include <Kernel/Library/LockRefPtr.h>
#include <Kernel/UserOrKernelBuffer.h>
namespace Kernel {
class SysFSMemoryStatus final : public SysFSGlobalInformation {
public:
virtual StringView name() const override { return "memstat"sv; }
static NonnullLockRefPtr<SysFSMemoryStatus> must_create(SysFSDirectory const& parent_directory);
private:
explicit SysFSMemoryStatus(SysFSDirectory const& parent_directory);
virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override;
};
}

View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/JsonObjectSerializer.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/ARP.h>
#include <Kernel/Net/ARP.h>
#include <Kernel/Net/Routing.h>
#include <Kernel/Sections.h>
namespace Kernel {
UNMAP_AFTER_INIT SysFSNetworkARPStats::SysFSNetworkARPStats(SysFSDirectory const& parent_directory)
: SysFSGlobalInformation(parent_directory)
{
}
UNMAP_AFTER_INIT NonnullLockRefPtr<SysFSNetworkARPStats> SysFSNetworkARPStats::must_create(SysFSDirectory const& parent_directory)
{
return adopt_lock_ref_if_nonnull(new (nothrow) SysFSNetworkARPStats(parent_directory)).release_nonnull();
}
ErrorOr<void> SysFSNetworkARPStats::try_generate(KBufferBuilder& builder)
{
auto array = TRY(JsonArraySerializer<>::try_create(builder));
TRY(arp_table().with([&](auto const& table) -> ErrorOr<void> {
for (auto& it : table) {
auto obj = TRY(array.add_object());
auto mac_address = TRY(it.value.to_string());
TRY(obj.add("mac_address"sv, mac_address->view()));
auto ip_address = TRY(it.key.to_string());
TRY(obj.add("ip_address"sv, ip_address->view()));
TRY(obj.finish());
}
return {};
}));
TRY(array.finish());
return {};
}
}

View file

@ -0,0 +1,27 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.h>
#include <Kernel/KBufferBuilder.h>
#include <Kernel/Library/LockRefPtr.h>
#include <Kernel/UserOrKernelBuffer.h>
namespace Kernel {
class SysFSNetworkARPStats final : public SysFSGlobalInformation {
public:
virtual StringView name() const override { return "arp"sv; }
static NonnullLockRefPtr<SysFSNetworkARPStats> must_create(SysFSDirectory const&);
private:
explicit SysFSNetworkARPStats(SysFSDirectory const&);
virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override;
};
}

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/JsonObjectSerializer.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Adapters.h>
#include <Kernel/Net/NetworkingManagement.h>
#include <Kernel/Sections.h>
namespace Kernel {
UNMAP_AFTER_INIT SysFSNetworkAdaptersStats::SysFSNetworkAdaptersStats(SysFSDirectory const& parent_directory)
: SysFSGlobalInformation(parent_directory)
{
}
UNMAP_AFTER_INIT NonnullLockRefPtr<SysFSNetworkAdaptersStats> SysFSNetworkAdaptersStats::must_create(SysFSDirectory const& parent_directory)
{
return adopt_lock_ref_if_nonnull(new (nothrow) SysFSNetworkAdaptersStats(parent_directory)).release_nonnull();
}
ErrorOr<void> SysFSNetworkAdaptersStats::try_generate(KBufferBuilder& builder)
{
auto array = TRY(JsonArraySerializer<>::try_create(builder));
TRY(NetworkingManagement::the().try_for_each([&array](auto& adapter) -> ErrorOr<void> {
auto obj = TRY(array.add_object());
TRY(obj.add("name"sv, adapter.name()));
TRY(obj.add("class_name"sv, adapter.class_name()));
auto mac_address = TRY(adapter.mac_address().to_string());
TRY(obj.add("mac_address"sv, mac_address->view()));
if (!adapter.ipv4_address().is_zero()) {
auto ipv4_address = TRY(adapter.ipv4_address().to_string());
TRY(obj.add("ipv4_address"sv, ipv4_address->view()));
auto ipv4_netmask = TRY(adapter.ipv4_netmask().to_string());
TRY(obj.add("ipv4_netmask"sv, ipv4_netmask->view()));
}
TRY(obj.add("packets_in"sv, adapter.packets_in()));
TRY(obj.add("bytes_in"sv, adapter.bytes_in()));
TRY(obj.add("packets_out"sv, adapter.packets_out()));
TRY(obj.add("bytes_out"sv, adapter.bytes_out()));
TRY(obj.add("link_up"sv, adapter.link_up()));
TRY(obj.add("link_speed"sv, adapter.link_speed()));
TRY(obj.add("link_full_duplex"sv, adapter.link_full_duplex()));
TRY(obj.add("mtu"sv, adapter.mtu()));
TRY(obj.finish());
return {};
}));
TRY(array.finish());
return {};
}
}

View file

@ -0,0 +1,27 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.h>
#include <Kernel/KBufferBuilder.h>
#include <Kernel/Library/LockRefPtr.h>
#include <Kernel/UserOrKernelBuffer.h>
namespace Kernel {
class SysFSNetworkAdaptersStats final : public SysFSGlobalInformation {
public:
virtual StringView name() const override { return "adapters"sv; }
static NonnullLockRefPtr<SysFSNetworkAdaptersStats> must_create(SysFSDirectory const&);
private:
explicit SysFSNetworkAdaptersStats(SysFSDirectory const&);
virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override;
};
}

View file

@ -0,0 +1,40 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Error.h>
#include <AK/Try.h>
#include <Kernel/FileSystem/SysFS/Component.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/ARP.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Adapters.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Directory.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Local.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Route.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/TCP.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/UDP.h>
namespace Kernel {
UNMAP_AFTER_INIT NonnullLockRefPtr<SysFSGlobalNetworkStatsDirectory> SysFSGlobalNetworkStatsDirectory::must_create(SysFSDirectory const& parent_directory)
{
auto global_network_stats_directory = adopt_lock_ref_if_nonnull(new (nothrow) SysFSGlobalNetworkStatsDirectory(parent_directory)).release_nonnull();
MUST(global_network_stats_directory->m_child_components.with([&](auto& list) -> ErrorOr<void> {
list.append(SysFSNetworkAdaptersStats::must_create(*global_network_stats_directory));
list.append(SysFSNetworkARPStats::must_create(*global_network_stats_directory));
list.append(SysFSNetworkRouteStats::must_create(*global_network_stats_directory));
list.append(SysFSNetworkTCPStats::must_create(*global_network_stats_directory));
list.append(SysFSLocalNetStats::must_create(*global_network_stats_directory));
list.append(SysFSNetworkUDPStats::must_create(*global_network_stats_directory));
return {};
}));
return global_network_stats_directory;
}
UNMAP_AFTER_INIT SysFSGlobalNetworkStatsDirectory::SysFSGlobalNetworkStatsDirectory(SysFSDirectory const& parent_directory)
: SysFSDirectory(parent_directory)
{
}
}

View file

@ -0,0 +1,24 @@
/*
* Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
#include <Kernel/FileSystem/SysFS/Component.h>
#include <Kernel/FileSystem/SysFS/RootDirectory.h>
namespace Kernel {
class SysFSGlobalNetworkStatsDirectory : public SysFSDirectory {
public:
static NonnullLockRefPtr<SysFSGlobalNetworkStatsDirectory> must_create(SysFSDirectory const&);
virtual StringView name() const override { return "net"sv; }
private:
explicit SysFSGlobalNetworkStatsDirectory(SysFSDirectory const&);
};
}

View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/JsonObjectSerializer.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Local.h>
#include <Kernel/Net/LocalSocket.h>
#include <Kernel/Sections.h>
namespace Kernel {
UNMAP_AFTER_INIT SysFSLocalNetStats::SysFSLocalNetStats(SysFSDirectory const& parent_directory)
: SysFSGlobalInformation(parent_directory)
{
}
UNMAP_AFTER_INIT NonnullLockRefPtr<SysFSLocalNetStats> SysFSLocalNetStats::must_create(SysFSDirectory const& parent_directory)
{
return adopt_lock_ref_if_nonnull(new (nothrow) SysFSLocalNetStats(parent_directory)).release_nonnull();
}
ErrorOr<void> SysFSLocalNetStats::try_generate(KBufferBuilder& builder)
{
auto array = TRY(JsonArraySerializer<>::try_create(builder));
TRY(LocalSocket::try_for_each([&array](auto& socket) -> ErrorOr<void> {
auto obj = TRY(array.add_object());
TRY(obj.add("path"sv, socket.socket_path()));
TRY(obj.add("origin_pid"sv, socket.origin_pid().value()));
TRY(obj.add("origin_uid"sv, socket.origin_uid().value()));
TRY(obj.add("origin_gid"sv, socket.origin_gid().value()));
TRY(obj.add("acceptor_pid"sv, socket.acceptor_pid().value()));
TRY(obj.add("acceptor_uid"sv, socket.acceptor_uid().value()));
TRY(obj.add("acceptor_gid"sv, socket.acceptor_gid().value()));
TRY(obj.finish());
return {};
}));
TRY(array.finish());
return {};
}
}

View file

@ -0,0 +1,27 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.h>
#include <Kernel/KBufferBuilder.h>
#include <Kernel/Library/LockRefPtr.h>
#include <Kernel/UserOrKernelBuffer.h>
namespace Kernel {
class SysFSLocalNetStats final : public SysFSGlobalInformation {
public:
virtual StringView name() const override { return "local"sv; }
static NonnullLockRefPtr<SysFSLocalNetStats> must_create(SysFSDirectory const&);
private:
explicit SysFSLocalNetStats(SysFSDirectory const&);
virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override;
};
}

View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/JsonObjectSerializer.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Route.h>
#include <Kernel/Net/Routing.h>
#include <Kernel/Sections.h>
namespace Kernel {
UNMAP_AFTER_INIT SysFSNetworkRouteStats::SysFSNetworkRouteStats(SysFSDirectory const& parent_directory)
: SysFSGlobalInformation(parent_directory)
{
}
UNMAP_AFTER_INIT NonnullLockRefPtr<SysFSNetworkRouteStats> SysFSNetworkRouteStats::must_create(SysFSDirectory const& parent_directory)
{
return adopt_lock_ref_if_nonnull(new (nothrow) SysFSNetworkRouteStats(parent_directory)).release_nonnull();
}
ErrorOr<void> SysFSNetworkRouteStats::try_generate(KBufferBuilder& builder)
{
auto array = TRY(JsonArraySerializer<>::try_create(builder));
TRY(routing_table().with([&](auto const& table) -> ErrorOr<void> {
for (auto& it : table) {
auto obj = TRY(array.add_object());
auto destination = TRY(it.destination.to_string());
TRY(obj.add("destination"sv, destination->view()));
auto gateway = TRY(it.gateway.to_string());
TRY(obj.add("gateway"sv, gateway->view()));
auto netmask = TRY(it.netmask.to_string());
TRY(obj.add("genmask"sv, netmask->view()));
TRY(obj.add("flags"sv, it.flags));
TRY(obj.add("interface"sv, it.adapter->name()));
TRY(obj.finish());
}
return {};
}));
TRY(array.finish());
return {};
}
}

View file

@ -0,0 +1,27 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.h>
#include <Kernel/KBufferBuilder.h>
#include <Kernel/Library/LockRefPtr.h>
#include <Kernel/UserOrKernelBuffer.h>
namespace Kernel {
class SysFSNetworkRouteStats final : public SysFSGlobalInformation {
public:
virtual StringView name() const override { return "route"sv; }
static NonnullLockRefPtr<SysFSNetworkRouteStats> must_create(SysFSDirectory const&);
private:
explicit SysFSNetworkRouteStats(SysFSDirectory const&);
virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override;
};
}

View file

@ -0,0 +1,57 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/JsonObjectSerializer.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/TCP.h>
#include <Kernel/Net/Routing.h>
#include <Kernel/Net/TCPSocket.h>
#include <Kernel/Process.h>
#include <Kernel/Sections.h>
namespace Kernel {
UNMAP_AFTER_INIT SysFSNetworkTCPStats::SysFSNetworkTCPStats(SysFSDirectory const& parent_directory)
: SysFSGlobalInformation(parent_directory)
{
}
UNMAP_AFTER_INIT NonnullLockRefPtr<SysFSNetworkTCPStats> SysFSNetworkTCPStats::must_create(SysFSDirectory const& parent_directory)
{
return adopt_lock_ref_if_nonnull(new (nothrow) SysFSNetworkTCPStats(parent_directory)).release_nonnull();
}
ErrorOr<void> SysFSNetworkTCPStats::try_generate(KBufferBuilder& builder)
{
auto array = TRY(JsonArraySerializer<>::try_create(builder));
TRY(TCPSocket::try_for_each([&array](auto& socket) -> ErrorOr<void> {
auto obj = TRY(array.add_object());
auto local_address = TRY(socket.local_address().to_string());
TRY(obj.add("local_address"sv, local_address->view()));
TRY(obj.add("local_port"sv, socket.local_port()));
auto peer_address = TRY(socket.peer_address().to_string());
TRY(obj.add("peer_address"sv, peer_address->view()));
TRY(obj.add("peer_port"sv, socket.peer_port()));
TRY(obj.add("state"sv, TCPSocket::to_string(socket.state())));
TRY(obj.add("ack_number"sv, socket.ack_number()));
TRY(obj.add("sequence_number"sv, socket.sequence_number()));
TRY(obj.add("packets_in"sv, socket.packets_in()));
TRY(obj.add("bytes_in"sv, socket.bytes_in()));
TRY(obj.add("packets_out"sv, socket.packets_out()));
TRY(obj.add("bytes_out"sv, socket.bytes_out()));
auto current_process_credentials = Process::current().credentials();
if (current_process_credentials->is_superuser() || current_process_credentials->uid() == socket.origin_uid()) {
TRY(obj.add("origin_pid"sv, socket.origin_pid().value()));
TRY(obj.add("origin_uid"sv, socket.origin_uid().value()));
TRY(obj.add("origin_gid"sv, socket.origin_gid().value()));
}
TRY(obj.finish());
return {};
}));
TRY(array.finish());
return {};
}
}

View file

@ -0,0 +1,27 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.h>
#include <Kernel/KBufferBuilder.h>
#include <Kernel/Library/LockRefPtr.h>
#include <Kernel/UserOrKernelBuffer.h>
namespace Kernel {
class SysFSNetworkTCPStats final : public SysFSGlobalInformation {
public:
virtual StringView name() const override { return "tcp"sv; }
static NonnullLockRefPtr<SysFSNetworkTCPStats> must_create(SysFSDirectory const&);
private:
explicit SysFSNetworkTCPStats(SysFSDirectory const&);
virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override;
};
}

View file

@ -0,0 +1,49 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/JsonObjectSerializer.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/UDP.h>
#include <Kernel/Net/UDPSocket.h>
#include <Kernel/Process.h>
#include <Kernel/Sections.h>
namespace Kernel {
UNMAP_AFTER_INIT SysFSNetworkUDPStats::SysFSNetworkUDPStats(SysFSDirectory const& parent_directory)
: SysFSGlobalInformation(parent_directory)
{
}
UNMAP_AFTER_INIT NonnullLockRefPtr<SysFSNetworkUDPStats> SysFSNetworkUDPStats::must_create(SysFSDirectory const& parent_directory)
{
return adopt_lock_ref_if_nonnull(new (nothrow) SysFSNetworkUDPStats(parent_directory)).release_nonnull();
}
ErrorOr<void> SysFSNetworkUDPStats::try_generate(KBufferBuilder& builder)
{
auto array = TRY(JsonArraySerializer<>::try_create(builder));
TRY(UDPSocket::try_for_each([&array](auto& socket) -> ErrorOr<void> {
auto obj = TRY(array.add_object());
auto local_address = TRY(socket.local_address().to_string());
TRY(obj.add("local_address"sv, local_address->view()));
TRY(obj.add("local_port"sv, socket.local_port()));
auto peer_address = TRY(socket.peer_address().to_string());
TRY(obj.add("peer_address"sv, peer_address->view()));
TRY(obj.add("peer_port"sv, socket.peer_port()));
auto current_process_credentials = Process::current().credentials();
if (current_process_credentials->is_superuser() || current_process_credentials->uid() == socket.origin_uid()) {
TRY(obj.add("origin_pid"sv, socket.origin_pid().value()));
TRY(obj.add("origin_uid"sv, socket.origin_uid().value()));
TRY(obj.add("origin_gid"sv, socket.origin_gid().value()));
}
TRY(obj.finish());
return {};
}));
TRY(array.finish());
return {};
}
}

View file

@ -0,0 +1,27 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.h>
#include <Kernel/KBufferBuilder.h>
#include <Kernel/Library/LockRefPtr.h>
#include <Kernel/UserOrKernelBuffer.h>
namespace Kernel {
class SysFSNetworkUDPStats final : public SysFSGlobalInformation {
public:
virtual StringView name() const override { return "udp"sv; }
static NonnullLockRefPtr<SysFSNetworkUDPStats> must_create(SysFSDirectory const&);
private:
explicit SysFSNetworkUDPStats(SysFSDirectory const&);
virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override;
};
}

View file

@ -0,0 +1,180 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/JsonObjectSerializer.h>
#include <AK/Try.h>
#include <AK/UBSanitizer.h>
#include <Kernel/Arch/InterruptManagement.h>
#include <Kernel/Arch/x86/ProcessorInfo.h>
#include <Kernel/Bus/PCI/API.h>
#include <Kernel/Bus/PCI/Access.h>
#include <Kernel/CommandLine.h>
#include <Kernel/Devices/DeviceManagement.h>
#include <Kernel/Devices/HID/HIDManagement.h>
#include <Kernel/FileSystem/Custody.h>
#include <Kernel/FileSystem/FileBackedFileSystem.h>
#include <Kernel/FileSystem/OpenFileDescription.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Processes.h>
#include <Kernel/Heap/kmalloc.h>
#include <Kernel/Interrupts/GenericInterruptHandler.h>
#include <Kernel/KBufferBuilder.h>
#include <Kernel/Net/LocalSocket.h>
#include <Kernel/Net/NetworkingManagement.h>
#include <Kernel/Net/Routing.h>
#include <Kernel/Net/TCPSocket.h>
#include <Kernel/Net/UDPSocket.h>
#include <Kernel/Process.h>
#include <Kernel/ProcessExposed.h>
#include <Kernel/Scheduler.h>
#include <Kernel/Sections.h>
#include <Kernel/TTY/TTY.h>
namespace Kernel {
UNMAP_AFTER_INIT SysFSOverallProcesses::SysFSOverallProcesses(SysFSDirectory const& parent_directory)
: SysFSGlobalInformation(parent_directory)
{
}
UNMAP_AFTER_INIT NonnullLockRefPtr<SysFSOverallProcesses> SysFSOverallProcesses::must_create(SysFSDirectory const& parent_directory)
{
return adopt_lock_ref_if_nonnull(new (nothrow) SysFSOverallProcesses(parent_directory)).release_nonnull();
}
ErrorOr<void> SysFSOverallProcesses::try_generate(KBufferBuilder& builder)
{
auto json = TRY(JsonObjectSerializer<>::try_create(builder));
// Keep this in sync with CProcessStatistics.
auto build_process = [&](JsonArraySerializer<KBufferBuilder>& array, Process const& process) -> ErrorOr<void> {
auto process_object = TRY(array.add_object());
if (process.is_user_process()) {
StringBuilder pledge_builder;
#define __ENUMERATE_PLEDGE_PROMISE(promise) \
if (process.has_promised(Pledge::promise)) \
TRY(pledge_builder.try_append(#promise " "sv));
ENUMERATE_PLEDGE_PROMISES
#undef __ENUMERATE_PLEDGE_PROMISE
TRY(process_object.add("pledge"sv, pledge_builder.string_view()));
switch (process.veil_state()) {
case VeilState::None:
TRY(process_object.add("veil"sv, "None"));
break;
case VeilState::Dropped:
TRY(process_object.add("veil"sv, "Dropped"));
break;
case VeilState::Locked:
TRY(process_object.add("veil"sv, "Locked"));
break;
}
} else {
TRY(process_object.add("pledge"sv, ""sv));
TRY(process_object.add("veil"sv, ""sv));
}
TRY(process_object.add("pid"sv, process.pid().value()));
TRY(process_object.add("pgid"sv, process.tty() ? process.tty()->pgid().value() : 0));
TRY(process_object.add("pgp"sv, process.pgid().value()));
TRY(process_object.add("sid"sv, process.sid().value()));
auto credentials = process.credentials();
TRY(process_object.add("uid"sv, credentials->uid().value()));
TRY(process_object.add("gid"sv, credentials->gid().value()));
TRY(process_object.add("ppid"sv, process.ppid().value()));
if (process.tty()) {
auto tty_pseudo_name = TRY(process.tty()->pseudo_name());
TRY(process_object.add("tty"sv, tty_pseudo_name->view()));
} else {
TRY(process_object.add("tty"sv, ""));
}
TRY(process_object.add("nfds"sv, process.fds().with_shared([](auto& fds) { return fds.open_count(); })));
TRY(process_object.add("name"sv, process.name()));
TRY(process_object.add("executable"sv, process.executable() ? TRY(process.executable()->try_serialize_absolute_path())->view() : ""sv));
size_t amount_virtual = 0;
size_t amount_resident = 0;
size_t amount_dirty_private = 0;
size_t amount_clean_inode = 0;
size_t amount_shared = 0;
size_t amount_purgeable_volatile = 0;
size_t amount_purgeable_nonvolatile = 0;
TRY(process.address_space().with([&](auto& space) -> ErrorOr<void> {
amount_virtual = space->amount_virtual();
amount_resident = space->amount_resident();
amount_dirty_private = space->amount_dirty_private();
amount_clean_inode = TRY(space->amount_clean_inode());
amount_shared = space->amount_shared();
amount_purgeable_volatile = space->amount_purgeable_volatile();
amount_purgeable_nonvolatile = space->amount_purgeable_nonvolatile();
return {};
}));
TRY(process_object.add("amount_virtual"sv, amount_virtual));
TRY(process_object.add("amount_resident"sv, amount_resident));
TRY(process_object.add("amount_dirty_private"sv, amount_dirty_private));
TRY(process_object.add("amount_clean_inode"sv, amount_clean_inode));
TRY(process_object.add("amount_shared"sv, amount_shared));
TRY(process_object.add("amount_purgeable_volatile"sv, amount_purgeable_volatile));
TRY(process_object.add("amount_purgeable_nonvolatile"sv, amount_purgeable_nonvolatile));
TRY(process_object.add("dumpable"sv, process.is_dumpable()));
TRY(process_object.add("kernel"sv, process.is_kernel_process()));
auto thread_array = TRY(process_object.add_array("threads"sv));
TRY(process.try_for_each_thread([&](const Thread& thread) -> ErrorOr<void> {
SpinlockLocker locker(thread.get_lock());
auto thread_object = TRY(thread_array.add_object());
#if LOCK_DEBUG
TRY(thread_object.add("lock_count"sv, thread.lock_count()));
#endif
TRY(thread_object.add("tid"sv, thread.tid().value()));
TRY(thread_object.add("name"sv, thread.name()));
TRY(thread_object.add("times_scheduled"sv, thread.times_scheduled()));
TRY(thread_object.add("time_user"sv, thread.time_in_user()));
TRY(thread_object.add("time_kernel"sv, thread.time_in_kernel()));
TRY(thread_object.add("state"sv, thread.state_string()));
TRY(thread_object.add("cpu"sv, thread.cpu()));
TRY(thread_object.add("priority"sv, thread.priority()));
TRY(thread_object.add("syscall_count"sv, thread.syscall_count()));
TRY(thread_object.add("inode_faults"sv, thread.inode_faults()));
TRY(thread_object.add("zero_faults"sv, thread.zero_faults()));
TRY(thread_object.add("cow_faults"sv, thread.cow_faults()));
TRY(thread_object.add("file_read_bytes"sv, thread.file_read_bytes()));
TRY(thread_object.add("file_write_bytes"sv, thread.file_write_bytes()));
TRY(thread_object.add("unix_socket_read_bytes"sv, thread.unix_socket_read_bytes()));
TRY(thread_object.add("unix_socket_write_bytes"sv, thread.unix_socket_write_bytes()));
TRY(thread_object.add("ipv4_socket_read_bytes"sv, thread.ipv4_socket_read_bytes()));
TRY(thread_object.add("ipv4_socket_write_bytes"sv, thread.ipv4_socket_write_bytes()));
TRY(thread_object.finish());
return {};
}));
TRY(thread_array.finish());
TRY(process_object.finish());
return {};
};
{
auto array = TRY(json.add_array("processes"sv));
TRY(build_process(array, *Scheduler::colonel()));
TRY(Process::all_instances().with([&](auto& processes) -> ErrorOr<void> {
for (auto& process : processes)
TRY(build_process(array, process));
return {};
}));
TRY(array.finish());
}
auto total_time_scheduled = Scheduler::get_total_time_scheduled();
TRY(json.add("total_time"sv, total_time_scheduled.total));
TRY(json.add("total_time_kernel"sv, total_time_scheduled.total_kernel));
TRY(json.finish());
return {};
}
}

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.h>
#include <Kernel/KBufferBuilder.h>
#include <Kernel/Library/LockRefPtr.h>
#include <Kernel/UserOrKernelBuffer.h>
namespace Kernel {
class SysFSOverallProcesses final : public SysFSGlobalInformation {
public:
virtual StringView name() const override { return "processes"sv; }
static NonnullLockRefPtr<SysFSOverallProcesses> must_create(SysFSDirectory const& parent_directory);
private:
explicit SysFSOverallProcesses(SysFSDirectory const& parent_directory);
virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override;
};
}

View file

@ -0,0 +1,36 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Profile.h>
#include <Kernel/PerformanceEventBuffer.h>
#include <Kernel/Sections.h>
namespace Kernel {
UNMAP_AFTER_INIT SysFSProfile::SysFSProfile(SysFSDirectory const& parent_directory)
: SysFSGlobalInformation(parent_directory)
{
}
UNMAP_AFTER_INIT NonnullLockRefPtr<SysFSProfile> SysFSProfile::must_create(SysFSDirectory const& parent_directory)
{
return adopt_lock_ref_if_nonnull(new (nothrow) SysFSProfile(parent_directory)).release_nonnull();
}
ErrorOr<void> SysFSProfile::try_generate(KBufferBuilder& builder)
{
if (!g_global_perf_events)
return ENOENT;
TRY(g_global_perf_events->to_json(builder));
return {};
}
mode_t SysFSProfile::permissions() const
{
return S_IRUSR;
}
}

View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.h>
#include <Kernel/KBufferBuilder.h>
#include <Kernel/Library/LockRefPtr.h>
#include <Kernel/UserOrKernelBuffer.h>
namespace Kernel {
class SysFSProfile final : public SysFSGlobalInformation {
public:
virtual StringView name() const override { return "profile"sv; }
static NonnullLockRefPtr<SysFSProfile> must_create(SysFSDirectory const& parent_directory);
private:
virtual mode_t permissions() const override;
explicit SysFSProfile(SysFSDirectory const& parent_directory);
virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override;
};
}

View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <Kernel/CommandLine.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/SystemMode.h>
#include <Kernel/Sections.h>
namespace Kernel {
UNMAP_AFTER_INIT SysFSSystemMode::SysFSSystemMode(SysFSDirectory const& parent_directory)
: SysFSGlobalInformation(parent_directory)
{
}
UNMAP_AFTER_INIT NonnullLockRefPtr<SysFSSystemMode> SysFSSystemMode::must_create(SysFSDirectory const& parent_directory)
{
return adopt_lock_ref_if_nonnull(new (nothrow) SysFSSystemMode(parent_directory)).release_nonnull();
}
ErrorOr<void> SysFSSystemMode::try_generate(KBufferBuilder& builder)
{
TRY(builder.append(kernel_command_line().system_mode()));
TRY(builder.append('\n'));
return {};
}
}

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.h>
#include <Kernel/KBufferBuilder.h>
#include <Kernel/Library/LockRefPtr.h>
#include <Kernel/UserOrKernelBuffer.h>
namespace Kernel {
class SysFSSystemMode final : public SysFSGlobalInformation {
public:
virtual StringView name() const override { return "system_mode"sv; }
static NonnullLockRefPtr<SysFSSystemMode> must_create(SysFSDirectory const& parent_directory);
private:
explicit SysFSSystemMode(SysFSDirectory const& parent_directory);
virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override;
};
}

View file

@ -0,0 +1,41 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/JsonObjectSerializer.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/SystemStatistics.h>
#include <Kernel/Scheduler.h>
#include <Kernel/Sections.h>
#include <Kernel/Time/TimeManagement.h>
namespace Kernel {
UNMAP_AFTER_INIT SysFSSystemStatistics::SysFSSystemStatistics(SysFSDirectory const& parent_directory)
: SysFSGlobalInformation(parent_directory)
{
}
UNMAP_AFTER_INIT NonnullLockRefPtr<SysFSSystemStatistics> SysFSSystemStatistics::must_create(SysFSDirectory const& parent_directory)
{
return adopt_lock_ref_if_nonnull(new (nothrow) SysFSSystemStatistics(parent_directory)).release_nonnull();
}
ErrorOr<void> SysFSSystemStatistics::try_generate(KBufferBuilder& builder)
{
auto json = TRY(JsonObjectSerializer<>::try_create(builder));
auto total_time_scheduled = Scheduler::get_total_time_scheduled();
TRY(json.add("total_time"sv, total_time_scheduled.total));
TRY(json.add("kernel_time"sv, total_time_scheduled.total_kernel));
TRY(json.add("user_time"sv, total_time_scheduled.total - total_time_scheduled.total_kernel));
u64 idle_time = 0;
Processor::for_each([&](Processor& processor) {
idle_time += processor.time_spent_idle();
});
TRY(json.add("idle_time"sv, idle_time));
TRY(json.finish());
return {};
}
}

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.h>
#include <Kernel/KBufferBuilder.h>
#include <Kernel/Library/LockRefPtr.h>
#include <Kernel/UserOrKernelBuffer.h>
namespace Kernel {
class SysFSSystemStatistics final : public SysFSGlobalInformation {
public:
virtual StringView name() const override { return "stats"sv; }
static NonnullLockRefPtr<SysFSSystemStatistics> must_create(SysFSDirectory const& parent_directory);
private:
explicit SysFSSystemStatistics(SysFSDirectory const& parent_directory);
virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override;
};
}

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Uptime.h>
#include <Kernel/Sections.h>
#include <Kernel/Time/TimeManagement.h>
namespace Kernel {
UNMAP_AFTER_INIT SysFSUptime::SysFSUptime(SysFSDirectory const& parent_directory)
: SysFSGlobalInformation(parent_directory)
{
}
UNMAP_AFTER_INIT NonnullLockRefPtr<SysFSUptime> SysFSUptime::must_create(SysFSDirectory const& parent_directory)
{
return adopt_lock_ref_if_nonnull(new (nothrow) SysFSUptime(parent_directory)).release_nonnull();
}
ErrorOr<void> SysFSUptime::try_generate(KBufferBuilder& builder)
{
return builder.appendff("{}\n", TimeManagement::the().uptime_ms() / 1000);
}
}

View file

@ -0,0 +1,27 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.h>
#include <Kernel/KBufferBuilder.h>
#include <Kernel/Library/LockRefPtr.h>
#include <Kernel/UserOrKernelBuffer.h>
namespace Kernel {
class SysFSUptime final : public SysFSGlobalInformation {
public:
virtual StringView name() const override { return "uptime"sv; }
static NonnullLockRefPtr<SysFSUptime> must_create(SysFSDirectory const& parent_directory);
private:
explicit SysFSUptime(SysFSDirectory const& parent_directory);
virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override;
};
}

View file

@ -0,0 +1,40 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/BooleanVariable.h>
#include <Kernel/Sections.h>
namespace Kernel {
ErrorOr<void> SysFSSystemBoolean::try_generate(KBufferBuilder& builder)
{
return builder.appendff("{}\n", static_cast<int>(value()));
}
ErrorOr<size_t> SysFSSystemBoolean::write_bytes(off_t, size_t count, UserOrKernelBuffer const& buffer, OpenFileDescription*)
{
if (count != 1)
return EINVAL;
MutexLocker locker(m_refresh_lock);
char value = 0;
TRY(buffer.read(&value, 1));
if (value == '0')
set_value(false);
else if (value == '1')
set_value(true);
else
return EINVAL;
return 1;
}
ErrorOr<void> SysFSSystemBoolean::truncate(u64 size)
{
if (size != 0)
return EPERM;
return {};
}
}

View file

@ -0,0 +1,44 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/AtomicRefCounted.h>
#include <AK/Error.h>
#include <AK/Function.h>
#include <AK/Types.h>
#include <Kernel/FileSystem/File.h>
#include <Kernel/FileSystem/FileSystem.h>
#include <Kernel/FileSystem/OpenFileDescription.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.h>
#include <Kernel/KBufferBuilder.h>
#include <Kernel/Library/LockRefPtr.h>
#include <Kernel/Locking/Mutex.h>
#include <Kernel/Time/TimeManagement.h>
#include <Kernel/UserOrKernelBuffer.h>
namespace Kernel {
class SysFSSystemBoolean : public SysFSGlobalInformation {
protected:
explicit SysFSSystemBoolean(SysFSDirectory const& parent_directory)
: SysFSGlobalInformation(parent_directory)
{
}
virtual bool value() const = 0;
virtual void set_value(bool new_value) = 0;
private:
// ^SysFSGlobalInformation
virtual ErrorOr<void> try_generate(KBufferBuilder&) override final;
// ^SysFSExposedComponent
virtual ErrorOr<size_t> write_bytes(off_t, size_t, UserOrKernelBuffer const&, OpenFileDescription*) override final;
virtual mode_t permissions() const override final { return 0644; }
virtual ErrorOr<void> truncate(u64) override final;
};
}

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <Kernel/Devices/HID/HIDManagement.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/CapsLockRemap.h>
#include <Kernel/Sections.h>
namespace Kernel {
UNMAP_AFTER_INIT SysFSCapsLockRemap::SysFSCapsLockRemap(SysFSDirectory const& parent_directory)
: SysFSSystemBoolean(parent_directory)
{
}
UNMAP_AFTER_INIT NonnullLockRefPtr<SysFSCapsLockRemap> SysFSCapsLockRemap::must_create(SysFSDirectory const& parent_directory)
{
return adopt_lock_ref_if_nonnull(new (nothrow) SysFSCapsLockRemap(parent_directory)).release_nonnull();
}
bool SysFSCapsLockRemap::value() const
{
MutexLocker locker(m_lock);
return g_caps_lock_remapped_to_ctrl.load();
}
void SysFSCapsLockRemap::set_value(bool new_value)
{
MutexLocker locker(m_lock);
g_caps_lock_remapped_to_ctrl.exchange(new_value);
}
}

View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/BooleanVariable.h>
#include <Kernel/Library/LockRefPtr.h>
#include <Kernel/UserOrKernelBuffer.h>
namespace Kernel {
class SysFSCapsLockRemap final : public SysFSSystemBoolean {
public:
virtual StringView name() const override { return "caps_lock_to_ctrl"sv; }
static NonnullLockRefPtr<SysFSCapsLockRemap> must_create(SysFSDirectory const&);
private:
virtual bool value() const override;
virtual void set_value(bool new_value) override;
explicit SysFSCapsLockRemap(SysFSDirectory const&);
mutable Mutex m_lock;
};
}

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Error.h>
#include <AK/Try.h>
#include <Kernel/FileSystem/SysFS/Component.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/CapsLockRemap.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/Directory.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/DumpKmallocStack.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/UBSANDeadly.h>
namespace Kernel {
UNMAP_AFTER_INIT NonnullLockRefPtr<SysFSGlobalKernelVariablesDirectory> SysFSGlobalKernelVariablesDirectory::must_create(SysFSDirectory const& parent_directory)
{
auto global_variables_directory = adopt_lock_ref_if_nonnull(new (nothrow) SysFSGlobalKernelVariablesDirectory(parent_directory)).release_nonnull();
MUST(global_variables_directory->m_child_components.with([&](auto& list) -> ErrorOr<void> {
list.append(SysFSCapsLockRemap::must_create(*global_variables_directory));
list.append(SysFSDumpKmallocStacks::must_create(*global_variables_directory));
list.append(SysFSUBSANDeadly::must_create(*global_variables_directory));
return {};
}));
return global_variables_directory;
}
UNMAP_AFTER_INIT SysFSGlobalKernelVariablesDirectory::SysFSGlobalKernelVariablesDirectory(SysFSDirectory const& parent_directory)
: SysFSDirectory(parent_directory)
{
}
}

View file

@ -0,0 +1,24 @@
/*
* Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
#include <Kernel/FileSystem/SysFS/Component.h>
#include <Kernel/FileSystem/SysFS/RootDirectory.h>
namespace Kernel {
class SysFSGlobalKernelVariablesDirectory : public SysFSDirectory {
public:
static NonnullLockRefPtr<SysFSGlobalKernelVariablesDirectory> must_create(SysFSDirectory const&);
virtual StringView name() const override { return "variables"sv; }
private:
explicit SysFSGlobalKernelVariablesDirectory(SysFSDirectory const&);
};
}

View file

@ -0,0 +1,35 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/DumpKmallocStack.h>
#include <Kernel/Process.h>
#include <Kernel/Sections.h>
namespace Kernel {
UNMAP_AFTER_INIT SysFSDumpKmallocStacks::SysFSDumpKmallocStacks(SysFSDirectory const& parent_directory)
: SysFSSystemBoolean(parent_directory)
{
}
UNMAP_AFTER_INIT NonnullLockRefPtr<SysFSDumpKmallocStacks> SysFSDumpKmallocStacks::must_create(SysFSDirectory const& parent_directory)
{
return adopt_lock_ref_if_nonnull(new (nothrow) SysFSDumpKmallocStacks(parent_directory)).release_nonnull();
}
bool SysFSDumpKmallocStacks::value() const
{
MutexLocker locker(m_lock);
return g_dump_kmalloc_stacks;
}
void SysFSDumpKmallocStacks::set_value(bool new_value)
{
MutexLocker locker(m_lock);
g_dump_kmalloc_stacks = new_value;
}
}

View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/BooleanVariable.h>
#include <Kernel/Library/LockRefPtr.h>
#include <Kernel/UserOrKernelBuffer.h>
namespace Kernel {
class SysFSDumpKmallocStacks final : public SysFSSystemBoolean {
public:
virtual StringView name() const override { return "kmalloc_stacks"sv; }
static NonnullLockRefPtr<SysFSDumpKmallocStacks> must_create(SysFSDirectory const&);
private:
virtual bool value() const override;
virtual void set_value(bool new_value) override;
explicit SysFSDumpKmallocStacks(SysFSDirectory const&);
mutable Mutex m_lock;
};
}

View file

@ -0,0 +1,32 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/UBSanitizer.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/UBSANDeadly.h>
#include <Kernel/Sections.h>
namespace Kernel {
UNMAP_AFTER_INIT SysFSUBSANDeadly::SysFSUBSANDeadly(SysFSDirectory const& parent_directory)
: SysFSSystemBoolean(parent_directory)
{
}
UNMAP_AFTER_INIT NonnullLockRefPtr<SysFSUBSANDeadly> SysFSUBSANDeadly::must_create(SysFSDirectory const& parent_directory)
{
return adopt_lock_ref_if_nonnull(new (nothrow) SysFSUBSANDeadly(parent_directory)).release_nonnull();
}
bool SysFSUBSANDeadly::value() const
{
return AK::UBSanitizer::g_ubsan_is_deadly;
}
void SysFSUBSANDeadly::set_value(bool new_value)
{
AK::UBSanitizer::g_ubsan_is_deadly = new_value;
}
}

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Types.h>
#include <Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/BooleanVariable.h>
#include <Kernel/Library/LockRefPtr.h>
#include <Kernel/UserOrKernelBuffer.h>
namespace Kernel {
class SysFSUBSANDeadly final : public SysFSSystemBoolean {
public:
virtual StringView name() const override { return "ubsan_is_deadly"sv; }
static NonnullLockRefPtr<SysFSUBSANDeadly> must_create(SysFSDirectory const&);
private:
virtual bool value() const override;
virtual void set_value(bool new_value) override;
explicit SysFSUBSANDeadly(SysFSDirectory const&);
};
}