GlobalProcessExposed.cpp 40 KB

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