GlobalProcessExposed.cpp 36 KB

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