From a91589c09b94477ffaff4fdf28c280790ee1441a Mon Sep 17 00:00:00 2001 From: Liav A Date: Fri, 14 Oct 2022 20:51:51 +0300 Subject: [PATCH] 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. --- Kernel/CMakeLists.txt | 27 +++ Kernel/Devices/ConsoleDevice.cpp | 6 +- Kernel/Devices/ConsoleDevice.h | 2 + Kernel/FileSystem/SysFS/RootDirectory.cpp | 3 + .../SysFS/Subsystems/Kernel/CPUInfo.cpp | 83 ++++++++ .../SysFS/Subsystems/Kernel/CPUInfo.h | 28 +++ .../SysFS/Subsystems/Kernel/CommandLine.cpp | 30 +++ .../SysFS/Subsystems/Kernel/CommandLine.h | 28 +++ .../SysFS/Subsystems/Kernel/Directory.cpp | 60 ++++++ .../SysFS/Subsystems/Kernel/Directory.h | 24 +++ .../SysFS/Subsystems/Kernel/DiskUsage.cpp | 56 ++++++ .../SysFS/Subsystems/Kernel/DiskUsage.h | 28 +++ .../Subsystems/Kernel/GlobalInformation.cpp | 62 ++++++ .../Subsystems/Kernel/GlobalInformation.h | 34 ++++ .../SysFS/Subsystems/Kernel/Interrupts.cpp | 48 +++++ .../SysFS/Subsystems/Kernel/Interrupts.h | 28 +++ .../SysFS/Subsystems/Kernel/Keymap.cpp | 34 ++++ .../SysFS/Subsystems/Kernel/Keymap.h | 28 +++ .../SysFS/Subsystems/Kernel/LoadBase.cpp | 38 ++++ .../SysFS/Subsystems/Kernel/LoadBase.h | 31 +++ .../SysFS/Subsystems/Kernel/Log.cpp | 39 ++++ .../FileSystem/SysFS/Subsystems/Kernel/Log.h | 29 +++ .../SysFS/Subsystems/Kernel/MemoryStatus.cpp | 44 +++++ .../SysFS/Subsystems/Kernel/MemoryStatus.h | 28 +++ .../SysFS/Subsystems/Kernel/Network/ARP.cpp | 43 +++++ .../SysFS/Subsystems/Kernel/Network/ARP.h | 27 +++ .../Subsystems/Kernel/Network/Adapters.cpp | 54 ++++++ .../Subsystems/Kernel/Network/Adapters.h | 27 +++ .../Subsystems/Kernel/Network/Directory.cpp | 40 ++++ .../Subsystems/Kernel/Network/Directory.h | 24 +++ .../SysFS/Subsystems/Kernel/Network/Local.cpp | 43 +++++ .../SysFS/Subsystems/Kernel/Network/Local.h | 27 +++ .../SysFS/Subsystems/Kernel/Network/Route.cpp | 46 +++++ .../SysFS/Subsystems/Kernel/Network/Route.h | 27 +++ .../SysFS/Subsystems/Kernel/Network/TCP.cpp | 57 ++++++ .../SysFS/Subsystems/Kernel/Network/TCP.h | 27 +++ .../SysFS/Subsystems/Kernel/Network/UDP.cpp | 49 +++++ .../SysFS/Subsystems/Kernel/Network/UDP.h | 27 +++ .../SysFS/Subsystems/Kernel/Processes.cpp | 180 ++++++++++++++++++ .../SysFS/Subsystems/Kernel/Processes.h | 28 +++ .../SysFS/Subsystems/Kernel/Profile.cpp | 36 ++++ .../SysFS/Subsystems/Kernel/Profile.h | 30 +++ .../SysFS/Subsystems/Kernel/SystemMode.cpp | 30 +++ .../SysFS/Subsystems/Kernel/SystemMode.h | 28 +++ .../Subsystems/Kernel/SystemStatistics.cpp | 41 ++++ .../Subsystems/Kernel/SystemStatistics.h | 28 +++ .../SysFS/Subsystems/Kernel/Uptime.cpp | 28 +++ .../SysFS/Subsystems/Kernel/Uptime.h | 27 +++ .../Kernel/Variables/BooleanVariable.cpp | 40 ++++ .../Kernel/Variables/BooleanVariable.h | 44 +++++ .../Kernel/Variables/CapsLockRemap.cpp | 34 ++++ .../Kernel/Variables/CapsLockRemap.h | 30 +++ .../Subsystems/Kernel/Variables/Directory.cpp | 34 ++++ .../Subsystems/Kernel/Variables/Directory.h | 24 +++ .../Kernel/Variables/DumpKmallocStack.cpp | 35 ++++ .../Kernel/Variables/DumpKmallocStack.h | 30 +++ .../Kernel/Variables/UBSANDeadly.cpp | 32 ++++ .../Subsystems/Kernel/Variables/UBSANDeadly.h | 28 +++ 58 files changed, 2122 insertions(+), 1 deletion(-) create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/CPUInfo.cpp create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/CPUInfo.h create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/CommandLine.cpp create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/CommandLine.h create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Directory.cpp create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Directory.h create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/DiskUsage.cpp create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/DiskUsage.h create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.cpp create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.h create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Interrupts.cpp create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Interrupts.h create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Keymap.cpp create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Keymap.h create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/LoadBase.cpp create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/LoadBase.h create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Log.cpp create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Log.h create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/MemoryStatus.cpp create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/MemoryStatus.h create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/ARP.cpp create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/ARP.h create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Adapters.cpp create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Adapters.h create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Directory.cpp create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Directory.h create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Local.cpp create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Local.h create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Route.cpp create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Route.h create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/TCP.cpp create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/TCP.h create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/UDP.cpp create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/UDP.h create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Processes.cpp create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Processes.h create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Profile.cpp create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Profile.h create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/SystemMode.cpp create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/SystemMode.h create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/SystemStatistics.cpp create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/SystemStatistics.h create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Uptime.cpp create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Uptime.h create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/BooleanVariable.cpp create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/BooleanVariable.h create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/CapsLockRemap.cpp create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/CapsLockRemap.h create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/Directory.cpp create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/Directory.h create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/DumpKmallocStack.cpp create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/DumpKmallocStack.h create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/UBSANDeadly.cpp create mode 100644 Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/UBSANDeadly.h diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt index 6f6b9daa09d..a9047438ba3 100644 --- a/Kernel/CMakeLists.txt +++ b/Kernel/CMakeLists.txt @@ -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 diff --git a/Kernel/Devices/ConsoleDevice.cpp b/Kernel/Devices/ConsoleDevice.cpp index 4c3644a6eb2..b639d76b2ea 100644 --- a/Kernel/Devices/ConsoleDevice.cpp +++ b/Kernel/Devices/ConsoleDevice.cpp @@ -14,7 +14,9 @@ #include #include -static Kernel::Spinlock g_console_lock { LockRank::None }; +namespace Kernel { + +Spinlock g_console_lock { LockRank::None }; UNMAP_AFTER_INIT NonnullLockRefPtr ConsoleDevice::must_create() { @@ -60,3 +62,5 @@ void ConsoleDevice::put_char(char ch) dbgputchar(ch); m_logbuffer.enqueue(ch); } + +} diff --git a/Kernel/Devices/ConsoleDevice.h b/Kernel/Devices/ConsoleDevice.h index 85243f2ceab..a3913cf4315 100644 --- a/Kernel/Devices/ConsoleDevice.h +++ b/Kernel/Devices/ConsoleDevice.h @@ -12,6 +12,8 @@ namespace Kernel { +extern Spinlock g_console_lock; + class ConsoleDevice final : public CharacterDevice { friend class DeviceManagement; diff --git a/Kernel/FileSystem/SysFS/RootDirectory.cpp b/Kernel/FileSystem/SysFS/RootDirectory.cpp index 409a412cb93..d031243950c 100644 --- a/Kernel/FileSystem/SysFS/RootDirectory.cpp +++ b/Kernel/FileSystem/SysFS/RootDirectory.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include 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 { 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; diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/CPUInfo.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/CPUInfo.cpp new file mode 100644 index 00000000000..096e4007944 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/CPUInfo.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include + +namespace Kernel { + +UNMAP_AFTER_INIT SysFSCPUInformation::SysFSCPUInformation(SysFSDirectory const& parent_directory) + : SysFSGlobalInformation(parent_directory) +{ +} + +UNMAP_AFTER_INIT NonnullLockRefPtr SysFSCPUInformation::must_create(SysFSDirectory const& parent_directory) +{ + return adopt_lock_ref_if_nonnull(new (nothrow) SysFSCPUInformation(parent_directory)).release_nonnull(); +} + +ErrorOr SysFSCPUInformation::try_generate(KBufferBuilder& builder) +{ + auto array = TRY(JsonArraySerializer<>::try_create(builder)); + TRY(Processor::try_for_each( + [&](Processor& proc) -> ErrorOr { + 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 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 { + 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 {}; +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/CPUInfo.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/CPUInfo.h new file mode 100644 index 00000000000..08897598bcc --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/CPUInfo.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace Kernel { + +class SysFSCPUInformation final : public SysFSGlobalInformation { +public: + virtual StringView name() const override { return "cpuinfo"sv; } + + static NonnullLockRefPtr must_create(SysFSDirectory const& parent_directory); + +private: + SysFSCPUInformation(SysFSDirectory const& parent_directory); + virtual ErrorOr try_generate(KBufferBuilder& builder) override; +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/CommandLine.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/CommandLine.cpp new file mode 100644 index 00000000000..8d77808fc37 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/CommandLine.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include + +namespace Kernel { + +UNMAP_AFTER_INIT NonnullLockRefPtr 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 SysFSCommandLine::try_generate(KBufferBuilder& builder) +{ + TRY(builder.append(kernel_command_line().string())); + TRY(builder.append('\n')); + return {}; +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/CommandLine.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/CommandLine.h new file mode 100644 index 00000000000..24e8873b617 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/CommandLine.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace Kernel { + +class SysFSCommandLine final : public SysFSGlobalInformation { +public: + virtual StringView name() const override { return "cmdline"sv; } + + static NonnullLockRefPtr must_create(SysFSDirectory const& parent_directory); + +private: + SysFSCommandLine(SysFSDirectory const& parent_directory); + virtual ErrorOr try_generate(KBufferBuilder& builder) override; +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Directory.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Directory.cpp new file mode 100644 index 00000000000..8d8bc394b7d --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Directory.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Kernel { + +UNMAP_AFTER_INIT NonnullLockRefPtr 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 { + 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) +{ +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Directory.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Directory.h new file mode 100644 index 00000000000..51af6e8be96 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Directory.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2021, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include + +namespace Kernel { + +class SysFSGlobalKernelStatsDirectory : public SysFSDirectory { +public: + static NonnullLockRefPtr must_create(SysFSRootDirectory const&); + virtual StringView name() const override { return "kernel"sv; } + +private: + explicit SysFSGlobalKernelStatsDirectory(SysFSDirectory const&); +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/DiskUsage.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/DiskUsage.cpp new file mode 100644 index 00000000000..cbe7f2f111e --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/DiskUsage.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include + +namespace Kernel { + +UNMAP_AFTER_INIT NonnullLockRefPtr 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 SysFSDiskUsage::try_generate(KBufferBuilder& builder) +{ + auto array = TRY(JsonArraySerializer<>::try_create(builder)); + TRY(VirtualFileSystem::the().for_each_mount([&array](auto& mount) -> ErrorOr { + 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(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(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 {}; +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/DiskUsage.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/DiskUsage.h new file mode 100644 index 00000000000..e317b968898 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/DiskUsage.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace Kernel { + +class SysFSDiskUsage final : public SysFSGlobalInformation { +public: + virtual StringView name() const override { return "df"sv; } + + static NonnullLockRefPtr must_create(SysFSDirectory const& parent_directory); + +private: + SysFSDiskUsage(SysFSDirectory const& parent_directory); + virtual ErrorOr try_generate(KBufferBuilder& builder) override; +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.cpp new file mode 100644 index 00000000000..6c87872afdd --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include + +namespace Kernel { + +ErrorOr 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(*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(data_buffer->size() - offset), static_cast(count)); + TRY(buffer.write(data_buffer->data() + offset, nread)); + return nread; +} + +SysFSGlobalInformation::SysFSGlobalInformation(SysFSDirectory const& parent_directory) + : SysFSComponent(parent_directory) +{ +} + +ErrorOr 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(*this).try_generate(builder)); + auto& typed_cached_data = static_cast(*cached_data); + typed_cached_data.buffer = builder.build(); + if (!typed_cached_data.buffer) + return ENOMEM; + return {}; +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.h new file mode 100644 index 00000000000..d4635733854 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/GlobalInformation.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Kernel { + +class SysFSGlobalInformation : public SysFSComponent { +public: + virtual ErrorOr read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, OpenFileDescription* description) const override; + +protected: + explicit SysFSGlobalInformation(SysFSDirectory const& parent_directory); + virtual ErrorOr refresh_data(OpenFileDescription&) const override; + virtual ErrorOr try_generate(KBufferBuilder&) = 0; + + mutable Mutex m_refresh_lock; +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Interrupts.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Interrupts.cpp new file mode 100644 index 00000000000..15510da7074 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Interrupts.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include + +namespace Kernel { + +UNMAP_AFTER_INIT SysFSInterrupts::SysFSInterrupts(SysFSDirectory const& parent_directory) + : SysFSGlobalInformation(parent_directory) +{ +} + +UNMAP_AFTER_INIT NonnullLockRefPtr SysFSInterrupts::must_create(SysFSDirectory const& parent_directory) +{ + return adopt_lock_ref_if_nonnull(new (nothrow) SysFSInterrupts(parent_directory)).release_nonnull(); +} + +ErrorOr SysFSInterrupts::try_generate(KBufferBuilder& builder) +{ + auto array = TRY(JsonArraySerializer<>::try_create(builder)); + ErrorOr result; // FIXME: Make this nicer + InterruptManagement::the().enumerate_interrupt_handlers([&array, &result](GenericInterruptHandler& handler) { + if (result.is_error()) + return; + result = ([&]() -> ErrorOr { + 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 {}; +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Interrupts.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Interrupts.h new file mode 100644 index 00000000000..7353a92b86c --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Interrupts.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace Kernel { + +class SysFSInterrupts final : public SysFSGlobalInformation { +public: + virtual StringView name() const override { return "interrupts"sv; } + + static NonnullLockRefPtr must_create(SysFSDirectory const& parent_directory); + +private: + explicit SysFSInterrupts(SysFSDirectory const& parent_directory); + virtual ErrorOr try_generate(KBufferBuilder& builder) override; +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Keymap.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Keymap.cpp new file mode 100644 index 00000000000..eb868248915 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Keymap.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include + +namespace Kernel { + +UNMAP_AFTER_INIT SysFSKeymap::SysFSKeymap(SysFSDirectory const& parent_directory) + : SysFSGlobalInformation(parent_directory) +{ +} + +UNMAP_AFTER_INIT NonnullLockRefPtr SysFSKeymap::must_create(SysFSDirectory const& parent_directory) +{ + return adopt_lock_ref_if_nonnull(new (nothrow) SysFSKeymap(parent_directory)).release_nonnull(); +} + +ErrorOr 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 {}; +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Keymap.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Keymap.h new file mode 100644 index 00000000000..8124615a861 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Keymap.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace Kernel { + +class SysFSKeymap final : public SysFSGlobalInformation { +public: + virtual StringView name() const override { return "keymap"sv; } + + static NonnullLockRefPtr must_create(SysFSDirectory const& parent_directory); + +private: + explicit SysFSKeymap(SysFSDirectory const& parent_directory); + virtual ErrorOr try_generate(KBufferBuilder& builder) override; +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/LoadBase.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/LoadBase.cpp new file mode 100644 index 00000000000..d5e519ecd5c --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/LoadBase.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include + +namespace Kernel { + +UNMAP_AFTER_INIT SysFSKernelLoadBase::SysFSKernelLoadBase(SysFSDirectory const& parent_directory) + : SysFSGlobalInformation(parent_directory) +{ +} + +UNMAP_AFTER_INIT NonnullLockRefPtr SysFSKernelLoadBase::must_create(SysFSDirectory const& parent_directory) +{ + return adopt_lock_ref_if_nonnull(new (nothrow) SysFSKernelLoadBase(parent_directory)).release_nonnull(); +} + +ErrorOr 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; +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/LoadBase.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/LoadBase.h new file mode 100644 index 00000000000..4a0e92fd8f9 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/LoadBase.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace Kernel { + +class SysFSKernelLoadBase final : public SysFSGlobalInformation { +public: + virtual StringView name() const override { return "load_base"sv; } + + static NonnullLockRefPtr must_create(SysFSDirectory const& parent_directory); + +private: + explicit SysFSKernelLoadBase(SysFSDirectory const& parent_directory); + + virtual mode_t permissions() const override; + + virtual ErrorOr try_generate(KBufferBuilder& builder) override; +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Log.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Log.cpp new file mode 100644 index 00000000000..17c04c96a63 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Log.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include + +namespace Kernel { + +UNMAP_AFTER_INIT SysFSKernelLog::SysFSKernelLog(SysFSDirectory const& parent_directory) + : SysFSGlobalInformation(parent_directory) +{ +} + +UNMAP_AFTER_INIT NonnullLockRefPtr 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 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 {}; +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Log.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Log.h new file mode 100644 index 00000000000..a43d8fe7f62 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Log.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace Kernel { + +class SysFSKernelLog final : public SysFSGlobalInformation { +public: + virtual StringView name() const override { return "dmesg"sv; } + static NonnullLockRefPtr must_create(SysFSDirectory const& parent_directory); + + virtual mode_t permissions() const override; + +private: + explicit SysFSKernelLog(SysFSDirectory const& parent_directory); + virtual ErrorOr try_generate(KBufferBuilder& builder) override; +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/MemoryStatus.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/MemoryStatus.cpp new file mode 100644 index 00000000000..be6ffed6feb --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/MemoryStatus.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include + +namespace Kernel { + +UNMAP_AFTER_INIT SysFSMemoryStatus::SysFSMemoryStatus(SysFSDirectory const& parent_directory) + : SysFSGlobalInformation(parent_directory) +{ +} + +UNMAP_AFTER_INIT NonnullLockRefPtr SysFSMemoryStatus::must_create(SysFSDirectory const& parent_directory) +{ + return adopt_lock_ref_if_nonnull(new (nothrow) SysFSMemoryStatus(parent_directory)).release_nonnull(); +} + +ErrorOr 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 {}; +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/MemoryStatus.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/MemoryStatus.h new file mode 100644 index 00000000000..675cfa1fc48 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/MemoryStatus.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace Kernel { + +class SysFSMemoryStatus final : public SysFSGlobalInformation { +public: + virtual StringView name() const override { return "memstat"sv; } + + static NonnullLockRefPtr must_create(SysFSDirectory const& parent_directory); + +private: + explicit SysFSMemoryStatus(SysFSDirectory const& parent_directory); + virtual ErrorOr try_generate(KBufferBuilder& builder) override; +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/ARP.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/ARP.cpp new file mode 100644 index 00000000000..319bafd0efa --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/ARP.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include + +namespace Kernel { + +UNMAP_AFTER_INIT SysFSNetworkARPStats::SysFSNetworkARPStats(SysFSDirectory const& parent_directory) + : SysFSGlobalInformation(parent_directory) +{ +} + +UNMAP_AFTER_INIT NonnullLockRefPtr SysFSNetworkARPStats::must_create(SysFSDirectory const& parent_directory) +{ + return adopt_lock_ref_if_nonnull(new (nothrow) SysFSNetworkARPStats(parent_directory)).release_nonnull(); +} + +ErrorOr SysFSNetworkARPStats::try_generate(KBufferBuilder& builder) +{ + auto array = TRY(JsonArraySerializer<>::try_create(builder)); + TRY(arp_table().with([&](auto const& table) -> ErrorOr { + 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 {}; +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/ARP.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/ARP.h new file mode 100644 index 00000000000..6764192d3a6 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/ARP.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace Kernel { + +class SysFSNetworkARPStats final : public SysFSGlobalInformation { +public: + virtual StringView name() const override { return "arp"sv; } + static NonnullLockRefPtr must_create(SysFSDirectory const&); + +private: + explicit SysFSNetworkARPStats(SysFSDirectory const&); + virtual ErrorOr try_generate(KBufferBuilder& builder) override; +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Adapters.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Adapters.cpp new file mode 100644 index 00000000000..83906bcaa9b --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Adapters.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include + +namespace Kernel { + +UNMAP_AFTER_INIT SysFSNetworkAdaptersStats::SysFSNetworkAdaptersStats(SysFSDirectory const& parent_directory) + : SysFSGlobalInformation(parent_directory) +{ +} + +UNMAP_AFTER_INIT NonnullLockRefPtr SysFSNetworkAdaptersStats::must_create(SysFSDirectory const& parent_directory) +{ + return adopt_lock_ref_if_nonnull(new (nothrow) SysFSNetworkAdaptersStats(parent_directory)).release_nonnull(); +} + +ErrorOr SysFSNetworkAdaptersStats::try_generate(KBufferBuilder& builder) +{ + auto array = TRY(JsonArraySerializer<>::try_create(builder)); + TRY(NetworkingManagement::the().try_for_each([&array](auto& adapter) -> ErrorOr { + 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 {}; +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Adapters.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Adapters.h new file mode 100644 index 00000000000..c55d5538d0f --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Adapters.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace Kernel { + +class SysFSNetworkAdaptersStats final : public SysFSGlobalInformation { +public: + virtual StringView name() const override { return "adapters"sv; } + static NonnullLockRefPtr must_create(SysFSDirectory const&); + +private: + explicit SysFSNetworkAdaptersStats(SysFSDirectory const&); + virtual ErrorOr try_generate(KBufferBuilder& builder) override; +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Directory.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Directory.cpp new file mode 100644 index 00000000000..76b5dd0f8a0 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Directory.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Kernel { + +UNMAP_AFTER_INIT NonnullLockRefPtr 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 { + 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) +{ +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Directory.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Directory.h new file mode 100644 index 00000000000..6563b75cf96 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Directory.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2021, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include + +namespace Kernel { + +class SysFSGlobalNetworkStatsDirectory : public SysFSDirectory { +public: + static NonnullLockRefPtr must_create(SysFSDirectory const&); + virtual StringView name() const override { return "net"sv; } + +private: + explicit SysFSGlobalNetworkStatsDirectory(SysFSDirectory const&); +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Local.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Local.cpp new file mode 100644 index 00000000000..9cb3509e4c6 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Local.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include + +namespace Kernel { + +UNMAP_AFTER_INIT SysFSLocalNetStats::SysFSLocalNetStats(SysFSDirectory const& parent_directory) + : SysFSGlobalInformation(parent_directory) +{ +} + +UNMAP_AFTER_INIT NonnullLockRefPtr SysFSLocalNetStats::must_create(SysFSDirectory const& parent_directory) +{ + return adopt_lock_ref_if_nonnull(new (nothrow) SysFSLocalNetStats(parent_directory)).release_nonnull(); +} + +ErrorOr SysFSLocalNetStats::try_generate(KBufferBuilder& builder) +{ + auto array = TRY(JsonArraySerializer<>::try_create(builder)); + TRY(LocalSocket::try_for_each([&array](auto& socket) -> ErrorOr { + 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 {}; +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Local.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Local.h new file mode 100644 index 00000000000..af6f5fb3780 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Local.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace Kernel { + +class SysFSLocalNetStats final : public SysFSGlobalInformation { +public: + virtual StringView name() const override { return "local"sv; } + static NonnullLockRefPtr must_create(SysFSDirectory const&); + +private: + explicit SysFSLocalNetStats(SysFSDirectory const&); + virtual ErrorOr try_generate(KBufferBuilder& builder) override; +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Route.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Route.cpp new file mode 100644 index 00000000000..2c33d864ff5 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Route.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include + +namespace Kernel { + +UNMAP_AFTER_INIT SysFSNetworkRouteStats::SysFSNetworkRouteStats(SysFSDirectory const& parent_directory) + : SysFSGlobalInformation(parent_directory) +{ +} + +UNMAP_AFTER_INIT NonnullLockRefPtr SysFSNetworkRouteStats::must_create(SysFSDirectory const& parent_directory) +{ + return adopt_lock_ref_if_nonnull(new (nothrow) SysFSNetworkRouteStats(parent_directory)).release_nonnull(); +} + +ErrorOr SysFSNetworkRouteStats::try_generate(KBufferBuilder& builder) +{ + auto array = TRY(JsonArraySerializer<>::try_create(builder)); + TRY(routing_table().with([&](auto const& table) -> ErrorOr { + 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 {}; +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Route.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Route.h new file mode 100644 index 00000000000..c8573751cbb --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/Route.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace Kernel { + +class SysFSNetworkRouteStats final : public SysFSGlobalInformation { +public: + virtual StringView name() const override { return "route"sv; } + static NonnullLockRefPtr must_create(SysFSDirectory const&); + +private: + explicit SysFSNetworkRouteStats(SysFSDirectory const&); + virtual ErrorOr try_generate(KBufferBuilder& builder) override; +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/TCP.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/TCP.cpp new file mode 100644 index 00000000000..ae294e60e70 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/TCP.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include +#include + +namespace Kernel { + +UNMAP_AFTER_INIT SysFSNetworkTCPStats::SysFSNetworkTCPStats(SysFSDirectory const& parent_directory) + : SysFSGlobalInformation(parent_directory) +{ +} + +UNMAP_AFTER_INIT NonnullLockRefPtr SysFSNetworkTCPStats::must_create(SysFSDirectory const& parent_directory) +{ + return adopt_lock_ref_if_nonnull(new (nothrow) SysFSNetworkTCPStats(parent_directory)).release_nonnull(); +} + +ErrorOr SysFSNetworkTCPStats::try_generate(KBufferBuilder& builder) +{ + auto array = TRY(JsonArraySerializer<>::try_create(builder)); + TRY(TCPSocket::try_for_each([&array](auto& socket) -> ErrorOr { + 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 {}; +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/TCP.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/TCP.h new file mode 100644 index 00000000000..a44644763c8 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/TCP.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace Kernel { + +class SysFSNetworkTCPStats final : public SysFSGlobalInformation { +public: + virtual StringView name() const override { return "tcp"sv; } + static NonnullLockRefPtr must_create(SysFSDirectory const&); + +private: + explicit SysFSNetworkTCPStats(SysFSDirectory const&); + virtual ErrorOr try_generate(KBufferBuilder& builder) override; +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/UDP.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/UDP.cpp new file mode 100644 index 00000000000..6a13a9dd97a --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/UDP.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include + +namespace Kernel { + +UNMAP_AFTER_INIT SysFSNetworkUDPStats::SysFSNetworkUDPStats(SysFSDirectory const& parent_directory) + : SysFSGlobalInformation(parent_directory) +{ +} + +UNMAP_AFTER_INIT NonnullLockRefPtr SysFSNetworkUDPStats::must_create(SysFSDirectory const& parent_directory) +{ + return adopt_lock_ref_if_nonnull(new (nothrow) SysFSNetworkUDPStats(parent_directory)).release_nonnull(); +} + +ErrorOr SysFSNetworkUDPStats::try_generate(KBufferBuilder& builder) +{ + auto array = TRY(JsonArraySerializer<>::try_create(builder)); + TRY(UDPSocket::try_for_each([&array](auto& socket) -> ErrorOr { + 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 {}; +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/UDP.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/UDP.h new file mode 100644 index 00000000000..59f79ad812f --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Network/UDP.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace Kernel { + +class SysFSNetworkUDPStats final : public SysFSGlobalInformation { +public: + virtual StringView name() const override { return "udp"sv; } + static NonnullLockRefPtr must_create(SysFSDirectory const&); + +private: + explicit SysFSNetworkUDPStats(SysFSDirectory const&); + virtual ErrorOr try_generate(KBufferBuilder& builder) override; +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Processes.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Processes.cpp new file mode 100644 index 00000000000..85bf3ca3cd9 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Processes.cpp @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Kernel { + +UNMAP_AFTER_INIT SysFSOverallProcesses::SysFSOverallProcesses(SysFSDirectory const& parent_directory) + : SysFSGlobalInformation(parent_directory) +{ +} + +UNMAP_AFTER_INIT NonnullLockRefPtr SysFSOverallProcesses::must_create(SysFSDirectory const& parent_directory) +{ + return adopt_lock_ref_if_nonnull(new (nothrow) SysFSOverallProcesses(parent_directory)).release_nonnull(); +} + +ErrorOr SysFSOverallProcesses::try_generate(KBufferBuilder& builder) +{ + auto json = TRY(JsonObjectSerializer<>::try_create(builder)); + + // Keep this in sync with CProcessStatistics. + auto build_process = [&](JsonArraySerializer& array, Process const& process) -> ErrorOr { + 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 { + 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 { + 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 { + 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 {}; +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Processes.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Processes.h new file mode 100644 index 00000000000..1995ce73d2e --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Processes.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace Kernel { + +class SysFSOverallProcesses final : public SysFSGlobalInformation { +public: + virtual StringView name() const override { return "processes"sv; } + + static NonnullLockRefPtr must_create(SysFSDirectory const& parent_directory); + +private: + explicit SysFSOverallProcesses(SysFSDirectory const& parent_directory); + virtual ErrorOr try_generate(KBufferBuilder& builder) override; +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Profile.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Profile.cpp new file mode 100644 index 00000000000..8d7565471a4 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Profile.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include + +namespace Kernel { + +UNMAP_AFTER_INIT SysFSProfile::SysFSProfile(SysFSDirectory const& parent_directory) + : SysFSGlobalInformation(parent_directory) +{ +} + +UNMAP_AFTER_INIT NonnullLockRefPtr SysFSProfile::must_create(SysFSDirectory const& parent_directory) +{ + return adopt_lock_ref_if_nonnull(new (nothrow) SysFSProfile(parent_directory)).release_nonnull(); +} + +ErrorOr 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; +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Profile.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Profile.h new file mode 100644 index 00000000000..b1bb21789ce --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Profile.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace Kernel { + +class SysFSProfile final : public SysFSGlobalInformation { +public: + virtual StringView name() const override { return "profile"sv; } + + static NonnullLockRefPtr must_create(SysFSDirectory const& parent_directory); + +private: + virtual mode_t permissions() const override; + + explicit SysFSProfile(SysFSDirectory const& parent_directory); + virtual ErrorOr try_generate(KBufferBuilder& builder) override; +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/SystemMode.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/SystemMode.cpp new file mode 100644 index 00000000000..36a4716fa3e --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/SystemMode.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include + +namespace Kernel { + +UNMAP_AFTER_INIT SysFSSystemMode::SysFSSystemMode(SysFSDirectory const& parent_directory) + : SysFSGlobalInformation(parent_directory) +{ +} + +UNMAP_AFTER_INIT NonnullLockRefPtr SysFSSystemMode::must_create(SysFSDirectory const& parent_directory) +{ + return adopt_lock_ref_if_nonnull(new (nothrow) SysFSSystemMode(parent_directory)).release_nonnull(); +} + +ErrorOr SysFSSystemMode::try_generate(KBufferBuilder& builder) +{ + TRY(builder.append(kernel_command_line().system_mode())); + TRY(builder.append('\n')); + return {}; +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/SystemMode.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/SystemMode.h new file mode 100644 index 00000000000..e137000cab8 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/SystemMode.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace Kernel { + +class SysFSSystemMode final : public SysFSGlobalInformation { +public: + virtual StringView name() const override { return "system_mode"sv; } + + static NonnullLockRefPtr must_create(SysFSDirectory const& parent_directory); + +private: + explicit SysFSSystemMode(SysFSDirectory const& parent_directory); + virtual ErrorOr try_generate(KBufferBuilder& builder) override; +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/SystemStatistics.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/SystemStatistics.cpp new file mode 100644 index 00000000000..6dbe8713a54 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/SystemStatistics.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include + +namespace Kernel { + +UNMAP_AFTER_INIT SysFSSystemStatistics::SysFSSystemStatistics(SysFSDirectory const& parent_directory) + : SysFSGlobalInformation(parent_directory) +{ +} + +UNMAP_AFTER_INIT NonnullLockRefPtr SysFSSystemStatistics::must_create(SysFSDirectory const& parent_directory) +{ + return adopt_lock_ref_if_nonnull(new (nothrow) SysFSSystemStatistics(parent_directory)).release_nonnull(); +} + +ErrorOr 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 {}; +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/SystemStatistics.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/SystemStatistics.h new file mode 100644 index 00000000000..6223ab36f57 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/SystemStatistics.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace Kernel { + +class SysFSSystemStatistics final : public SysFSGlobalInformation { +public: + virtual StringView name() const override { return "stats"sv; } + + static NonnullLockRefPtr must_create(SysFSDirectory const& parent_directory); + +private: + explicit SysFSSystemStatistics(SysFSDirectory const& parent_directory); + virtual ErrorOr try_generate(KBufferBuilder& builder) override; +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Uptime.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Uptime.cpp new file mode 100644 index 00000000000..e2bf3c4678e --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Uptime.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include + +namespace Kernel { + +UNMAP_AFTER_INIT SysFSUptime::SysFSUptime(SysFSDirectory const& parent_directory) + : SysFSGlobalInformation(parent_directory) +{ +} + +UNMAP_AFTER_INIT NonnullLockRefPtr SysFSUptime::must_create(SysFSDirectory const& parent_directory) +{ + return adopt_lock_ref_if_nonnull(new (nothrow) SysFSUptime(parent_directory)).release_nonnull(); +} + +ErrorOr SysFSUptime::try_generate(KBufferBuilder& builder) +{ + return builder.appendff("{}\n", TimeManagement::the().uptime_ms() / 1000); +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Uptime.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Uptime.h new file mode 100644 index 00000000000..4d5a77be803 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Uptime.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace Kernel { + +class SysFSUptime final : public SysFSGlobalInformation { +public: + virtual StringView name() const override { return "uptime"sv; } + static NonnullLockRefPtr must_create(SysFSDirectory const& parent_directory); + +private: + explicit SysFSUptime(SysFSDirectory const& parent_directory); + virtual ErrorOr try_generate(KBufferBuilder& builder) override; +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/BooleanVariable.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/BooleanVariable.cpp new file mode 100644 index 00000000000..e1a1b434862 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/BooleanVariable.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include + +namespace Kernel { + +ErrorOr SysFSSystemBoolean::try_generate(KBufferBuilder& builder) +{ + return builder.appendff("{}\n", static_cast(value())); +} + +ErrorOr 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 SysFSSystemBoolean::truncate(u64 size) +{ + if (size != 0) + return EPERM; + return {}; +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/BooleanVariable.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/BooleanVariable.h new file mode 100644 index 00000000000..a877fc8b9e5 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/BooleanVariable.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 try_generate(KBufferBuilder&) override final; + + // ^SysFSExposedComponent + virtual ErrorOr write_bytes(off_t, size_t, UserOrKernelBuffer const&, OpenFileDescription*) override final; + virtual mode_t permissions() const override final { return 0644; } + virtual ErrorOr truncate(u64) override final; +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/CapsLockRemap.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/CapsLockRemap.cpp new file mode 100644 index 00000000000..eec99b37a1b --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/CapsLockRemap.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include + +namespace Kernel { + +UNMAP_AFTER_INIT SysFSCapsLockRemap::SysFSCapsLockRemap(SysFSDirectory const& parent_directory) + : SysFSSystemBoolean(parent_directory) +{ +} + +UNMAP_AFTER_INIT NonnullLockRefPtr 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); +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/CapsLockRemap.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/CapsLockRemap.h new file mode 100644 index 00000000000..3cb0390bd0d --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/CapsLockRemap.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include + +namespace Kernel { + +class SysFSCapsLockRemap final : public SysFSSystemBoolean { +public: + virtual StringView name() const override { return "caps_lock_to_ctrl"sv; } + static NonnullLockRefPtr 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; +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/Directory.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/Directory.cpp new file mode 100644 index 00000000000..06d265347e9 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/Directory.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include +#include +#include + +namespace Kernel { + +UNMAP_AFTER_INIT NonnullLockRefPtr 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 { + 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) +{ +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/Directory.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/Directory.h new file mode 100644 index 00000000000..e8b8bc4a896 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/Directory.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2021, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include + +namespace Kernel { + +class SysFSGlobalKernelVariablesDirectory : public SysFSDirectory { +public: + static NonnullLockRefPtr must_create(SysFSDirectory const&); + virtual StringView name() const override { return "variables"sv; } + +private: + explicit SysFSGlobalKernelVariablesDirectory(SysFSDirectory const&); +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/DumpKmallocStack.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/DumpKmallocStack.cpp new file mode 100644 index 00000000000..f1645a1c8e9 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/DumpKmallocStack.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include + +namespace Kernel { + +UNMAP_AFTER_INIT SysFSDumpKmallocStacks::SysFSDumpKmallocStacks(SysFSDirectory const& parent_directory) + : SysFSSystemBoolean(parent_directory) +{ +} + +UNMAP_AFTER_INIT NonnullLockRefPtr 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; +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/DumpKmallocStack.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/DumpKmallocStack.h new file mode 100644 index 00000000000..21719e22f4f --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/DumpKmallocStack.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include + +namespace Kernel { + +class SysFSDumpKmallocStacks final : public SysFSSystemBoolean { +public: + virtual StringView name() const override { return "kmalloc_stacks"sv; } + static NonnullLockRefPtr 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; +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/UBSANDeadly.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/UBSANDeadly.cpp new file mode 100644 index 00000000000..44bd1a4d2d0 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/UBSANDeadly.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include + +namespace Kernel { + +UNMAP_AFTER_INIT SysFSUBSANDeadly::SysFSUBSANDeadly(SysFSDirectory const& parent_directory) + : SysFSSystemBoolean(parent_directory) +{ +} + +UNMAP_AFTER_INIT NonnullLockRefPtr 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; +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/UBSANDeadly.h b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/UBSANDeadly.h new file mode 100644 index 00000000000..6c18625f2dd --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Variables/UBSANDeadly.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include + +namespace Kernel { + +class SysFSUBSANDeadly final : public SysFSSystemBoolean { +public: + virtual StringView name() const override { return "ubsan_is_deadly"sv; } + static NonnullLockRefPtr must_create(SysFSDirectory const&); + +private: + virtual bool value() const override; + virtual void set_value(bool new_value) override; + + explicit SysFSUBSANDeadly(SysFSDirectory const&); +}; + +}