GlobalProcessExposed.cpp 37 KB

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