GlobalProcessExposed.cpp 40 KB

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