GlobalProcessExposed.cpp 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095
  1. /*
  2. * Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
  3. * Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include <AK/JsonObjectSerializer.h>
  8. #include <AK/Try.h>
  9. #include <AK/UBSanitizer.h>
  10. #include <Kernel/Arch/InterruptDisabler.h>
  11. #include <Kernel/Arch/InterruptManagement.h>
  12. #include <Kernel/Arch/x86/ProcessorInfo.h>
  13. #include <Kernel/Bus/PCI/API.h>
  14. #include <Kernel/Bus/PCI/Access.h>
  15. #include <Kernel/CommandLine.h>
  16. #include <Kernel/Devices/DeviceManagement.h>
  17. #include <Kernel/Devices/HID/HIDManagement.h>
  18. #include <Kernel/FileSystem/Custody.h>
  19. #include <Kernel/FileSystem/FileBackedFileSystem.h>
  20. #include <Kernel/FileSystem/OpenFileDescription.h>
  21. #include <Kernel/Heap/kmalloc.h>
  22. #include <Kernel/Interrupts/GenericInterruptHandler.h>
  23. #include <Kernel/KBufferBuilder.h>
  24. #include <Kernel/Net/LocalSocket.h>
  25. #include <Kernel/Net/NetworkingManagement.h>
  26. #include <Kernel/Net/Routing.h>
  27. #include <Kernel/Net/TCPSocket.h>
  28. #include <Kernel/Net/UDPSocket.h>
  29. #include <Kernel/Process.h>
  30. #include <Kernel/ProcessExposed.h>
  31. #include <Kernel/Scheduler.h>
  32. #include <Kernel/Sections.h>
  33. #include <Kernel/TTY/TTY.h>
  34. namespace Kernel {
  35. class ProcFSAdapters final : public ProcFSGlobalInformation {
  36. public:
  37. static NonnullRefPtr<ProcFSAdapters> must_create();
  38. private:
  39. ProcFSAdapters();
  40. virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override
  41. {
  42. auto array = TRY(JsonArraySerializer<>::try_create(builder));
  43. TRY(NetworkingManagement::the().try_for_each([&array](auto& adapter) -> ErrorOr<void> {
  44. auto obj = TRY(array.add_object());
  45. TRY(obj.add("name"sv, adapter.name()));
  46. TRY(obj.add("class_name"sv, adapter.class_name()));
  47. auto mac_address = TRY(adapter.mac_address().to_string());
  48. TRY(obj.add("mac_address"sv, mac_address->view()));
  49. if (!adapter.ipv4_address().is_zero()) {
  50. auto ipv4_address = TRY(adapter.ipv4_address().to_string());
  51. TRY(obj.add("ipv4_address"sv, ipv4_address->view()));
  52. auto ipv4_netmask = TRY(adapter.ipv4_netmask().to_string());
  53. TRY(obj.add("ipv4_netmask"sv, ipv4_netmask->view()));
  54. }
  55. TRY(obj.add("packets_in"sv, adapter.packets_in()));
  56. TRY(obj.add("bytes_in"sv, adapter.bytes_in()));
  57. TRY(obj.add("packets_out"sv, adapter.packets_out()));
  58. TRY(obj.add("bytes_out"sv, adapter.bytes_out()));
  59. TRY(obj.add("link_up"sv, adapter.link_up()));
  60. TRY(obj.add("link_speed"sv, adapter.link_speed()));
  61. TRY(obj.add("link_full_duplex"sv, adapter.link_full_duplex()));
  62. TRY(obj.add("mtu"sv, adapter.mtu()));
  63. TRY(obj.finish());
  64. return {};
  65. }));
  66. TRY(array.finish());
  67. return {};
  68. }
  69. };
  70. class ProcFSARP final : public ProcFSGlobalInformation {
  71. public:
  72. static NonnullRefPtr<ProcFSARP> must_create();
  73. private:
  74. ProcFSARP();
  75. virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override
  76. {
  77. auto array = TRY(JsonArraySerializer<>::try_create(builder));
  78. TRY(arp_table().with([&](auto const& table) -> ErrorOr<void> {
  79. for (auto& it : table) {
  80. auto obj = TRY(array.add_object());
  81. auto mac_address = TRY(it.value.to_string());
  82. TRY(obj.add("mac_address"sv, mac_address->view()));
  83. auto ip_address = TRY(it.key.to_string());
  84. TRY(obj.add("ip_address"sv, ip_address->view()));
  85. TRY(obj.finish());
  86. }
  87. return {};
  88. }));
  89. TRY(array.finish());
  90. return {};
  91. }
  92. };
  93. class ProcFSRoute final : public ProcFSGlobalInformation {
  94. public:
  95. static NonnullRefPtr<ProcFSRoute> must_create();
  96. private:
  97. ProcFSRoute();
  98. virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override
  99. {
  100. auto array = TRY(JsonArraySerializer<>::try_create(builder));
  101. TRY(routing_table().with([&](auto const& table) -> ErrorOr<void> {
  102. for (auto& it : table) {
  103. auto obj = TRY(array.add_object());
  104. auto destination = TRY(it.destination.to_string());
  105. TRY(obj.add("destination"sv, destination->view()));
  106. auto gateway = TRY(it.gateway.to_string());
  107. TRY(obj.add("gateway"sv, gateway->view()));
  108. auto netmask = TRY(it.netmask.to_string());
  109. TRY(obj.add("genmask"sv, netmask->view()));
  110. TRY(obj.add("flags"sv, it.flags));
  111. TRY(obj.add("interface"sv, it.adapter->name()));
  112. TRY(obj.finish());
  113. }
  114. return {};
  115. }));
  116. TRY(array.finish());
  117. return {};
  118. }
  119. };
  120. class ProcFSTCP final : public ProcFSGlobalInformation {
  121. public:
  122. static NonnullRefPtr<ProcFSTCP> must_create();
  123. private:
  124. ProcFSTCP();
  125. virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override
  126. {
  127. auto array = TRY(JsonArraySerializer<>::try_create(builder));
  128. TRY(TCPSocket::try_for_each([&array](auto& socket) -> ErrorOr<void> {
  129. auto obj = TRY(array.add_object());
  130. auto local_address = TRY(socket.local_address().to_string());
  131. TRY(obj.add("local_address"sv, local_address->view()));
  132. TRY(obj.add("local_port"sv, socket.local_port()));
  133. auto peer_address = TRY(socket.peer_address().to_string());
  134. TRY(obj.add("peer_address"sv, peer_address->view()));
  135. TRY(obj.add("peer_port"sv, socket.peer_port()));
  136. TRY(obj.add("state"sv, TCPSocket::to_string(socket.state())));
  137. TRY(obj.add("ack_number"sv, socket.ack_number()));
  138. TRY(obj.add("sequence_number"sv, socket.sequence_number()));
  139. TRY(obj.add("packets_in"sv, socket.packets_in()));
  140. TRY(obj.add("bytes_in"sv, socket.bytes_in()));
  141. TRY(obj.add("packets_out"sv, socket.packets_out()));
  142. TRY(obj.add("bytes_out"sv, socket.bytes_out()));
  143. if (Process::current().is_superuser() || Process::current().uid() == socket.origin_uid()) {
  144. TRY(obj.add("origin_pid"sv, socket.origin_pid().value()));
  145. TRY(obj.add("origin_uid"sv, socket.origin_uid().value()));
  146. TRY(obj.add("origin_gid"sv, socket.origin_gid().value()));
  147. }
  148. TRY(obj.finish());
  149. return {};
  150. }));
  151. TRY(array.finish());
  152. return {};
  153. }
  154. };
  155. class ProcFSLocalNet final : public ProcFSGlobalInformation {
  156. public:
  157. static NonnullRefPtr<ProcFSLocalNet> must_create();
  158. private:
  159. ProcFSLocalNet();
  160. virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override
  161. {
  162. auto array = TRY(JsonArraySerializer<>::try_create(builder));
  163. TRY(LocalSocket::try_for_each([&array](auto& socket) -> ErrorOr<void> {
  164. auto obj = TRY(array.add_object());
  165. TRY(obj.add("path"sv, socket.socket_path()));
  166. TRY(obj.add("origin_pid"sv, socket.origin_pid().value()));
  167. TRY(obj.add("origin_uid"sv, socket.origin_uid().value()));
  168. TRY(obj.add("origin_gid"sv, socket.origin_gid().value()));
  169. TRY(obj.add("acceptor_pid"sv, socket.acceptor_pid().value()));
  170. TRY(obj.add("acceptor_uid"sv, socket.acceptor_uid().value()));
  171. TRY(obj.add("acceptor_gid"sv, socket.acceptor_gid().value()));
  172. TRY(obj.finish());
  173. return {};
  174. }));
  175. TRY(array.finish());
  176. return {};
  177. }
  178. };
  179. class ProcFSUDP final : public ProcFSGlobalInformation {
  180. public:
  181. static NonnullRefPtr<ProcFSUDP> must_create();
  182. private:
  183. ProcFSUDP();
  184. virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override
  185. {
  186. auto array = TRY(JsonArraySerializer<>::try_create(builder));
  187. TRY(UDPSocket::try_for_each([&array](auto& socket) -> ErrorOr<void> {
  188. auto obj = TRY(array.add_object());
  189. auto local_address = TRY(socket.local_address().to_string());
  190. TRY(obj.add("local_address"sv, local_address->view()));
  191. TRY(obj.add("local_port"sv, socket.local_port()));
  192. auto peer_address = TRY(socket.peer_address().to_string());
  193. TRY(obj.add("peer_address"sv, peer_address->view()));
  194. TRY(obj.add("peer_port"sv, socket.peer_port()));
  195. if (Process::current().is_superuser() || Process::current().uid() == socket.origin_uid()) {
  196. TRY(obj.add("origin_pid"sv, socket.origin_pid().value()));
  197. TRY(obj.add("origin_uid"sv, socket.origin_uid().value()));
  198. TRY(obj.add("origin_gid"sv, socket.origin_gid().value()));
  199. }
  200. TRY(obj.finish());
  201. return {};
  202. }));
  203. TRY(array.finish());
  204. return {};
  205. }
  206. };
  207. class ProcFSNetworkDirectory : public ProcFSExposedDirectory {
  208. public:
  209. static NonnullRefPtr<ProcFSNetworkDirectory> must_create(ProcFSRootDirectory const& parent_directory);
  210. private:
  211. ProcFSNetworkDirectory(ProcFSRootDirectory const& parent_directory);
  212. };
  213. class ProcFSSystemDirectory : public ProcFSExposedDirectory {
  214. public:
  215. static NonnullRefPtr<ProcFSSystemDirectory> must_create(ProcFSRootDirectory const& parent_directory);
  216. private:
  217. ProcFSSystemDirectory(ProcFSRootDirectory const& parent_directory);
  218. };
  219. UNMAP_AFTER_INIT NonnullRefPtr<ProcFSAdapters> ProcFSAdapters::must_create()
  220. {
  221. return adopt_ref_if_nonnull(new (nothrow) ProcFSAdapters).release_nonnull();
  222. }
  223. UNMAP_AFTER_INIT NonnullRefPtr<ProcFSARP> ProcFSARP::must_create()
  224. {
  225. return adopt_ref_if_nonnull(new (nothrow) ProcFSARP).release_nonnull();
  226. }
  227. UNMAP_AFTER_INIT NonnullRefPtr<ProcFSRoute> ProcFSRoute::must_create()
  228. {
  229. return adopt_ref_if_nonnull(new (nothrow) ProcFSRoute).release_nonnull();
  230. }
  231. UNMAP_AFTER_INIT NonnullRefPtr<ProcFSTCP> ProcFSTCP::must_create()
  232. {
  233. return adopt_ref_if_nonnull(new (nothrow) ProcFSTCP).release_nonnull();
  234. }
  235. UNMAP_AFTER_INIT NonnullRefPtr<ProcFSLocalNet> ProcFSLocalNet::must_create()
  236. {
  237. return adopt_ref_if_nonnull(new (nothrow) ProcFSLocalNet).release_nonnull();
  238. }
  239. UNMAP_AFTER_INIT NonnullRefPtr<ProcFSUDP> ProcFSUDP::must_create()
  240. {
  241. return adopt_ref_if_nonnull(new (nothrow) ProcFSUDP).release_nonnull();
  242. }
  243. UNMAP_AFTER_INIT NonnullRefPtr<ProcFSNetworkDirectory> ProcFSNetworkDirectory::must_create(ProcFSRootDirectory const& parent_directory)
  244. {
  245. auto directory = adopt_ref(*new (nothrow) ProcFSNetworkDirectory(parent_directory));
  246. directory->m_components.append(ProcFSAdapters::must_create());
  247. directory->m_components.append(ProcFSARP::must_create());
  248. directory->m_components.append(ProcFSRoute::must_create());
  249. directory->m_components.append(ProcFSTCP::must_create());
  250. directory->m_components.append(ProcFSLocalNet::must_create());
  251. directory->m_components.append(ProcFSUDP::must_create());
  252. return directory;
  253. }
  254. UNMAP_AFTER_INIT ProcFSAdapters::ProcFSAdapters()
  255. : ProcFSGlobalInformation("adapters"sv)
  256. {
  257. }
  258. UNMAP_AFTER_INIT ProcFSARP::ProcFSARP()
  259. : ProcFSGlobalInformation("arp"sv)
  260. {
  261. }
  262. UNMAP_AFTER_INIT ProcFSRoute::ProcFSRoute()
  263. : ProcFSGlobalInformation("route"sv)
  264. {
  265. }
  266. UNMAP_AFTER_INIT ProcFSTCP::ProcFSTCP()
  267. : ProcFSGlobalInformation("tcp"sv)
  268. {
  269. }
  270. UNMAP_AFTER_INIT ProcFSLocalNet::ProcFSLocalNet()
  271. : ProcFSGlobalInformation("local"sv)
  272. {
  273. }
  274. UNMAP_AFTER_INIT ProcFSUDP::ProcFSUDP()
  275. : ProcFSGlobalInformation("udp"sv)
  276. {
  277. }
  278. UNMAP_AFTER_INIT ProcFSNetworkDirectory::ProcFSNetworkDirectory(ProcFSRootDirectory const& parent_directory)
  279. : ProcFSExposedDirectory("net"sv, parent_directory)
  280. {
  281. }
  282. class ProcFSDumpKmallocStacks : public ProcFSSystemBoolean {
  283. public:
  284. static NonnullRefPtr<ProcFSDumpKmallocStacks> must_create(ProcFSSystemDirectory const&);
  285. virtual bool value() const override
  286. {
  287. MutexLocker locker(m_lock);
  288. return g_dump_kmalloc_stacks;
  289. }
  290. virtual void set_value(bool new_value) override
  291. {
  292. MutexLocker locker(m_lock);
  293. g_dump_kmalloc_stacks = new_value;
  294. }
  295. private:
  296. ProcFSDumpKmallocStacks();
  297. mutable Mutex m_lock;
  298. };
  299. class ProcFSUBSanDeadly : public ProcFSSystemBoolean {
  300. public:
  301. static NonnullRefPtr<ProcFSUBSanDeadly> must_create(ProcFSSystemDirectory const&);
  302. virtual bool value() const override { return AK::UBSanitizer::g_ubsan_is_deadly; }
  303. virtual void set_value(bool new_value) override { AK::UBSanitizer::g_ubsan_is_deadly = new_value; }
  304. private:
  305. ProcFSUBSanDeadly();
  306. };
  307. class ProcFSCapsLockRemap : public ProcFSSystemBoolean {
  308. public:
  309. static NonnullRefPtr<ProcFSCapsLockRemap> must_create(ProcFSSystemDirectory const&);
  310. virtual bool value() const override
  311. {
  312. MutexLocker locker(m_lock);
  313. return g_caps_lock_remapped_to_ctrl.load();
  314. }
  315. virtual void set_value(bool new_value) override
  316. {
  317. MutexLocker locker(m_lock);
  318. g_caps_lock_remapped_to_ctrl.exchange(new_value);
  319. }
  320. private:
  321. ProcFSCapsLockRemap();
  322. mutable Mutex m_lock;
  323. };
  324. UNMAP_AFTER_INIT NonnullRefPtr<ProcFSDumpKmallocStacks> ProcFSDumpKmallocStacks::must_create(ProcFSSystemDirectory const&)
  325. {
  326. return adopt_ref_if_nonnull(new (nothrow) ProcFSDumpKmallocStacks).release_nonnull();
  327. }
  328. UNMAP_AFTER_INIT NonnullRefPtr<ProcFSUBSanDeadly> ProcFSUBSanDeadly::must_create(ProcFSSystemDirectory const&)
  329. {
  330. return adopt_ref_if_nonnull(new (nothrow) ProcFSUBSanDeadly).release_nonnull();
  331. }
  332. UNMAP_AFTER_INIT NonnullRefPtr<ProcFSCapsLockRemap> ProcFSCapsLockRemap::must_create(ProcFSSystemDirectory const&)
  333. {
  334. return adopt_ref_if_nonnull(new (nothrow) ProcFSCapsLockRemap).release_nonnull();
  335. }
  336. UNMAP_AFTER_INIT ProcFSDumpKmallocStacks::ProcFSDumpKmallocStacks()
  337. : ProcFSSystemBoolean("kmalloc_stacks"sv)
  338. {
  339. }
  340. UNMAP_AFTER_INIT ProcFSUBSanDeadly::ProcFSUBSanDeadly()
  341. : ProcFSSystemBoolean("ubsan_is_deadly"sv)
  342. {
  343. }
  344. UNMAP_AFTER_INIT ProcFSCapsLockRemap::ProcFSCapsLockRemap()
  345. : ProcFSSystemBoolean("caps_lock_to_ctrl"sv)
  346. {
  347. }
  348. class ProcFSSelfProcessDirectory final : public ProcFSExposedLink {
  349. public:
  350. static NonnullRefPtr<ProcFSSelfProcessDirectory> must_create();
  351. private:
  352. ProcFSSelfProcessDirectory();
  353. virtual bool acquire_link(KBufferBuilder& builder) override
  354. {
  355. return !builder.appendff("{}", Process::current().pid().value()).is_error();
  356. }
  357. };
  358. class ProcFSDiskUsage final : public ProcFSGlobalInformation {
  359. public:
  360. static NonnullRefPtr<ProcFSDiskUsage> must_create();
  361. private:
  362. ProcFSDiskUsage();
  363. virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override
  364. {
  365. auto array = TRY(JsonArraySerializer<>::try_create(builder));
  366. TRY(VirtualFileSystem::the().for_each_mount([&array](auto& mount) -> ErrorOr<void> {
  367. auto& fs = mount.guest_fs();
  368. auto fs_object = TRY(array.add_object());
  369. TRY(fs_object.add("class_name"sv, fs.class_name()));
  370. TRY(fs_object.add("total_block_count"sv, fs.total_block_count()));
  371. TRY(fs_object.add("free_block_count"sv, fs.free_block_count()));
  372. TRY(fs_object.add("total_inode_count"sv, fs.total_inode_count()));
  373. TRY(fs_object.add("free_inode_count"sv, fs.free_inode_count()));
  374. auto mount_point = TRY(mount.absolute_path());
  375. TRY(fs_object.add("mount_point"sv, mount_point->view()));
  376. TRY(fs_object.add("block_size"sv, static_cast<u64>(fs.block_size())));
  377. TRY(fs_object.add("readonly"sv, fs.is_readonly()));
  378. TRY(fs_object.add("mount_flags"sv, mount.flags()));
  379. if (fs.is_file_backed()) {
  380. auto pseudo_path = TRY(static_cast<const FileBackedFileSystem&>(fs).file_description().pseudo_path());
  381. TRY(fs_object.add("source"sv, pseudo_path->view()));
  382. } else {
  383. TRY(fs_object.add("source"sv, "none"));
  384. }
  385. TRY(fs_object.finish());
  386. return {};
  387. }));
  388. TRY(array.finish());
  389. return {};
  390. }
  391. };
  392. class ProcFSMemoryStatus final : public ProcFSGlobalInformation {
  393. public:
  394. static NonnullRefPtr<ProcFSMemoryStatus> must_create();
  395. private:
  396. ProcFSMemoryStatus();
  397. virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override
  398. {
  399. InterruptDisabler disabler;
  400. kmalloc_stats stats;
  401. get_kmalloc_stats(stats);
  402. auto system_memory = MM.get_system_memory_info();
  403. auto json = TRY(JsonObjectSerializer<>::try_create(builder));
  404. TRY(json.add("kmalloc_allocated"sv, stats.bytes_allocated));
  405. TRY(json.add("kmalloc_available"sv, stats.bytes_free));
  406. TRY(json.add("physical_allocated"sv, system_memory.physical_pages_used));
  407. TRY(json.add("physical_available"sv, system_memory.physical_pages - system_memory.physical_pages_used));
  408. TRY(json.add("physical_committed"sv, system_memory.physical_pages_committed));
  409. TRY(json.add("physical_uncommitted"sv, system_memory.physical_pages_uncommitted));
  410. TRY(json.add("kmalloc_call_count"sv, stats.kmalloc_call_count));
  411. TRY(json.add("kfree_call_count"sv, stats.kfree_call_count));
  412. TRY(json.finish());
  413. return {};
  414. }
  415. };
  416. class ProcFSSystemStatistics final : public ProcFSGlobalInformation {
  417. public:
  418. static NonnullRefPtr<ProcFSSystemStatistics> must_create();
  419. private:
  420. ProcFSSystemStatistics();
  421. virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override
  422. {
  423. auto json = TRY(JsonObjectSerializer<>::try_create(builder));
  424. auto total_time_scheduled = Scheduler::get_total_time_scheduled();
  425. TRY(json.add("total_time"sv, total_time_scheduled.total));
  426. TRY(json.add("kernel_time"sv, total_time_scheduled.total_kernel));
  427. TRY(json.add("user_time"sv, total_time_scheduled.total - total_time_scheduled.total_kernel));
  428. u64 idle_time = 0;
  429. Processor::for_each([&](Processor& processor) {
  430. idle_time += processor.time_spent_idle();
  431. });
  432. TRY(json.add("idle_time"sv, idle_time));
  433. TRY(json.finish());
  434. return {};
  435. }
  436. };
  437. class ProcFSOverallProcesses final : public ProcFSGlobalInformation {
  438. public:
  439. static NonnullRefPtr<ProcFSOverallProcesses> must_create();
  440. private:
  441. ProcFSOverallProcesses();
  442. virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override
  443. {
  444. auto json = TRY(JsonObjectSerializer<>::try_create(builder));
  445. // Keep this in sync with CProcessStatistics.
  446. auto build_process = [&](JsonArraySerializer<KBufferBuilder>& array, Process const& process) -> ErrorOr<void> {
  447. auto process_object = TRY(array.add_object());
  448. if (process.is_user_process()) {
  449. StringBuilder pledge_builder;
  450. #define __ENUMERATE_PLEDGE_PROMISE(promise) \
  451. if (process.has_promised(Pledge::promise)) \
  452. TRY(pledge_builder.try_append(#promise " "sv));
  453. ENUMERATE_PLEDGE_PROMISES
  454. #undef __ENUMERATE_PLEDGE_PROMISE
  455. TRY(process_object.add("pledge"sv, pledge_builder.string_view()));
  456. switch (process.veil_state()) {
  457. case VeilState::None:
  458. TRY(process_object.add("veil"sv, "None"));
  459. break;
  460. case VeilState::Dropped:
  461. TRY(process_object.add("veil"sv, "Dropped"));
  462. break;
  463. case VeilState::Locked:
  464. TRY(process_object.add("veil"sv, "Locked"));
  465. break;
  466. }
  467. } else {
  468. TRY(process_object.add("pledge"sv, ""sv));
  469. TRY(process_object.add("veil"sv, ""sv));
  470. }
  471. TRY(process_object.add("pid"sv, process.pid().value()));
  472. TRY(process_object.add("pgid"sv, process.tty() ? process.tty()->pgid().value() : 0));
  473. TRY(process_object.add("pgp"sv, process.pgid().value()));
  474. TRY(process_object.add("sid"sv, process.sid().value()));
  475. TRY(process_object.add("uid"sv, process.uid().value()));
  476. TRY(process_object.add("gid"sv, process.gid().value()));
  477. TRY(process_object.add("ppid"sv, process.ppid().value()));
  478. if (process.tty()) {
  479. auto tty_pseudo_name = TRY(process.tty()->pseudo_name());
  480. TRY(process_object.add("tty"sv, tty_pseudo_name->view()));
  481. } else {
  482. TRY(process_object.add("tty"sv, ""));
  483. }
  484. TRY(process_object.add("nfds"sv, process.fds().with_shared([](auto& fds) { return fds.open_count(); })));
  485. TRY(process_object.add("name"sv, process.name()));
  486. TRY(process_object.add("executable"sv, process.executable() ? TRY(process.executable()->try_serialize_absolute_path())->view() : ""sv));
  487. TRY(process_object.add("amount_virtual"sv, process.address_space().amount_virtual()));
  488. TRY(process_object.add("amount_resident"sv, process.address_space().amount_resident()));
  489. TRY(process_object.add("amount_dirty_private"sv, process.address_space().amount_dirty_private()));
  490. TRY(process_object.add("amount_clean_inode"sv, TRY(process.address_space().amount_clean_inode())));
  491. TRY(process_object.add("amount_shared"sv, process.address_space().amount_shared()));
  492. TRY(process_object.add("amount_purgeable_volatile"sv, process.address_space().amount_purgeable_volatile()));
  493. TRY(process_object.add("amount_purgeable_nonvolatile"sv, process.address_space().amount_purgeable_nonvolatile()));
  494. TRY(process_object.add("dumpable"sv, process.is_dumpable()));
  495. TRY(process_object.add("kernel"sv, process.is_kernel_process()));
  496. auto thread_array = TRY(process_object.add_array("threads"sv));
  497. TRY(process.try_for_each_thread([&](const Thread& thread) -> ErrorOr<void> {
  498. SpinlockLocker locker(thread.get_lock());
  499. auto thread_object = TRY(thread_array.add_object());
  500. #if LOCK_DEBUG
  501. TRY(thread_object.add("lock_count"sv, thread.lock_count()));
  502. #endif
  503. TRY(thread_object.add("tid"sv, thread.tid().value()));
  504. TRY(thread_object.add("name"sv, thread.name()));
  505. TRY(thread_object.add("times_scheduled"sv, thread.times_scheduled()));
  506. TRY(thread_object.add("time_user"sv, thread.time_in_user()));
  507. TRY(thread_object.add("time_kernel"sv, thread.time_in_kernel()));
  508. TRY(thread_object.add("state"sv, thread.state_string()));
  509. TRY(thread_object.add("cpu"sv, thread.cpu()));
  510. TRY(thread_object.add("priority"sv, thread.priority()));
  511. TRY(thread_object.add("syscall_count"sv, thread.syscall_count()));
  512. TRY(thread_object.add("inode_faults"sv, thread.inode_faults()));
  513. TRY(thread_object.add("zero_faults"sv, thread.zero_faults()));
  514. TRY(thread_object.add("cow_faults"sv, thread.cow_faults()));
  515. TRY(thread_object.add("file_read_bytes"sv, thread.file_read_bytes()));
  516. TRY(thread_object.add("file_write_bytes"sv, thread.file_write_bytes()));
  517. TRY(thread_object.add("unix_socket_read_bytes"sv, thread.unix_socket_read_bytes()));
  518. TRY(thread_object.add("unix_socket_write_bytes"sv, thread.unix_socket_write_bytes()));
  519. TRY(thread_object.add("ipv4_socket_read_bytes"sv, thread.ipv4_socket_read_bytes()));
  520. TRY(thread_object.add("ipv4_socket_write_bytes"sv, thread.ipv4_socket_write_bytes()));
  521. TRY(thread_object.finish());
  522. return {};
  523. }));
  524. TRY(thread_array.finish());
  525. TRY(process_object.finish());
  526. return {};
  527. };
  528. {
  529. auto array = TRY(json.add_array("processes"sv));
  530. TRY(build_process(array, *Scheduler::colonel()));
  531. TRY(Process::all_instances().with([&](auto& processes) -> ErrorOr<void> {
  532. for (auto& process : processes)
  533. TRY(build_process(array, process));
  534. return {};
  535. }));
  536. TRY(array.finish());
  537. }
  538. auto total_time_scheduled = Scheduler::get_total_time_scheduled();
  539. TRY(json.add("total_time"sv, total_time_scheduled.total));
  540. TRY(json.add("total_time_kernel"sv, total_time_scheduled.total_kernel));
  541. TRY(json.finish());
  542. return {};
  543. }
  544. };
  545. class ProcFSCPUInformation final : public ProcFSGlobalInformation {
  546. public:
  547. static NonnullRefPtr<ProcFSCPUInformation> must_create();
  548. private:
  549. ProcFSCPUInformation();
  550. virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override
  551. {
  552. auto array = TRY(JsonArraySerializer<>::try_create(builder));
  553. TRY(Processor::try_for_each(
  554. [&](Processor& proc) -> ErrorOr<void> {
  555. auto& info = proc.info();
  556. auto obj = TRY(array.add_object());
  557. TRY(obj.add("processor"sv, proc.id()));
  558. TRY(obj.add("vendor_id"sv, info.vendor_id_string()));
  559. TRY(obj.add("family"sv, info.display_family()));
  560. if (!info.hypervisor_vendor_id_string().is_null())
  561. TRY(obj.add("hypervisor_vendor_id"sv, info.hypervisor_vendor_id_string()));
  562. auto features_array = TRY(obj.add_array("features"sv));
  563. auto keep_empty = false;
  564. ErrorOr<void> result; // FIXME: Make this nicer
  565. info.features_string().for_each_split_view(' ', keep_empty, [&](StringView feature) {
  566. if (result.is_error())
  567. return;
  568. result = features_array.add(feature);
  569. });
  570. TRY(result);
  571. TRY(features_array.finish());
  572. TRY(obj.add("model"sv, info.display_model()));
  573. TRY(obj.add("stepping"sv, info.stepping()));
  574. TRY(obj.add("type"sv, info.type()));
  575. TRY(obj.add("brand"sv, info.brand_string()));
  576. auto caches = TRY(obj.add_object("caches"sv));
  577. auto add_cache_info = [&](StringView name, ProcessorInfo::Cache const& cache) -> ErrorOr<void> {
  578. auto cache_object = TRY(caches.add_object(name));
  579. TRY(cache_object.add("size"sv, cache.size));
  580. TRY(cache_object.add("line_size"sv, cache.line_size));
  581. TRY(cache_object.finish());
  582. return {};
  583. };
  584. if (info.l1_data_cache().has_value())
  585. TRY(add_cache_info("l1_data"sv, *info.l1_data_cache()));
  586. if (info.l1_data_cache().has_value())
  587. TRY(add_cache_info("l1_instruction"sv, *info.l1_instruction_cache()));
  588. if (info.l1_data_cache().has_value())
  589. TRY(add_cache_info("l2"sv, *info.l2_cache()));
  590. if (info.l1_data_cache().has_value())
  591. TRY(add_cache_info("l3"sv, *info.l3_cache()));
  592. TRY(caches.finish());
  593. TRY(obj.finish());
  594. return {};
  595. }));
  596. TRY(array.finish());
  597. return {};
  598. }
  599. };
  600. class ProcFSDmesg final : public ProcFSGlobalInformation {
  601. public:
  602. static NonnullRefPtr<ProcFSDmesg> must_create();
  603. virtual mode_t required_mode() const override { return 0400; }
  604. private:
  605. ProcFSDmesg();
  606. virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override
  607. {
  608. VERIFY(DeviceManagement::the().is_console_device_attached());
  609. InterruptDisabler disabler;
  610. for (char ch : DeviceManagement::the().console_device().logbuffer()) {
  611. TRY(builder.append(ch));
  612. }
  613. return {};
  614. }
  615. };
  616. class ProcFSInterrupts final : public ProcFSGlobalInformation {
  617. public:
  618. static NonnullRefPtr<ProcFSInterrupts> must_create();
  619. private:
  620. ProcFSInterrupts();
  621. virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override
  622. {
  623. auto array = TRY(JsonArraySerializer<>::try_create(builder));
  624. ErrorOr<void> result; // FIXME: Make this nicer
  625. InterruptManagement::the().enumerate_interrupt_handlers([&array, &result](GenericInterruptHandler& handler) {
  626. if (result.is_error())
  627. return;
  628. result = ([&]() -> ErrorOr<void> {
  629. auto obj = TRY(array.add_object());
  630. TRY(obj.add("purpose"sv, handler.purpose()));
  631. TRY(obj.add("interrupt_line"sv, handler.interrupt_number()));
  632. TRY(obj.add("controller"sv, handler.controller()));
  633. TRY(obj.add("cpu_handler"sv, 0)); // FIXME: Determine the responsible CPU for each interrupt handler.
  634. TRY(obj.add("device_sharing"sv, (unsigned)handler.sharing_devices_count()));
  635. TRY(obj.add("call_count"sv, (unsigned)handler.get_invoking_count()));
  636. TRY(obj.finish());
  637. return {};
  638. })();
  639. });
  640. TRY(result);
  641. TRY(array.finish());
  642. return {};
  643. }
  644. };
  645. class ProcFSKeymap final : public ProcFSGlobalInformation {
  646. public:
  647. static NonnullRefPtr<ProcFSKeymap> must_create();
  648. private:
  649. ProcFSKeymap();
  650. virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override
  651. {
  652. auto json = TRY(JsonObjectSerializer<>::try_create(builder));
  653. TRY(HIDManagement::the().keymap_data().with([&](auto const& keymap_data) {
  654. return json.add("keymap"sv, keymap_data.character_map_name->view());
  655. }));
  656. TRY(json.finish());
  657. return {};
  658. }
  659. };
  660. // FIXME: Remove this after we enumerate the SysFS from lspci and SystemMonitor
  661. class ProcFSPCI final : public ProcFSGlobalInformation {
  662. public:
  663. static NonnullRefPtr<ProcFSPCI> must_create();
  664. private:
  665. ProcFSPCI();
  666. virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override
  667. {
  668. auto array = TRY(JsonArraySerializer<>::try_create(builder));
  669. ErrorOr<void> result; // FIXME: Make this nicer
  670. TRY(PCI::enumerate([&array, &result](PCI::DeviceIdentifier const& device_identifier) {
  671. if (result.is_error())
  672. return;
  673. result = ([&]() -> ErrorOr<void> {
  674. auto obj = TRY(array.add_object());
  675. TRY(obj.add("domain"sv, device_identifier.address().domain()));
  676. TRY(obj.add("bus"sv, device_identifier.address().bus()));
  677. TRY(obj.add("device"sv, device_identifier.address().device()));
  678. TRY(obj.add("function"sv, device_identifier.address().function()));
  679. TRY(obj.add("vendor_id"sv, device_identifier.hardware_id().vendor_id));
  680. TRY(obj.add("device_id"sv, device_identifier.hardware_id().device_id));
  681. TRY(obj.add("revision_id"sv, device_identifier.revision_id().value()));
  682. TRY(obj.add("subclass"sv, device_identifier.subclass_code().value()));
  683. TRY(obj.add("class"sv, device_identifier.class_code().value()));
  684. TRY(obj.add("subsystem_id"sv, device_identifier.subsystem_id().value()));
  685. TRY(obj.add("subsystem_vendor_id"sv, device_identifier.subsystem_vendor_id().value()));
  686. TRY(obj.finish());
  687. return {};
  688. })();
  689. }));
  690. TRY(result);
  691. TRY(array.finish());
  692. return {};
  693. }
  694. };
  695. class ProcFSDevices final : public ProcFSGlobalInformation {
  696. public:
  697. static NonnullRefPtr<ProcFSDevices> must_create();
  698. private:
  699. ProcFSDevices();
  700. virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override
  701. {
  702. auto array = TRY(JsonArraySerializer<>::try_create(builder));
  703. TRY(DeviceManagement::the().try_for_each([&array](auto& device) -> ErrorOr<void> {
  704. auto obj = TRY(array.add_object());
  705. TRY(obj.add("major"sv, device.major().value()));
  706. TRY(obj.add("minor"sv, device.minor().value()));
  707. TRY(obj.add("class_name"sv, device.class_name()));
  708. if (device.is_block_device())
  709. TRY(obj.add("type"sv, "block"));
  710. else if (device.is_character_device())
  711. TRY(obj.add("type"sv, "character"));
  712. else
  713. VERIFY_NOT_REACHED();
  714. TRY(obj.finish());
  715. return {};
  716. }));
  717. TRY(array.finish());
  718. return {};
  719. }
  720. };
  721. class ProcFSUptime final : public ProcFSGlobalInformation {
  722. public:
  723. static NonnullRefPtr<ProcFSUptime> must_create();
  724. private:
  725. ProcFSUptime();
  726. virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override
  727. {
  728. return builder.appendff("{}\n", TimeManagement::the().uptime_ms() / 1000);
  729. }
  730. };
  731. class ProcFSCommandLine final : public ProcFSGlobalInformation {
  732. public:
  733. static NonnullRefPtr<ProcFSCommandLine> must_create();
  734. private:
  735. ProcFSCommandLine();
  736. virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override
  737. {
  738. TRY(builder.append(kernel_command_line().string()));
  739. TRY(builder.append('\n'));
  740. return {};
  741. }
  742. };
  743. class ProcFSSystemMode final : public ProcFSGlobalInformation {
  744. public:
  745. static NonnullRefPtr<ProcFSSystemMode> must_create();
  746. private:
  747. ProcFSSystemMode();
  748. virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override
  749. {
  750. TRY(builder.append(kernel_command_line().system_mode()));
  751. TRY(builder.append('\n'));
  752. return {};
  753. }
  754. };
  755. class ProcFSProfile final : public ProcFSGlobalInformation {
  756. public:
  757. static NonnullRefPtr<ProcFSProfile> must_create();
  758. virtual mode_t required_mode() const override { return 0400; }
  759. private:
  760. ProcFSProfile();
  761. virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override
  762. {
  763. if (!g_global_perf_events)
  764. return ENOENT;
  765. TRY(g_global_perf_events->to_json(builder));
  766. return {};
  767. }
  768. };
  769. class ProcFSKernelBase final : public ProcFSGlobalInformation {
  770. public:
  771. static NonnullRefPtr<ProcFSKernelBase> must_create();
  772. private:
  773. ProcFSKernelBase();
  774. virtual mode_t required_mode() const override { return 0400; }
  775. virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override
  776. {
  777. if (!Process::current().is_superuser())
  778. return EPERM;
  779. return builder.appendff("{}", kernel_load_base);
  780. }
  781. };
  782. UNMAP_AFTER_INIT NonnullRefPtr<ProcFSSelfProcessDirectory> ProcFSSelfProcessDirectory::must_create()
  783. {
  784. return adopt_ref_if_nonnull(new (nothrow) ProcFSSelfProcessDirectory()).release_nonnull();
  785. }
  786. UNMAP_AFTER_INIT NonnullRefPtr<ProcFSDiskUsage> ProcFSDiskUsage::must_create()
  787. {
  788. return adopt_ref_if_nonnull(new (nothrow) ProcFSDiskUsage).release_nonnull();
  789. }
  790. UNMAP_AFTER_INIT NonnullRefPtr<ProcFSMemoryStatus> ProcFSMemoryStatus::must_create()
  791. {
  792. return adopt_ref_if_nonnull(new (nothrow) ProcFSMemoryStatus).release_nonnull();
  793. }
  794. UNMAP_AFTER_INIT NonnullRefPtr<ProcFSSystemStatistics> ProcFSSystemStatistics::must_create()
  795. {
  796. return adopt_ref_if_nonnull(new (nothrow) ProcFSSystemStatistics).release_nonnull();
  797. }
  798. UNMAP_AFTER_INIT NonnullRefPtr<ProcFSOverallProcesses> ProcFSOverallProcesses::must_create()
  799. {
  800. return adopt_ref_if_nonnull(new (nothrow) ProcFSOverallProcesses).release_nonnull();
  801. }
  802. UNMAP_AFTER_INIT NonnullRefPtr<ProcFSCPUInformation> ProcFSCPUInformation::must_create()
  803. {
  804. return adopt_ref_if_nonnull(new (nothrow) ProcFSCPUInformation).release_nonnull();
  805. }
  806. UNMAP_AFTER_INIT NonnullRefPtr<ProcFSDmesg> ProcFSDmesg::must_create()
  807. {
  808. return adopt_ref_if_nonnull(new (nothrow) ProcFSDmesg).release_nonnull();
  809. }
  810. UNMAP_AFTER_INIT NonnullRefPtr<ProcFSInterrupts> ProcFSInterrupts::must_create()
  811. {
  812. return adopt_ref_if_nonnull(new (nothrow) ProcFSInterrupts).release_nonnull();
  813. }
  814. UNMAP_AFTER_INIT NonnullRefPtr<ProcFSKeymap> ProcFSKeymap::must_create()
  815. {
  816. return adopt_ref_if_nonnull(new (nothrow) ProcFSKeymap).release_nonnull();
  817. }
  818. UNMAP_AFTER_INIT NonnullRefPtr<ProcFSPCI> ProcFSPCI::must_create()
  819. {
  820. return adopt_ref_if_nonnull(new (nothrow) ProcFSPCI).release_nonnull();
  821. }
  822. UNMAP_AFTER_INIT NonnullRefPtr<ProcFSDevices> ProcFSDevices::must_create()
  823. {
  824. return adopt_ref_if_nonnull(new (nothrow) ProcFSDevices).release_nonnull();
  825. }
  826. UNMAP_AFTER_INIT NonnullRefPtr<ProcFSUptime> ProcFSUptime::must_create()
  827. {
  828. return adopt_ref_if_nonnull(new (nothrow) ProcFSUptime).release_nonnull();
  829. }
  830. UNMAP_AFTER_INIT NonnullRefPtr<ProcFSCommandLine> ProcFSCommandLine::must_create()
  831. {
  832. return adopt_ref_if_nonnull(new (nothrow) ProcFSCommandLine).release_nonnull();
  833. }
  834. UNMAP_AFTER_INIT NonnullRefPtr<ProcFSSystemMode> ProcFSSystemMode::must_create()
  835. {
  836. return adopt_ref_if_nonnull(new (nothrow) ProcFSSystemMode).release_nonnull();
  837. }
  838. UNMAP_AFTER_INIT NonnullRefPtr<ProcFSProfile> ProcFSProfile::must_create()
  839. {
  840. return adopt_ref_if_nonnull(new (nothrow) ProcFSProfile).release_nonnull();
  841. }
  842. UNMAP_AFTER_INIT NonnullRefPtr<ProcFSKernelBase> ProcFSKernelBase::must_create()
  843. {
  844. return adopt_ref_if_nonnull(new (nothrow) ProcFSKernelBase).release_nonnull();
  845. }
  846. UNMAP_AFTER_INIT ProcFSSelfProcessDirectory::ProcFSSelfProcessDirectory()
  847. : ProcFSExposedLink("self"sv)
  848. {
  849. }
  850. UNMAP_AFTER_INIT ProcFSDiskUsage::ProcFSDiskUsage()
  851. : ProcFSGlobalInformation("df"sv)
  852. {
  853. }
  854. UNMAP_AFTER_INIT ProcFSMemoryStatus::ProcFSMemoryStatus()
  855. : ProcFSGlobalInformation("memstat"sv)
  856. {
  857. }
  858. UNMAP_AFTER_INIT ProcFSSystemStatistics::ProcFSSystemStatistics()
  859. : ProcFSGlobalInformation("stat"sv)
  860. {
  861. }
  862. UNMAP_AFTER_INIT ProcFSOverallProcesses::ProcFSOverallProcesses()
  863. : ProcFSGlobalInformation("all"sv)
  864. {
  865. }
  866. UNMAP_AFTER_INIT ProcFSCPUInformation::ProcFSCPUInformation()
  867. : ProcFSGlobalInformation("cpuinfo"sv)
  868. {
  869. }
  870. UNMAP_AFTER_INIT ProcFSDmesg::ProcFSDmesg()
  871. : ProcFSGlobalInformation("dmesg"sv)
  872. {
  873. }
  874. UNMAP_AFTER_INIT ProcFSInterrupts::ProcFSInterrupts()
  875. : ProcFSGlobalInformation("interrupts"sv)
  876. {
  877. }
  878. UNMAP_AFTER_INIT ProcFSKeymap::ProcFSKeymap()
  879. : ProcFSGlobalInformation("keymap"sv)
  880. {
  881. }
  882. UNMAP_AFTER_INIT ProcFSPCI::ProcFSPCI()
  883. : ProcFSGlobalInformation("pci"sv)
  884. {
  885. }
  886. UNMAP_AFTER_INIT ProcFSDevices::ProcFSDevices()
  887. : ProcFSGlobalInformation("devices"sv)
  888. {
  889. }
  890. UNMAP_AFTER_INIT ProcFSUptime::ProcFSUptime()
  891. : ProcFSGlobalInformation("uptime"sv)
  892. {
  893. }
  894. UNMAP_AFTER_INIT ProcFSCommandLine::ProcFSCommandLine()
  895. : ProcFSGlobalInformation("cmdline"sv)
  896. {
  897. }
  898. UNMAP_AFTER_INIT ProcFSSystemMode::ProcFSSystemMode()
  899. : ProcFSGlobalInformation("system_mode"sv)
  900. {
  901. }
  902. UNMAP_AFTER_INIT ProcFSProfile::ProcFSProfile()
  903. : ProcFSGlobalInformation("profile"sv)
  904. {
  905. }
  906. UNMAP_AFTER_INIT ProcFSKernelBase::ProcFSKernelBase()
  907. : ProcFSGlobalInformation("kernel_base"sv)
  908. {
  909. }
  910. UNMAP_AFTER_INIT NonnullRefPtr<ProcFSSystemDirectory> ProcFSSystemDirectory::must_create(ProcFSRootDirectory const& parent_directory)
  911. {
  912. auto directory = adopt_ref(*new (nothrow) ProcFSSystemDirectory(parent_directory));
  913. directory->m_components.append(ProcFSDumpKmallocStacks::must_create(directory));
  914. directory->m_components.append(ProcFSUBSanDeadly::must_create(directory));
  915. directory->m_components.append(ProcFSCapsLockRemap::must_create(directory));
  916. return directory;
  917. }
  918. UNMAP_AFTER_INIT ProcFSSystemDirectory::ProcFSSystemDirectory(ProcFSRootDirectory const& parent_directory)
  919. : ProcFSExposedDirectory("sys"sv, parent_directory)
  920. {
  921. }
  922. UNMAP_AFTER_INIT void ProcFSRootDirectory::add_pci_node(Badge<PCI::Access>)
  923. {
  924. m_components.append(ProcFSPCI::must_create());
  925. }
  926. UNMAP_AFTER_INIT NonnullRefPtr<ProcFSRootDirectory> ProcFSRootDirectory::must_create()
  927. {
  928. auto directory = adopt_ref(*new (nothrow) ProcFSRootDirectory);
  929. directory->m_components.append(ProcFSSelfProcessDirectory::must_create());
  930. directory->m_components.append(ProcFSDiskUsage::must_create());
  931. directory->m_components.append(ProcFSMemoryStatus::must_create());
  932. directory->m_components.append(ProcFSSystemStatistics::must_create());
  933. directory->m_components.append(ProcFSOverallProcesses::must_create());
  934. directory->m_components.append(ProcFSCPUInformation::must_create());
  935. directory->m_components.append(ProcFSDmesg::must_create());
  936. directory->m_components.append(ProcFSInterrupts::must_create());
  937. directory->m_components.append(ProcFSKeymap::must_create());
  938. directory->m_components.append(ProcFSDevices::must_create());
  939. directory->m_components.append(ProcFSUptime::must_create());
  940. directory->m_components.append(ProcFSCommandLine::must_create());
  941. directory->m_components.append(ProcFSSystemMode::must_create());
  942. directory->m_components.append(ProcFSProfile::must_create());
  943. directory->m_components.append(ProcFSKernelBase::must_create());
  944. directory->m_components.append(ProcFSNetworkDirectory::must_create(*directory));
  945. directory->m_components.append(ProcFSSystemDirectory::must_create(*directory));
  946. return directory;
  947. }
  948. ErrorOr<void> ProcFSRootDirectory::traverse_as_directory(FileSystemID fsid, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const
  949. {
  950. MutexLocker locker(ProcFSComponentRegistry::the().get_lock());
  951. TRY(callback({ "."sv, { fsid, component_index() }, 0 }));
  952. TRY(callback({ ".."sv, { fsid, 0 }, 0 }));
  953. for (auto const& component : m_components) {
  954. InodeIdentifier identifier = { fsid, component.component_index() };
  955. TRY(callback({ component.name(), identifier, 0 }));
  956. }
  957. return Process::all_instances().with([&](auto& list) -> ErrorOr<void> {
  958. for (auto& process : list) {
  959. VERIFY(!(process.pid() < 0));
  960. u64 process_id = (u64)process.pid().value();
  961. InodeIdentifier identifier = { fsid, static_cast<InodeIndex>(process_id << 36) };
  962. auto process_id_string = TRY(KString::formatted("{:d}", process_id));
  963. TRY(callback({ process_id_string->view(), identifier, 0 }));
  964. }
  965. return {};
  966. });
  967. }
  968. ErrorOr<NonnullRefPtr<ProcFSExposedComponent>> ProcFSRootDirectory::lookup(StringView name)
  969. {
  970. auto maybe_candidate = ProcFSExposedDirectory::lookup(name);
  971. if (maybe_candidate.is_error()) {
  972. if (maybe_candidate.error().code() != ENOENT) {
  973. return maybe_candidate.release_error();
  974. }
  975. } else {
  976. return maybe_candidate.release_value();
  977. }
  978. auto pid = name.to_uint<unsigned>();
  979. if (!pid.has_value())
  980. return ESRCH;
  981. auto actual_pid = pid.value();
  982. if (auto maybe_process = Process::from_pid(actual_pid))
  983. return maybe_process->procfs_traits();
  984. return ENOENT;
  985. }
  986. UNMAP_AFTER_INIT ProcFSRootDirectory::ProcFSRootDirectory()
  987. : ProcFSExposedDirectory("."sv)
  988. {
  989. }
  990. UNMAP_AFTER_INIT ProcFSRootDirectory::~ProcFSRootDirectory() = default;
  991. }