ProcFS.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/HashMap.h>
  8. #include <AK/Types.h>
  9. #include <Kernel/FileSystem/FileSystem.h>
  10. #include <Kernel/FileSystem/Inode.h>
  11. #include <Kernel/Forward.h>
  12. #include <Kernel/KBufferBuilder.h>
  13. #include <Kernel/Locking/Mutex.h>
  14. #include <Kernel/ProcessExposed.h>
  15. #include <Kernel/UnixTypes.h>
  16. namespace Kernel {
  17. class ProcFS final : public FileSystem {
  18. friend class ProcFSInode;
  19. friend class ProcFSDirectoryInode;
  20. friend class ProcFSProcessDirectoryInode;
  21. friend class ProcFSGlobalInode;
  22. friend class ProcFSAssociatedProcessInode;
  23. friend class ProcFSProcessSubDirectoryInode;
  24. public:
  25. virtual ~ProcFS() override;
  26. static KResultOr<NonnullRefPtr<ProcFS>> try_create();
  27. virtual KResult initialize() override;
  28. virtual StringView class_name() const override { return "ProcFS"sv; }
  29. virtual Inode& root_inode() override;
  30. private:
  31. ProcFS();
  32. RefPtr<ProcFSDirectoryInode> m_root_inode;
  33. };
  34. class ProcFSInode : public Inode {
  35. friend class ProcFS;
  36. public:
  37. virtual ~ProcFSInode() override;
  38. protected:
  39. ProcFSInode(const ProcFS&, InodeIndex);
  40. ProcFS& procfs() { return static_cast<ProcFS&>(Inode::fs()); }
  41. ProcFS const& procfs() const { return static_cast<ProcFS const&>(Inode::fs()); }
  42. // ^Inode
  43. virtual KResult attach(FileDescription& description) = 0;
  44. virtual void did_seek(FileDescription&, off_t) = 0;
  45. virtual void flush_metadata() override final;
  46. virtual KResultOr<NonnullRefPtr<Inode>> create_child(StringView name, mode_t, dev_t, UserID, GroupID) override final;
  47. virtual KResult add_child(Inode&, const StringView& name, mode_t) override final;
  48. virtual KResult remove_child(const StringView& name) override final;
  49. virtual KResult chmod(mode_t) override final;
  50. virtual KResult chown(UserID, GroupID) override final;
  51. virtual KResult truncate(u64) override final;
  52. };
  53. class ProcFSGlobalInode : public ProcFSInode {
  54. friend class ProcFS;
  55. public:
  56. static KResultOr<NonnullRefPtr<ProcFSGlobalInode>> try_create(const ProcFS&, const ProcFSExposedComponent&);
  57. virtual ~ProcFSGlobalInode() override {};
  58. StringView name() const;
  59. protected:
  60. ProcFSGlobalInode(const ProcFS&, const ProcFSExposedComponent&);
  61. // ^Inode
  62. virtual KResult attach(FileDescription& description) override final;
  63. virtual KResultOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, FileDescription*) const override final;
  64. virtual KResultOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer& buffer, FileDescription*) override final;
  65. virtual void did_seek(FileDescription&, off_t) override final;
  66. virtual InodeMetadata metadata() const override;
  67. virtual KResult traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const override;
  68. virtual KResultOr<NonnullRefPtr<Inode>> lookup(StringView) override;
  69. NonnullRefPtr<ProcFSExposedComponent> m_associated_component;
  70. };
  71. class ProcFSLinkInode : public ProcFSGlobalInode {
  72. friend class ProcFS;
  73. public:
  74. static KResultOr<NonnullRefPtr<ProcFSLinkInode>> try_create(const ProcFS&, const ProcFSExposedComponent&);
  75. protected:
  76. ProcFSLinkInode(const ProcFS&, const ProcFSExposedComponent&);
  77. virtual InodeMetadata metadata() const override;
  78. };
  79. class ProcFSDirectoryInode final : public ProcFSGlobalInode {
  80. friend class ProcFS;
  81. public:
  82. static KResultOr<NonnullRefPtr<ProcFSDirectoryInode>> try_create(const ProcFS&, const ProcFSExposedComponent&);
  83. virtual ~ProcFSDirectoryInode() override;
  84. protected:
  85. ProcFSDirectoryInode(const ProcFS&, const ProcFSExposedComponent&);
  86. // ^Inode
  87. virtual InodeMetadata metadata() const override;
  88. virtual KResult traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const override;
  89. virtual KResultOr<NonnullRefPtr<Inode>> lookup(StringView name) override;
  90. };
  91. class ProcFSProcessAssociatedInode : public ProcFSInode {
  92. friend class ProcFS;
  93. protected:
  94. ProcFSProcessAssociatedInode(const ProcFS&, ProcessID, InodeIndex);
  95. ProcessID associated_pid() const { return m_pid; }
  96. // ^Inode
  97. virtual KResultOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer& buffer, FileDescription*) override final;
  98. private:
  99. const ProcessID m_pid;
  100. };
  101. class ProcFSProcessDirectoryInode final : public ProcFSProcessAssociatedInode {
  102. friend class ProcFS;
  103. public:
  104. static KResultOr<NonnullRefPtr<ProcFSProcessDirectoryInode>> try_create(const ProcFS&, ProcessID);
  105. private:
  106. ProcFSProcessDirectoryInode(const ProcFS&, ProcessID);
  107. // ^Inode
  108. virtual KResult attach(FileDescription& description) override;
  109. virtual void did_seek(FileDescription&, off_t) override { }
  110. virtual InodeMetadata metadata() const override;
  111. virtual KResult traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const override;
  112. virtual KResultOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, FileDescription*) const override final;
  113. virtual KResultOr<NonnullRefPtr<Inode>> lookup(StringView name) override;
  114. };
  115. class ProcFSProcessSubDirectoryInode final : public ProcFSProcessAssociatedInode {
  116. friend class ProcFS;
  117. public:
  118. static KResultOr<NonnullRefPtr<ProcFSProcessSubDirectoryInode>> try_create(const ProcFS&, SegmentedProcFSIndex::ProcessSubDirectory, ProcessID);
  119. private:
  120. ProcFSProcessSubDirectoryInode(const ProcFS&, SegmentedProcFSIndex::ProcessSubDirectory, ProcessID);
  121. // ^Inode
  122. virtual KResult attach(FileDescription& description) override;
  123. virtual void did_seek(FileDescription&, off_t) override;
  124. virtual InodeMetadata metadata() const override;
  125. virtual KResult traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const override;
  126. virtual KResultOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, FileDescription*) const override final;
  127. virtual KResultOr<NonnullRefPtr<Inode>> lookup(StringView name) override;
  128. const SegmentedProcFSIndex::ProcessSubDirectory m_sub_directory_type;
  129. };
  130. class ProcFSProcessPropertyInode final : public ProcFSProcessAssociatedInode {
  131. friend class ProcFS;
  132. public:
  133. static KResultOr<NonnullRefPtr<ProcFSProcessPropertyInode>> try_create_for_file_description_link(const ProcFS&, unsigned, ProcessID);
  134. static KResultOr<NonnullRefPtr<ProcFSProcessPropertyInode>> try_create_for_thread_stack(const ProcFS&, ThreadID, ProcessID);
  135. static KResultOr<NonnullRefPtr<ProcFSProcessPropertyInode>> try_create_for_pid_property(const ProcFS&, SegmentedProcFSIndex::MainProcessProperty, ProcessID);
  136. private:
  137. ProcFSProcessPropertyInode(const ProcFS&, SegmentedProcFSIndex::MainProcessProperty, ProcessID);
  138. ProcFSProcessPropertyInode(const ProcFS&, ThreadID, ProcessID);
  139. ProcFSProcessPropertyInode(const ProcFS&, unsigned, ProcessID);
  140. // ^Inode
  141. virtual KResult attach(FileDescription& description) override;
  142. virtual void did_seek(FileDescription&, off_t) override;
  143. virtual InodeMetadata metadata() const override;
  144. virtual KResult traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const override;
  145. virtual KResultOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, FileDescription*) const override final;
  146. virtual KResultOr<NonnullRefPtr<Inode>> lookup(StringView name) override final;
  147. KResult refresh_data(FileDescription& description);
  148. KResult try_to_acquire_data(Process& process, KBufferBuilder& builder) const;
  149. const SegmentedProcFSIndex::ProcessSubDirectory m_parent_sub_directory_type;
  150. union {
  151. SegmentedProcFSIndex::MainProcessProperty property_type;
  152. unsigned property_index;
  153. } m_possible_data;
  154. mutable Mutex m_refresh_lock;
  155. };
  156. }