GlobalProcessExposed.cpp 32 KB

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