GlobalProcessExposed.cpp 40 KB

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