ProcessExposed.h 6.7 KB

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