123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267 |
- /*
- * Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
- #pragma once
- #include <AK/Function.h>
- #include <AK/RefCounted.h>
- #include <AK/RefPtr.h>
- #include <AK/String.h>
- #include <AK/Types.h>
- #include <Kernel/Arch/x86/CPU.h>
- #include <Kernel/FileSystem/File.h>
- #include <Kernel/FileSystem/FileSystem.h>
- #include <Kernel/KBufferBuilder.h>
- #include <Kernel/KResult.h>
- #include <Kernel/Process.h>
- #include <Kernel/UserOrKernelBuffer.h>
- namespace Kernel {
- class ProcFSComponentRegistry {
- public:
- static ProcFSComponentRegistry& the();
- static void initialize();
- InodeIndex allocate_inode_index() const;
- ProcFSComponentRegistry();
- void register_new_bus_folder(ProcFSExposedDirectory&);
- const ProcFSBusDirectory& buses_folder() const;
- void register_new_process(Process&);
- void unregister_process(Process&);
- ProcFSRootDirectory& root_folder() { return *m_root_folder; }
- Lock& get_lock() { return m_lock; }
- private:
- Lock m_lock;
- NonnullRefPtr<ProcFSRootDirectory> m_root_folder;
- };
- class ProcFSExposedComponent : public RefCounted<ProcFSExposedComponent> {
- public:
- virtual KResultOr<size_t> entries_count() const { VERIFY_NOT_REACHED(); };
- StringView name() const { return m_name->view(); }
- virtual KResultOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer&, FileDescription*) const { VERIFY_NOT_REACHED(); }
- virtual KResult traverse_as_directory(unsigned, Function<bool(FileSystem::DirectoryEntryView const&)>) const { VERIFY_NOT_REACHED(); }
- virtual RefPtr<ProcFSExposedComponent> lookup(StringView) { VERIFY_NOT_REACHED(); };
- virtual KResultOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer&, FileDescription*) { return KResult(EROFS); }
- virtual size_t size() const { return 0; }
- virtual mode_t required_mode() const { return 0444; }
- virtual uid_t owner_user() const { return 0; }
- virtual gid_t owner_group() const { return 0; }
- time_t modified_time() const { return TimeManagement::now().to_timeval().tv_sec; }
- virtual void prepare_for_deletion() { }
- virtual KResult refresh_data(FileDescription&) const
- {
- return KSuccess;
- }
- virtual NonnullRefPtr<Inode> to_inode(const ProcFS& procfs_instance) const;
- InodeIndex component_index() const { return m_component_index; };
- virtual ~ProcFSExposedComponent() = default;
- protected:
- explicit ProcFSExposedComponent(StringView name);
- ProcFSExposedComponent(StringView name, InodeIndex preallocated_index);
- private:
- OwnPtr<KString> m_name;
- InodeIndex m_component_index {};
- };
- class ProcFSExposedDirectory
- : public ProcFSExposedComponent
- , public Weakable<ProcFSExposedDirectory> {
- friend class ProcFSProcessDirectory;
- friend class ProcFSComponentRegistry;
- public:
- virtual KResultOr<size_t> entries_count() const override { return m_components.size(); };
- virtual KResult traverse_as_directory(unsigned, Function<bool(FileSystem::DirectoryEntryView const&)>) const override;
- virtual RefPtr<ProcFSExposedComponent> lookup(StringView name) override;
- void add_component(const ProcFSExposedComponent&);
- virtual void prepare_for_deletion() override
- {
- for (auto& component : m_components) {
- component.prepare_for_deletion();
- }
- }
- virtual mode_t required_mode() const override { return 0555; }
- virtual NonnullRefPtr<Inode> to_inode(const ProcFS& procfs_instance) const override final;
- protected:
- explicit ProcFSExposedDirectory(StringView name);
- ProcFSExposedDirectory(StringView name, const ProcFSExposedDirectory& parent_folder);
- NonnullRefPtrVector<ProcFSExposedComponent> m_components;
- WeakPtr<ProcFSExposedDirectory> m_parent_folder;
- };
- class ProcFSExposedLink : public ProcFSExposedComponent {
- public:
- virtual NonnullRefPtr<Inode> to_inode(const ProcFS& procfs_instance) const override final;
- virtual KResultOr<size_t> read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, FileDescription* description) const override;
- protected:
- virtual bool acquire_link(KBufferBuilder& builder) = 0;
- explicit ProcFSExposedLink(StringView name);
- ProcFSExposedLink(StringView name, InodeIndex preallocated_index);
- mutable Lock m_lock { "ProcFSLink" };
- };
- class ProcFSProcessDirectory final
- : public ProcFSExposedDirectory {
- friend class ProcFSComponentRegistry;
- friend class ProcFSRootDirectory;
- friend class ProcFSProcessInformation;
- friend class ProcFSProcessPledge;
- friend class ProcFSProcessUnveil;
- friend class ProcFSProcessPerformanceEvents;
- friend class ProcFSProcessFileDescription;
- friend class ProcFSProcessFileDescriptions;
- friend class ProcFSProcessOverallFileDescriptions;
- friend class ProcFSProcessRoot;
- friend class ProcFSProcessVirtualMemory;
- friend class ProcFSProcessCurrentWorkDirectory;
- friend class ProcFSProcessBinary;
- friend class ProcFSProcessStacks;
- public:
- static NonnullRefPtr<ProcFSProcessDirectory> create(const Process&);
- RefPtr<Process> associated_process() { return m_associated_process; }
- virtual uid_t owner_user() const override { return m_associated_process ? m_associated_process->uid() : 0; }
- virtual gid_t owner_group() const override { return m_associated_process ? m_associated_process->gid() : 0; }
- virtual KResult refresh_data(FileDescription&) const override;
- virtual RefPtr<ProcFSExposedComponent> lookup(StringView name) override;
- virtual void prepare_for_deletion() override;
- private:
- void on_attach();
- IntrusiveListNode<ProcFSProcessDirectory, RefPtr<ProcFSProcessDirectory>> m_list_node;
- explicit ProcFSProcessDirectory(const Process&);
- RefPtr<Process> m_associated_process;
- };
- class ProcFSBusDirectory : public ProcFSExposedDirectory {
- friend class ProcFSComponentRegistry;
- public:
- static NonnullRefPtr<ProcFSBusDirectory> must_create(const ProcFSRootDirectory& parent_folder);
- private:
- ProcFSBusDirectory(const ProcFSRootDirectory& parent_folder);
- };
- class ProcFSRootDirectory final : public ProcFSExposedDirectory {
- friend class ProcFSComponentRegistry;
- public:
- virtual RefPtr<ProcFSExposedComponent> lookup(StringView name) override;
- RefPtr<ProcFSProcessDirectory> process_folder_for(Process&);
- static NonnullRefPtr<ProcFSRootDirectory> must_create();
- virtual ~ProcFSRootDirectory();
- private:
- virtual KResult traverse_as_directory(unsigned, Function<bool(FileSystem::DirectoryEntryView const&)>) const override;
- ProcFSRootDirectory();
- RefPtr<ProcFSBusDirectory> m_buses_folder;
- IntrusiveList<ProcFSProcessDirectory, RefPtr<ProcFSProcessDirectory>, &ProcFSProcessDirectory::m_list_node> m_process_folders;
- };
- class ProcFSGlobalInformation : public ProcFSExposedComponent {
- public:
- virtual ~ProcFSGlobalInformation() override {};
- virtual KResultOr<size_t> read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, FileDescription* description) const override;
- virtual mode_t required_mode() const override { return 0444; }
- protected:
- explicit ProcFSGlobalInformation(StringView name)
- : ProcFSExposedComponent(name)
- {
- }
- virtual KResult refresh_data(FileDescription&) const override;
- virtual bool output(KBufferBuilder& builder) = 0;
- mutable SpinLock<u8> m_refresh_lock;
- };
- class ProcFSSystemBoolean : public ProcFSGlobalInformation {
- public:
- virtual bool value() const = 0;
- virtual void set_value(bool new_value) = 0;
- protected:
- explicit ProcFSSystemBoolean(StringView name)
- : ProcFSGlobalInformation(name)
- {
- }
- virtual bool output(KBufferBuilder& builder) override
- {
- builder.appendff("{}\n", value());
- return true;
- }
- };
- class ProcFSProcessInformation : public ProcFSExposedComponent {
- public:
- virtual ~ProcFSProcessInformation() override {};
- virtual KResultOr<size_t> read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, FileDescription* description) const override;
- virtual uid_t owner_user() const override
- {
- auto parent_folder = m_parent_folder.strong_ref();
- if (!parent_folder)
- return false;
- auto process = parent_folder->associated_process();
- if (!process)
- return false;
- return process->uid();
- }
- virtual gid_t owner_group() const override
- {
- auto parent_folder = m_parent_folder.strong_ref();
- if (!parent_folder)
- return false;
- auto process = parent_folder->associated_process();
- if (!process)
- return false;
- return process->gid();
- }
- protected:
- ProcFSProcessInformation(StringView name, const ProcFSProcessDirectory& process_folder)
- : ProcFSExposedComponent(name)
- , m_parent_folder(process_folder)
- {
- }
- virtual KResult refresh_data(FileDescription&) const override;
- virtual bool output(KBufferBuilder& builder) = 0;
- WeakPtr<ProcFSProcessDirectory> m_parent_folder;
- mutable SpinLock<u8> m_refresh_lock;
- };
- }
|