GlobalProcessExposed.cpp 41 KB

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