ProcessExposed.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /*
  2. * Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Function.h>
  8. #include <AK/RefCounted.h>
  9. #include <AK/RefPtr.h>
  10. #include <AK/String.h>
  11. #include <AK/Types.h>
  12. #include <Kernel/API/KResult.h>
  13. #include <Kernel/Arch/x86/CPU.h>
  14. #include <Kernel/FileSystem/File.h>
  15. #include <Kernel/FileSystem/FileDescription.h>
  16. #include <Kernel/FileSystem/FileSystem.h>
  17. #include <Kernel/KBufferBuilder.h>
  18. #include <Kernel/UserOrKernelBuffer.h>
  19. namespace Kernel {
  20. namespace SegmentedProcFSIndex {
  21. enum class MainProcessProperty {
  22. Reserved = 0,
  23. Unveil = 1,
  24. Pledge = 2,
  25. FileDescriptions = 3,
  26. BinaryLink = 4,
  27. CurrentWorkDirectoryLink = 5,
  28. PerformanceEvents = 6,
  29. VirtualMemoryStats = 7,
  30. };
  31. enum class ProcessSubDirectory {
  32. Reserved = 0,
  33. FileDescriptions = 1,
  34. Stacks = 2,
  35. };
  36. void read_segments(u32& primary, ProcessSubDirectory& sub_directory, MainProcessProperty& property);
  37. InodeIndex build_segmented_index_for_pid_directory(ProcessID);
  38. InodeIndex build_segmented_index_for_sub_directory(ProcessID, ProcessSubDirectory sub_directory);
  39. InodeIndex build_segmented_index_for_main_property(ProcessID, ProcessSubDirectory sub_directory, MainProcessProperty property);
  40. InodeIndex build_segmented_index_for_main_property_in_pid_directory(ProcessID, MainProcessProperty property);
  41. InodeIndex build_segmented_index_for_thread_stack(ProcessID, ThreadID);
  42. InodeIndex build_segmented_index_for_file_description(ProcessID, unsigned);
  43. }
  44. class ProcFSComponentRegistry {
  45. public:
  46. static ProcFSComponentRegistry& the();
  47. static void initialize();
  48. ProcFSComponentRegistry();
  49. ProcFSRootDirectory& root_directory() { return *m_root_directory; }
  50. Mutex& get_lock() { return m_lock; }
  51. private:
  52. Mutex m_lock;
  53. NonnullRefPtr<ProcFSRootDirectory> m_root_directory;
  54. };
  55. class ProcFSExposedComponent : public RefCounted<ProcFSExposedComponent> {
  56. public:
  57. StringView name() const { return m_name->view(); }
  58. virtual KResultOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer&, FileDescription*) const { VERIFY_NOT_REACHED(); }
  59. virtual KResult traverse_as_directory(unsigned, Function<bool(FileSystem::DirectoryEntryView const&)>) const { VERIFY_NOT_REACHED(); }
  60. virtual KResultOr<NonnullRefPtr<ProcFSExposedComponent>> lookup(StringView) { VERIFY_NOT_REACHED(); };
  61. virtual KResultOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer&, FileDescription*) { return KResult(EROFS); }
  62. virtual mode_t required_mode() const { return 0444; }
  63. virtual UserID owner_user() const { return 0; }
  64. virtual GroupID owner_group() const { return 0; }
  65. time_t modified_time() const { return TimeManagement::now().to_timeval().tv_sec; }
  66. virtual void prepare_for_deletion() { }
  67. virtual KResult refresh_data(FileDescription&) const
  68. {
  69. return KSuccess;
  70. }
  71. virtual KResultOr<NonnullRefPtr<Inode>> to_inode(const ProcFS& procfs_instance) const;
  72. virtual InodeIndex component_index() const { return m_component_index; }
  73. virtual ~ProcFSExposedComponent() = default;
  74. protected:
  75. ProcFSExposedComponent();
  76. explicit ProcFSExposedComponent(StringView name);
  77. private:
  78. OwnPtr<KString> m_name;
  79. InodeIndex m_component_index {};
  80. };
  81. class ProcFSExposedDirectory
  82. : public ProcFSExposedComponent
  83. , public Weakable<ProcFSExposedDirectory> {
  84. friend class ProcFSComponentRegistry;
  85. public:
  86. virtual KResult traverse_as_directory(unsigned, Function<bool(FileSystem::DirectoryEntryView const&)>) const override;
  87. virtual KResultOr<NonnullRefPtr<ProcFSExposedComponent>> lookup(StringView name) override;
  88. void add_component(const ProcFSExposedComponent&);
  89. virtual void prepare_for_deletion() override
  90. {
  91. for (auto& component : m_components) {
  92. component.prepare_for_deletion();
  93. }
  94. }
  95. virtual mode_t required_mode() const override { return 0555; }
  96. virtual KResultOr<NonnullRefPtr<Inode>> to_inode(const ProcFS& procfs_instance) const override final;
  97. protected:
  98. explicit ProcFSExposedDirectory(StringView name);
  99. ProcFSExposedDirectory(StringView name, const ProcFSExposedDirectory& parent_directory);
  100. NonnullRefPtrVector<ProcFSExposedComponent> m_components;
  101. WeakPtr<ProcFSExposedDirectory> m_parent_directory;
  102. };
  103. class ProcFSExposedLink : public ProcFSExposedComponent {
  104. public:
  105. virtual KResultOr<NonnullRefPtr<Inode>> to_inode(const ProcFS& procfs_instance) const override final;
  106. virtual KResultOr<size_t> read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, FileDescription* description) const override;
  107. protected:
  108. virtual bool acquire_link(KBufferBuilder& builder) = 0;
  109. explicit ProcFSExposedLink(StringView name);
  110. mutable Mutex m_lock { "ProcFSLink" };
  111. };
  112. class ProcFSRootDirectory final : public ProcFSExposedDirectory {
  113. friend class ProcFSComponentRegistry;
  114. public:
  115. virtual KResultOr<NonnullRefPtr<ProcFSExposedComponent>> lookup(StringView name) override;
  116. static NonnullRefPtr<ProcFSRootDirectory> must_create();
  117. virtual ~ProcFSRootDirectory();
  118. private:
  119. virtual KResult traverse_as_directory(unsigned, Function<bool(FileSystem::DirectoryEntryView const&)>) const override;
  120. ProcFSRootDirectory();
  121. };
  122. struct ProcFSInodeData : public FileDescriptionData {
  123. OwnPtr<KBuffer> buffer;
  124. };
  125. class ProcFSGlobalInformation : public ProcFSExposedComponent {
  126. public:
  127. virtual ~ProcFSGlobalInformation() override {};
  128. virtual KResultOr<size_t> read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, FileDescription* description) const override;
  129. virtual mode_t required_mode() const override { return 0444; }
  130. protected:
  131. explicit ProcFSGlobalInformation(StringView name)
  132. : ProcFSExposedComponent(name)
  133. {
  134. }
  135. virtual KResult refresh_data(FileDescription&) const override;
  136. virtual bool output(KBufferBuilder& builder) = 0;
  137. mutable Mutex m_refresh_lock;
  138. };
  139. class ProcFSSystemBoolean : public ProcFSGlobalInformation {
  140. public:
  141. virtual bool value() const = 0;
  142. virtual void set_value(bool new_value) = 0;
  143. protected:
  144. explicit ProcFSSystemBoolean(StringView name)
  145. : ProcFSGlobalInformation(name)
  146. {
  147. }
  148. virtual bool output(KBufferBuilder& builder) override
  149. {
  150. builder.appendff("{}\n", value());
  151. return true;
  152. }
  153. };
  154. }