ebpf_apps.c 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. #include "ebpf.h"
  3. #include "ebpf_socket.h"
  4. #include "ebpf_apps.h"
  5. // ----------------------------------------------------------------------------
  6. // ARAL vectors used to speed up processing
  7. ARAL *ebpf_aral_apps_pid_stat = NULL;
  8. ARAL *ebpf_aral_process_stat = NULL;
  9. ARAL *ebpf_aral_socket_pid = NULL;
  10. ARAL *ebpf_aral_cachestat_pid = NULL;
  11. ARAL *ebpf_aral_dcstat_pid = NULL;
  12. ARAL *ebpf_aral_vfs_pid = NULL;
  13. ARAL *ebpf_aral_fd_pid = NULL;
  14. ARAL *ebpf_aral_shm_pid = NULL;
  15. // ----------------------------------------------------------------------------
  16. // Global vectors used with apps
  17. ebpf_socket_publish_apps_t **socket_bandwidth_curr = NULL;
  18. netdata_publish_cachestat_t **cachestat_pid = NULL;
  19. netdata_publish_dcstat_t **dcstat_pid = NULL;
  20. netdata_publish_swap_t **swap_pid = NULL;
  21. netdata_publish_vfs_t **vfs_pid = NULL;
  22. netdata_fd_stat_t **fd_pid = NULL;
  23. netdata_publish_shm_t **shm_pid = NULL;
  24. ebpf_process_stat_t **global_process_stats = NULL;
  25. /**
  26. * eBPF ARAL Init
  27. *
  28. * Initiallize array allocator that will be used when integration with apps and ebpf is created.
  29. */
  30. void ebpf_aral_init(void)
  31. {
  32. size_t max_elements = NETDATA_EBPF_ALLOC_MAX_PID;
  33. if (max_elements < NETDATA_EBPF_ALLOC_MIN_ELEMENTS) {
  34. error("Number of elements given is too small, adjusting it for %d", NETDATA_EBPF_ALLOC_MIN_ELEMENTS);
  35. max_elements = NETDATA_EBPF_ALLOC_MIN_ELEMENTS;
  36. }
  37. ebpf_aral_apps_pid_stat = ebpf_allocate_pid_aral("ebpf_pid_stat", sizeof(struct ebpf_pid_stat));
  38. ebpf_aral_process_stat = ebpf_allocate_pid_aral(NETDATA_EBPF_PROC_ARAL_NAME, sizeof(ebpf_process_stat_t));
  39. #ifdef NETDATA_DEV_MODE
  40. info("Plugin is using ARAL with values %d", NETDATA_EBPF_ALLOC_MAX_PID);
  41. #endif
  42. }
  43. /**
  44. * eBPF pid stat get
  45. *
  46. * Get a ebpf_pid_stat entry to be used with a specific PID.
  47. *
  48. * @return it returns the address on success.
  49. */
  50. struct ebpf_pid_stat *ebpf_pid_stat_get(void)
  51. {
  52. struct ebpf_pid_stat *target = aral_mallocz(ebpf_aral_apps_pid_stat);
  53. memset(target, 0, sizeof(struct ebpf_pid_stat));
  54. return target;
  55. }
  56. /**
  57. * eBPF target release
  58. *
  59. * @param stat Release a target after usage.
  60. */
  61. void ebpf_pid_stat_release(struct ebpf_pid_stat *stat)
  62. {
  63. aral_freez(ebpf_aral_apps_pid_stat, stat);
  64. }
  65. /*****************************************************************
  66. *
  67. * PROCESS ARAL FUNCTIONS
  68. *
  69. *****************************************************************/
  70. /**
  71. * eBPF process stat get
  72. *
  73. * Get a ebpf_pid_stat entry to be used with a specific PID.
  74. *
  75. * @return it returns the address on success.
  76. */
  77. ebpf_process_stat_t *ebpf_process_stat_get(void)
  78. {
  79. ebpf_process_stat_t *target = aral_mallocz(ebpf_aral_process_stat);
  80. memset(target, 0, sizeof(ebpf_process_stat_t));
  81. return target;
  82. }
  83. /**
  84. * eBPF process release
  85. *
  86. * @param stat Release a target after usage.
  87. */
  88. void ebpf_process_stat_release(ebpf_process_stat_t *stat)
  89. {
  90. aral_freez(ebpf_aral_process_stat, stat);
  91. }
  92. /*****************************************************************
  93. *
  94. * SOCKET ARAL FUNCTIONS
  95. *
  96. *****************************************************************/
  97. /**
  98. * eBPF socket Aral init
  99. *
  100. * Initiallize array allocator that will be used when integration with apps is enabled.
  101. */
  102. void ebpf_socket_aral_init()
  103. {
  104. ebpf_aral_socket_pid = ebpf_allocate_pid_aral(NETDATA_EBPF_SOCKET_ARAL_NAME, sizeof(ebpf_socket_publish_apps_t));
  105. }
  106. /**
  107. * eBPF socket get
  108. *
  109. * Get a ebpf_socket_publish_apps_t entry to be used with a specific PID.
  110. *
  111. * @return it returns the address on success.
  112. */
  113. ebpf_socket_publish_apps_t *ebpf_socket_stat_get(void)
  114. {
  115. ebpf_socket_publish_apps_t *target = aral_mallocz(ebpf_aral_socket_pid);
  116. memset(target, 0, sizeof(ebpf_socket_publish_apps_t));
  117. return target;
  118. }
  119. /**
  120. * eBPF socket release
  121. *
  122. * @param stat Release a target after usage.
  123. */
  124. void ebpf_socket_release(ebpf_socket_publish_apps_t *stat)
  125. {
  126. aral_freez(ebpf_aral_socket_pid, stat);
  127. }
  128. /*****************************************************************
  129. *
  130. * CACHESTAT ARAL FUNCTIONS
  131. *
  132. *****************************************************************/
  133. /**
  134. * eBPF Cachestat Aral init
  135. *
  136. * Initiallize array allocator that will be used when integration with apps is enabled.
  137. */
  138. void ebpf_cachestat_aral_init()
  139. {
  140. ebpf_aral_cachestat_pid = ebpf_allocate_pid_aral(NETDATA_EBPF_CACHESTAT_ARAL_NAME, sizeof(netdata_publish_cachestat_t));
  141. }
  142. /**
  143. * eBPF publish cachestat get
  144. *
  145. * Get a netdata_publish_cachestat_t entry to be used with a specific PID.
  146. *
  147. * @return it returns the address on success.
  148. */
  149. netdata_publish_cachestat_t *ebpf_publish_cachestat_get(void)
  150. {
  151. netdata_publish_cachestat_t *target = aral_mallocz(ebpf_aral_cachestat_pid);
  152. memset(target, 0, sizeof(netdata_publish_cachestat_t));
  153. return target;
  154. }
  155. /**
  156. * eBPF cachestat release
  157. *
  158. * @param stat Release a target after usage.
  159. */
  160. void ebpf_cachestat_release(netdata_publish_cachestat_t *stat)
  161. {
  162. aral_freez(ebpf_aral_cachestat_pid, stat);
  163. }
  164. /*****************************************************************
  165. *
  166. * DCSTAT ARAL FUNCTIONS
  167. *
  168. *****************************************************************/
  169. /**
  170. * eBPF directory cache Aral init
  171. *
  172. * Initiallize array allocator that will be used when integration with apps is enabled.
  173. */
  174. void ebpf_dcstat_aral_init()
  175. {
  176. ebpf_aral_dcstat_pid = ebpf_allocate_pid_aral(NETDATA_EBPF_DCSTAT_ARAL_NAME, sizeof(netdata_publish_dcstat_t));
  177. }
  178. /**
  179. * eBPF publish dcstat get
  180. *
  181. * Get a netdata_publish_dcstat_t entry to be used with a specific PID.
  182. *
  183. * @return it returns the address on success.
  184. */
  185. netdata_publish_dcstat_t *ebpf_publish_dcstat_get(void)
  186. {
  187. netdata_publish_dcstat_t *target = aral_mallocz(ebpf_aral_dcstat_pid);
  188. memset(target, 0, sizeof(netdata_publish_dcstat_t));
  189. return target;
  190. }
  191. /**
  192. * eBPF dcstat release
  193. *
  194. * @param stat Release a target after usage.
  195. */
  196. void ebpf_dcstat_release(netdata_publish_dcstat_t *stat)
  197. {
  198. aral_freez(ebpf_aral_dcstat_pid, stat);
  199. }
  200. /*****************************************************************
  201. *
  202. * VFS ARAL FUNCTIONS
  203. *
  204. *****************************************************************/
  205. /**
  206. * eBPF VFS Aral init
  207. *
  208. * Initiallize array allocator that will be used when integration with apps is enabled.
  209. */
  210. void ebpf_vfs_aral_init()
  211. {
  212. ebpf_aral_vfs_pid = ebpf_allocate_pid_aral(NETDATA_EBPF_VFS_ARAL_NAME, sizeof(netdata_publish_vfs_t));
  213. }
  214. /**
  215. * eBPF publish VFS get
  216. *
  217. * Get a netdata_publish_vfs_t entry to be used with a specific PID.
  218. *
  219. * @return it returns the address on success.
  220. */
  221. netdata_publish_vfs_t *ebpf_vfs_get(void)
  222. {
  223. netdata_publish_vfs_t *target = aral_mallocz(ebpf_aral_vfs_pid);
  224. memset(target, 0, sizeof(netdata_publish_vfs_t));
  225. return target;
  226. }
  227. /**
  228. * eBPF VFS release
  229. *
  230. * @param stat Release a target after usage.
  231. */
  232. void ebpf_vfs_release(netdata_publish_vfs_t *stat)
  233. {
  234. aral_freez(ebpf_aral_vfs_pid, stat);
  235. }
  236. /*****************************************************************
  237. *
  238. * FD ARAL FUNCTIONS
  239. *
  240. *****************************************************************/
  241. /**
  242. * eBPF file descriptor Aral init
  243. *
  244. * Initiallize array allocator that will be used when integration with apps is enabled.
  245. */
  246. void ebpf_fd_aral_init()
  247. {
  248. ebpf_aral_fd_pid = ebpf_allocate_pid_aral(NETDATA_EBPF_FD_ARAL_NAME, sizeof(netdata_fd_stat_t));
  249. }
  250. /**
  251. * eBPF publish file descriptor get
  252. *
  253. * Get a netdata_fd_stat_t entry to be used with a specific PID.
  254. *
  255. * @return it returns the address on success.
  256. */
  257. netdata_fd_stat_t *ebpf_fd_stat_get(void)
  258. {
  259. netdata_fd_stat_t *target = aral_mallocz(ebpf_aral_fd_pid);
  260. memset(target, 0, sizeof(netdata_fd_stat_t));
  261. return target;
  262. }
  263. /**
  264. * eBPF file descriptor release
  265. *
  266. * @param stat Release a target after usage.
  267. */
  268. void ebpf_fd_release(netdata_fd_stat_t *stat)
  269. {
  270. aral_freez(ebpf_aral_fd_pid, stat);
  271. }
  272. /*****************************************************************
  273. *
  274. * SHM ARAL FUNCTIONS
  275. *
  276. *****************************************************************/
  277. /**
  278. * eBPF shared memory Aral init
  279. *
  280. * Initiallize array allocator that will be used when integration with apps is enabled.
  281. */
  282. void ebpf_shm_aral_init()
  283. {
  284. ebpf_aral_shm_pid = ebpf_allocate_pid_aral(NETDATA_EBPF_SHM_ARAL_NAME, sizeof(netdata_publish_shm_t));
  285. }
  286. /**
  287. * eBPF shared memory get
  288. *
  289. * Get a netdata_publish_shm_t entry to be used with a specific PID.
  290. *
  291. * @return it returns the address on success.
  292. */
  293. netdata_publish_shm_t *ebpf_shm_stat_get(void)
  294. {
  295. netdata_publish_shm_t *target = aral_mallocz(ebpf_aral_shm_pid);
  296. memset(target, 0, sizeof(netdata_publish_shm_t));
  297. return target;
  298. }
  299. /**
  300. * eBPF shared memory release
  301. *
  302. * @param stat Release a target after usage.
  303. */
  304. void ebpf_shm_release(netdata_publish_shm_t *stat)
  305. {
  306. aral_freez(ebpf_aral_shm_pid, stat);
  307. }
  308. // ----------------------------------------------------------------------------
  309. // internal flags
  310. // handled in code (automatically set)
  311. static int proc_pid_cmdline_is_needed = 0; // 1 when we need to read /proc/cmdline
  312. /*****************************************************************
  313. *
  314. * FUNCTIONS USED TO READ HASH TABLES
  315. *
  316. *****************************************************************/
  317. /**
  318. * Read statistic hash table.
  319. *
  320. * @param ep the output structure.
  321. * @param fd the file descriptor mapped from kernel ring.
  322. * @param pid the index used to select the data.
  323. * @param bpf_map_lookup_elem a pointer for the function used to read data.
  324. *
  325. * @return It returns 0 when the data was copied and -1 otherwise
  326. */
  327. int ebpf_read_hash_table(void *ep, int fd, uint32_t pid)
  328. {
  329. if (!ep)
  330. return -1;
  331. if (!bpf_map_lookup_elem(fd, &pid, ep))
  332. return 0;
  333. return -1;
  334. }
  335. /**
  336. * Read socket statistic
  337. *
  338. * Read information from kernel ring to user ring.
  339. *
  340. * @param ep the table with all process stats values.
  341. * @param fd the file descriptor mapped from kernel
  342. * @param ef a pointer for the functions mapped from dynamic library
  343. * @param pids the list of pids associated to a target.
  344. *
  345. * @return
  346. */
  347. size_t read_bandwidth_statistic_using_pid_on_target(ebpf_bandwidth_t **ep, int fd, struct ebpf_pid_on_target *pids)
  348. {
  349. size_t count = 0;
  350. while (pids) {
  351. uint32_t current_pid = pids->pid;
  352. if (!ebpf_read_hash_table(ep[current_pid], fd, current_pid))
  353. count++;
  354. pids = pids->next;
  355. }
  356. return count;
  357. }
  358. /**
  359. * Read bandwidth statistic using hash table
  360. *
  361. * @param out the output tensor that will receive the information.
  362. * @param fd the file descriptor that has the data
  363. * @param bpf_map_lookup_elem a pointer for the function to read the data
  364. * @param bpf_map_get_next_key a pointer fo the function to read the index.
  365. */
  366. size_t read_bandwidth_statistic_using_hash_table(ebpf_bandwidth_t **out, int fd)
  367. {
  368. size_t count = 0;
  369. uint32_t key = 0;
  370. uint32_t next_key = 0;
  371. while (bpf_map_get_next_key(fd, &key, &next_key) == 0) {
  372. ebpf_bandwidth_t *eps = out[next_key];
  373. if (!eps) {
  374. eps = callocz(1, sizeof(ebpf_process_stat_t));
  375. out[next_key] = eps;
  376. }
  377. ebpf_read_hash_table(eps, fd, next_key);
  378. }
  379. return count;
  380. }
  381. /*****************************************************************
  382. *
  383. * FUNCTIONS CALLED FROM COLLECTORS
  384. *
  385. *****************************************************************/
  386. /**
  387. * Am I running as Root
  388. *
  389. * Verify the user that is running the collector.
  390. *
  391. * @return It returns 1 for root and 0 otherwise.
  392. */
  393. int am_i_running_as_root()
  394. {
  395. uid_t uid = getuid(), euid = geteuid();
  396. if (uid == 0 || euid == 0) {
  397. return 1;
  398. }
  399. return 0;
  400. }
  401. /**
  402. * Reset the target values
  403. *
  404. * @param root the pointer to the chain that will be reset.
  405. *
  406. * @return it returns the number of structures that was reset.
  407. */
  408. size_t zero_all_targets(struct ebpf_target *root)
  409. {
  410. struct ebpf_target *w;
  411. size_t count = 0;
  412. for (w = root; w; w = w->next) {
  413. count++;
  414. if (unlikely(w->root_pid)) {
  415. struct ebpf_pid_on_target *pid_on_target = w->root_pid;
  416. while (pid_on_target) {
  417. struct ebpf_pid_on_target *pid_on_target_to_free = pid_on_target;
  418. pid_on_target = pid_on_target->next;
  419. freez(pid_on_target_to_free);
  420. }
  421. w->root_pid = NULL;
  422. }
  423. }
  424. return count;
  425. }
  426. /**
  427. * Clean the allocated structures
  428. *
  429. * @param agrt the pointer to be cleaned.
  430. */
  431. void clean_apps_groups_target(struct ebpf_target *agrt)
  432. {
  433. struct ebpf_target *current_target;
  434. while (agrt) {
  435. current_target = agrt;
  436. agrt = current_target->target;
  437. freez(current_target);
  438. }
  439. }
  440. /**
  441. * Find or create a new target
  442. * there are targets that are just aggregated to other target (the second argument)
  443. *
  444. * @param id
  445. * @param target
  446. * @param name
  447. *
  448. * @return It returns the target on success and NULL otherwise
  449. */
  450. struct ebpf_target *get_apps_groups_target(struct ebpf_target **agrt, const char *id, struct ebpf_target *target, const char *name)
  451. {
  452. int tdebug = 0, thidden = target ? target->hidden : 0, ends_with = 0;
  453. const char *nid = id;
  454. // extract the options
  455. while (nid[0] == '-' || nid[0] == '+' || nid[0] == '*') {
  456. if (nid[0] == '-')
  457. thidden = 1;
  458. if (nid[0] == '+')
  459. tdebug = 1;
  460. if (nid[0] == '*')
  461. ends_with = 1;
  462. nid++;
  463. }
  464. uint32_t hash = simple_hash(id);
  465. // find if it already exists
  466. struct ebpf_target *w, *last = *agrt;
  467. for (w = *agrt; w; w = w->next) {
  468. if (w->idhash == hash && strncmp(nid, w->id, EBPF_MAX_NAME) == 0)
  469. return w;
  470. last = w;
  471. }
  472. // find an existing target
  473. if (unlikely(!target)) {
  474. while (*name == '-') {
  475. if (*name == '-')
  476. thidden = 1;
  477. name++;
  478. }
  479. for (target = *agrt; target != NULL; target = target->next) {
  480. if (!target->target && strcmp(name, target->name) == 0)
  481. break;
  482. }
  483. }
  484. if (target && target->target)
  485. fatal(
  486. "Internal Error: request to link process '%s' to target '%s' which is linked to target '%s'", id,
  487. target->id, target->target->id);
  488. w = callocz(1, sizeof(struct ebpf_target));
  489. strncpyz(w->id, nid, EBPF_MAX_NAME);
  490. w->idhash = simple_hash(w->id);
  491. if (unlikely(!target))
  492. // copy the name
  493. strncpyz(w->name, name, EBPF_MAX_NAME);
  494. else
  495. // copy the id
  496. strncpyz(w->name, nid, EBPF_MAX_NAME);
  497. strncpyz(w->compare, nid, EBPF_MAX_COMPARE_NAME);
  498. size_t len = strlen(w->compare);
  499. if (w->compare[len - 1] == '*') {
  500. w->compare[len - 1] = '\0';
  501. w->starts_with = 1;
  502. }
  503. w->ends_with = ends_with;
  504. if (w->starts_with && w->ends_with)
  505. proc_pid_cmdline_is_needed = 1;
  506. w->comparehash = simple_hash(w->compare);
  507. w->comparelen = strlen(w->compare);
  508. w->hidden = thidden;
  509. #ifdef NETDATA_INTERNAL_CHECKS
  510. w->debug_enabled = tdebug;
  511. #else
  512. if (tdebug)
  513. fprintf(stderr, "apps.plugin has been compiled without debugging\n");
  514. #endif
  515. w->target = target;
  516. // append it, to maintain the order in apps_groups.conf
  517. if (last)
  518. last->next = w;
  519. else
  520. *agrt = w;
  521. return w;
  522. }
  523. /**
  524. * Read the apps_groups.conf file
  525. *
  526. * @param agrt a pointer to apps_group_root_target
  527. * @param path the directory to search apps_%s.conf
  528. * @param file the word to complement the file name.
  529. *
  530. * @return It returns 0 on success and -1 otherwise
  531. */
  532. int ebpf_read_apps_groups_conf(struct ebpf_target **agdt, struct ebpf_target **agrt, const char *path, const char *file)
  533. {
  534. char filename[FILENAME_MAX + 1];
  535. snprintfz(filename, FILENAME_MAX, "%s/apps_%s.conf", path, file);
  536. // ----------------------------------------
  537. procfile *ff = procfile_open_no_log(filename, " :\t", PROCFILE_FLAG_DEFAULT);
  538. if (!ff)
  539. return -1;
  540. procfile_set_quotes(ff, "'\"");
  541. ff = procfile_readall(ff);
  542. if (!ff)
  543. return -1;
  544. size_t line, lines = procfile_lines(ff);
  545. for (line = 0; line < lines; line++) {
  546. size_t word, words = procfile_linewords(ff, line);
  547. if (!words)
  548. continue;
  549. char *name = procfile_lineword(ff, line, 0);
  550. if (!name || !*name)
  551. continue;
  552. // find a possibly existing target
  553. struct ebpf_target *w = NULL;
  554. // loop through all words, skipping the first one (the name)
  555. for (word = 0; word < words; word++) {
  556. char *s = procfile_lineword(ff, line, word);
  557. if (!s || !*s)
  558. continue;
  559. if (*s == '#')
  560. break;
  561. // is this the first word? skip it
  562. if (s == name)
  563. continue;
  564. // add this target
  565. struct ebpf_target *n = get_apps_groups_target(agrt, s, w, name);
  566. if (!n) {
  567. error("Cannot create target '%s' (line %zu, word %zu)", s, line, word);
  568. continue;
  569. }
  570. // just some optimization
  571. // to avoid searching for a target for each process
  572. if (!w)
  573. w = n->target ? n->target : n;
  574. }
  575. }
  576. procfile_close(ff);
  577. *agdt = get_apps_groups_target(agrt, "p+!o@w#e$i^r&7*5(-i)l-o_", NULL, "other"); // match nothing
  578. if (!*agdt)
  579. fatal("Cannot create default target");
  580. struct ebpf_target *ptr = *agdt;
  581. if (ptr->target)
  582. *agdt = ptr->target;
  583. return 0;
  584. }
  585. // the minimum PID of the system
  586. // this is also the pid of the init process
  587. #define INIT_PID 1
  588. // ----------------------------------------------------------------------------
  589. // string lengths
  590. #define MAX_CMDLINE 16384
  591. struct ebpf_pid_stat **ebpf_all_pids = NULL; // to avoid allocations, we pre-allocate the
  592. // the entire pid space.
  593. struct ebpf_pid_stat *ebpf_root_of_pids = NULL; // global list of all processes running
  594. size_t ebpf_all_pids_count = 0; // the number of processes running
  595. struct ebpf_target
  596. *apps_groups_default_target = NULL, // the default target
  597. *apps_groups_root_target = NULL, // apps_groups.conf defined
  598. *users_root_target = NULL, // users
  599. *groups_root_target = NULL; // user groups
  600. size_t apps_groups_targets_count = 0; // # of apps_groups.conf targets
  601. // ----------------------------------------------------------------------------
  602. // internal counters
  603. static size_t
  604. // global_iterations_counter = 1,
  605. calls_counter = 0,
  606. // file_counter = 0,
  607. // filenames_allocated_counter = 0,
  608. // inodes_changed_counter = 0,
  609. // links_changed_counter = 0,
  610. targets_assignment_counter = 0;
  611. // ----------------------------------------------------------------------------
  612. // debugging
  613. // log each problem once per process
  614. // log flood protection flags (log_thrown)
  615. #define PID_LOG_IO 0x00000001
  616. #define PID_LOG_STATUS 0x00000002
  617. #define PID_LOG_CMDLINE 0x00000004
  618. #define PID_LOG_FDS 0x00000008
  619. #define PID_LOG_STAT 0x00000010
  620. int debug_enabled = 0;
  621. #ifdef NETDATA_INTERNAL_CHECKS
  622. #define debug_log(fmt, args...) \
  623. do { \
  624. if (unlikely(debug_enabled)) \
  625. debug_log_int(fmt, ##args); \
  626. } while (0)
  627. #else
  628. static inline void debug_log_dummy(void)
  629. {
  630. }
  631. #define debug_log(fmt, args...) debug_log_dummy()
  632. #endif
  633. /**
  634. * Managed log
  635. *
  636. * Store log information if it is necessary.
  637. *
  638. * @param p the pid stat structure
  639. * @param log the log id
  640. * @param status the return from a function.
  641. *
  642. * @return It returns the status value.
  643. */
  644. static inline int managed_log(struct ebpf_pid_stat *p, uint32_t log, int status)
  645. {
  646. if (unlikely(!status)) {
  647. // error("command failed log %u, errno %d", log, errno);
  648. if (unlikely(debug_enabled || errno != ENOENT)) {
  649. if (unlikely(debug_enabled || !(p->log_thrown & log))) {
  650. p->log_thrown |= log;
  651. switch (log) {
  652. case PID_LOG_IO:
  653. error(
  654. "Cannot process %s/proc/%d/io (command '%s')", netdata_configured_host_prefix, p->pid,
  655. p->comm);
  656. break;
  657. case PID_LOG_STATUS:
  658. error(
  659. "Cannot process %s/proc/%d/status (command '%s')", netdata_configured_host_prefix, p->pid,
  660. p->comm);
  661. break;
  662. case PID_LOG_CMDLINE:
  663. error(
  664. "Cannot process %s/proc/%d/cmdline (command '%s')", netdata_configured_host_prefix, p->pid,
  665. p->comm);
  666. break;
  667. case PID_LOG_FDS:
  668. error(
  669. "Cannot process entries in %s/proc/%d/fd (command '%s')", netdata_configured_host_prefix,
  670. p->pid, p->comm);
  671. break;
  672. case PID_LOG_STAT:
  673. break;
  674. default:
  675. error("unhandled error for pid %d, command '%s'", p->pid, p->comm);
  676. break;
  677. }
  678. }
  679. }
  680. errno = 0;
  681. } else if (unlikely(p->log_thrown & log)) {
  682. // error("unsetting log %u on pid %d", log, p->pid);
  683. p->log_thrown &= ~log;
  684. }
  685. return status;
  686. }
  687. /**
  688. * Get PID entry
  689. *
  690. * Get or allocate the PID entry for the specified pid.
  691. *
  692. * @param pid the pid to search the data.
  693. *
  694. * @return It returns the pid entry structure
  695. */
  696. static inline struct ebpf_pid_stat *get_pid_entry(pid_t pid)
  697. {
  698. if (unlikely(ebpf_all_pids[pid]))
  699. return ebpf_all_pids[pid];
  700. struct ebpf_pid_stat *p = ebpf_pid_stat_get();
  701. if (likely(ebpf_root_of_pids))
  702. ebpf_root_of_pids->prev = p;
  703. p->next = ebpf_root_of_pids;
  704. ebpf_root_of_pids = p;
  705. p->pid = pid;
  706. ebpf_all_pids[pid] = p;
  707. ebpf_all_pids_count++;
  708. return p;
  709. }
  710. /**
  711. * Assign the PID to a target.
  712. *
  713. * @param p the pid_stat structure to assign for a target.
  714. */
  715. static inline void assign_target_to_pid(struct ebpf_pid_stat *p)
  716. {
  717. targets_assignment_counter++;
  718. uint32_t hash = simple_hash(p->comm);
  719. size_t pclen = strlen(p->comm);
  720. struct ebpf_target *w;
  721. for (w = apps_groups_root_target; w; w = w->next) {
  722. // if(debug_enabled || (p->target && p->target->debug_enabled)) debug_log_int("\t\tcomparing '%s' with '%s'", w->compare, p->comm);
  723. // find it - 4 cases:
  724. // 1. the target is not a pattern
  725. // 2. the target has the prefix
  726. // 3. the target has the suffix
  727. // 4. the target is something inside cmdline
  728. if (unlikely(
  729. ((!w->starts_with && !w->ends_with && w->comparehash == hash && !strcmp(w->compare, p->comm)) ||
  730. (w->starts_with && !w->ends_with && !strncmp(w->compare, p->comm, w->comparelen)) ||
  731. (!w->starts_with && w->ends_with && pclen >= w->comparelen && !strcmp(w->compare, &p->comm[pclen - w->comparelen])) ||
  732. (proc_pid_cmdline_is_needed && w->starts_with && w->ends_with && p->cmdline && strstr(p->cmdline, w->compare))))) {
  733. if (w->target)
  734. p->target = w->target;
  735. else
  736. p->target = w;
  737. if (debug_enabled || (p->target && p->target->debug_enabled))
  738. debug_log_int("%s linked to target %s", p->comm, p->target->name);
  739. break;
  740. }
  741. }
  742. }
  743. // ----------------------------------------------------------------------------
  744. // update pids from proc
  745. /**
  746. * Read cmd line from /proc/PID/cmdline
  747. *
  748. * @param p the ebpf_pid_stat_structure.
  749. *
  750. * @return It returns 1 on success and 0 otherwise.
  751. */
  752. static inline int read_proc_pid_cmdline(struct ebpf_pid_stat *p)
  753. {
  754. static char cmdline[MAX_CMDLINE + 1];
  755. if (unlikely(!p->cmdline_filename)) {
  756. char filename[FILENAME_MAX + 1];
  757. snprintfz(filename, FILENAME_MAX, "%s/proc/%d/cmdline", netdata_configured_host_prefix, p->pid);
  758. p->cmdline_filename = strdupz(filename);
  759. }
  760. int fd = open(p->cmdline_filename, procfile_open_flags, 0666);
  761. if (unlikely(fd == -1))
  762. goto cleanup;
  763. ssize_t i, bytes = read(fd, cmdline, MAX_CMDLINE);
  764. close(fd);
  765. if (unlikely(bytes < 0))
  766. goto cleanup;
  767. cmdline[bytes] = '\0';
  768. for (i = 0; i < bytes; i++) {
  769. if (unlikely(!cmdline[i]))
  770. cmdline[i] = ' ';
  771. }
  772. if (p->cmdline)
  773. freez(p->cmdline);
  774. p->cmdline = strdupz(cmdline);
  775. debug_log("Read file '%s' contents: %s", p->cmdline_filename, p->cmdline);
  776. return 1;
  777. cleanup:
  778. // copy the command to the command line
  779. if (p->cmdline)
  780. freez(p->cmdline);
  781. p->cmdline = strdupz(p->comm);
  782. return 0;
  783. }
  784. /**
  785. * Read information from /proc/PID/stat and /proc/PID/cmdline
  786. * Assign target to pid
  787. *
  788. * @param p the pid stat structure to store the data.
  789. * @param ptr an useless argument.
  790. */
  791. static inline int read_proc_pid_stat(struct ebpf_pid_stat *p, void *ptr)
  792. {
  793. UNUSED(ptr);
  794. static procfile *ff = NULL;
  795. if (unlikely(!p->stat_filename)) {
  796. char filename[FILENAME_MAX + 1];
  797. snprintfz(filename, FILENAME_MAX, "%s/proc/%d/stat", netdata_configured_host_prefix, p->pid);
  798. p->stat_filename = strdupz(filename);
  799. }
  800. int set_quotes = (!ff) ? 1 : 0;
  801. struct stat statbuf;
  802. if (stat(p->stat_filename, &statbuf))
  803. return 0;
  804. ff = procfile_reopen(ff, p->stat_filename, NULL, PROCFILE_FLAG_NO_ERROR_ON_FILE_IO);
  805. if (unlikely(!ff))
  806. return 0;
  807. if (unlikely(set_quotes))
  808. procfile_set_open_close(ff, "(", ")");
  809. ff = procfile_readall(ff);
  810. if (unlikely(!ff))
  811. return 0;
  812. p->last_stat_collected_usec = p->stat_collected_usec;
  813. p->stat_collected_usec = now_monotonic_usec();
  814. calls_counter++;
  815. char *comm = procfile_lineword(ff, 0, 1);
  816. p->ppid = (int32_t)str2pid_t(procfile_lineword(ff, 0, 3));
  817. if (strcmp(p->comm, comm) != 0) {
  818. if (unlikely(debug_enabled)) {
  819. if (p->comm[0])
  820. debug_log("\tpid %d (%s) changed name to '%s'", p->pid, p->comm, comm);
  821. else
  822. debug_log("\tJust added %d (%s)", p->pid, comm);
  823. }
  824. strncpyz(p->comm, comm, EBPF_MAX_COMPARE_NAME);
  825. // /proc/<pid>/cmdline
  826. if (likely(proc_pid_cmdline_is_needed))
  827. managed_log(p, PID_LOG_CMDLINE, read_proc_pid_cmdline(p));
  828. assign_target_to_pid(p);
  829. }
  830. if (unlikely(debug_enabled || (p->target && p->target->debug_enabled)))
  831. debug_log_int(
  832. "READ PROC/PID/STAT: %s/proc/%d/stat, process: '%s' on target '%s' (dt=%llu)",
  833. netdata_configured_host_prefix, p->pid, p->comm, (p->target) ? p->target->name : "UNSET",
  834. p->stat_collected_usec - p->last_stat_collected_usec);
  835. return 1;
  836. }
  837. /**
  838. * Collect data for PID
  839. *
  840. * @param pid the current pid that we are working
  841. * @param ptr a NULL value
  842. *
  843. * @return It returns 1 on success and 0 otherwise
  844. */
  845. static inline int collect_data_for_pid(pid_t pid, void *ptr)
  846. {
  847. if (unlikely(pid < 0 || pid > pid_max)) {
  848. error("Invalid pid %d read (expected %d to %d). Ignoring process.", pid, 0, pid_max);
  849. return 0;
  850. }
  851. struct ebpf_pid_stat *p = get_pid_entry(pid);
  852. if (unlikely(!p || p->read))
  853. return 0;
  854. p->read = 1;
  855. if (unlikely(!managed_log(p, PID_LOG_STAT, read_proc_pid_stat(p, ptr))))
  856. // there is no reason to proceed if we cannot get its status
  857. return 0;
  858. // check its parent pid
  859. if (unlikely(p->ppid < 0 || p->ppid > pid_max)) {
  860. error("Pid %d (command '%s') states invalid parent pid %d. Using 0.", pid, p->comm, p->ppid);
  861. p->ppid = 0;
  862. }
  863. // mark it as updated
  864. p->updated = 1;
  865. p->keep = 0;
  866. p->keeploops = 0;
  867. return 1;
  868. }
  869. /**
  870. * Fill link list of parents with children PIDs
  871. */
  872. static inline void link_all_processes_to_their_parents(void)
  873. {
  874. struct ebpf_pid_stat *p, *pp;
  875. // link all children to their parents
  876. // and update children count on parents
  877. for (p = ebpf_root_of_pids; p; p = p->next) {
  878. // for each process found
  879. p->sortlist = 0;
  880. p->parent = NULL;
  881. if (unlikely(!p->ppid)) {
  882. p->parent = NULL;
  883. continue;
  884. }
  885. pp = ebpf_all_pids[p->ppid];
  886. if (likely(pp)) {
  887. p->parent = pp;
  888. pp->children_count++;
  889. if (unlikely(debug_enabled || (p->target && p->target->debug_enabled)))
  890. debug_log_int(
  891. "child %d (%s, %s) on target '%s' has parent %d (%s, %s).", p->pid, p->comm,
  892. p->updated ? "running" : "exited", (p->target) ? p->target->name : "UNSET", pp->pid, pp->comm,
  893. pp->updated ? "running" : "exited");
  894. } else {
  895. p->parent = NULL;
  896. debug_log("pid %d %s states parent %d, but the later does not exist.", p->pid, p->comm, p->ppid);
  897. }
  898. }
  899. }
  900. /**
  901. * Aggregate PIDs to targets.
  902. */
  903. static void apply_apps_groups_targets_inheritance(void)
  904. {
  905. struct ebpf_pid_stat *p = NULL;
  906. // children that do not have a target
  907. // inherit their target from their parent
  908. int found = 1, loops = 0;
  909. while (found) {
  910. if (unlikely(debug_enabled))
  911. loops++;
  912. found = 0;
  913. for (p = ebpf_root_of_pids; p; p = p->next) {
  914. // if this process does not have a target
  915. // and it has a parent
  916. // and its parent has a target
  917. // then, set the parent's target to this process
  918. if (unlikely(!p->target && p->parent && p->parent->target)) {
  919. p->target = p->parent->target;
  920. found++;
  921. if (debug_enabled || (p->target && p->target->debug_enabled))
  922. debug_log_int(
  923. "TARGET INHERITANCE: %s is inherited by %d (%s) from its parent %d (%s).", p->target->name,
  924. p->pid, p->comm, p->parent->pid, p->parent->comm);
  925. }
  926. }
  927. }
  928. // find all the procs with 0 childs and merge them to their parents
  929. // repeat, until nothing more can be done.
  930. int sortlist = 1;
  931. found = 1;
  932. while (found) {
  933. if (unlikely(debug_enabled))
  934. loops++;
  935. found = 0;
  936. for (p = ebpf_root_of_pids; p; p = p->next) {
  937. if (unlikely(!p->sortlist && !p->children_count))
  938. p->sortlist = sortlist++;
  939. if (unlikely(
  940. !p->children_count // if this process does not have any children
  941. && !p->merged // and is not already merged
  942. && p->parent // and has a parent
  943. && p->parent->children_count // and its parent has children
  944. // and the target of this process and its parent is the same,
  945. // or the parent does not have a target
  946. && (p->target == p->parent->target || !p->parent->target) &&
  947. p->ppid != INIT_PID // and its parent is not init
  948. )) {
  949. // mark it as merged
  950. p->parent->children_count--;
  951. p->merged = 1;
  952. // the parent inherits the child's target, if it does not have a target itself
  953. if (unlikely(p->target && !p->parent->target)) {
  954. p->parent->target = p->target;
  955. if (debug_enabled || (p->target && p->target->debug_enabled))
  956. debug_log_int(
  957. "TARGET INHERITANCE: %s is inherited by %d (%s) from its child %d (%s).", p->target->name,
  958. p->parent->pid, p->parent->comm, p->pid, p->comm);
  959. }
  960. found++;
  961. }
  962. }
  963. debug_log("TARGET INHERITANCE: merged %d processes", found);
  964. }
  965. // init goes always to default target
  966. if (ebpf_all_pids[INIT_PID])
  967. ebpf_all_pids[INIT_PID]->target = apps_groups_default_target;
  968. // pid 0 goes always to default target
  969. if (ebpf_all_pids[0])
  970. ebpf_all_pids[0]->target = apps_groups_default_target;
  971. // give a default target on all top level processes
  972. if (unlikely(debug_enabled))
  973. loops++;
  974. for (p = ebpf_root_of_pids; p; p = p->next) {
  975. // if the process is not merged itself
  976. // then is is a top level process
  977. if (unlikely(!p->merged && !p->target))
  978. p->target = apps_groups_default_target;
  979. // make sure all processes have a sortlist
  980. if (unlikely(!p->sortlist))
  981. p->sortlist = sortlist++;
  982. }
  983. if (ebpf_all_pids[1])
  984. ebpf_all_pids[1]->sortlist = sortlist++;
  985. // give a target to all merged child processes
  986. found = 1;
  987. while (found) {
  988. if (unlikely(debug_enabled))
  989. loops++;
  990. found = 0;
  991. for (p = ebpf_root_of_pids; p; p = p->next) {
  992. if (unlikely(!p->target && p->merged && p->parent && p->parent->target)) {
  993. p->target = p->parent->target;
  994. found++;
  995. if (debug_enabled || (p->target && p->target->debug_enabled))
  996. debug_log_int(
  997. "TARGET INHERITANCE: %s is inherited by %d (%s) from its parent %d (%s) at phase 2.",
  998. p->target->name, p->pid, p->comm, p->parent->pid, p->parent->comm);
  999. }
  1000. }
  1001. }
  1002. debug_log("apply_apps_groups_targets_inheritance() made %d loops on the process tree", loops);
  1003. }
  1004. /**
  1005. * Update target timestamp.
  1006. *
  1007. * @param root the targets that will be updated.
  1008. */
  1009. static inline void post_aggregate_targets(struct ebpf_target *root)
  1010. {
  1011. struct ebpf_target *w;
  1012. for (w = root; w; w = w->next) {
  1013. if (w->collected_starttime) {
  1014. if (!w->starttime || w->collected_starttime < w->starttime) {
  1015. w->starttime = w->collected_starttime;
  1016. }
  1017. } else {
  1018. w->starttime = 0;
  1019. }
  1020. }
  1021. }
  1022. /**
  1023. * Remove PID from the link list.
  1024. *
  1025. * @param pid the PID that will be removed.
  1026. */
  1027. static inline void del_pid_entry(pid_t pid)
  1028. {
  1029. struct ebpf_pid_stat *p = ebpf_all_pids[pid];
  1030. if (unlikely(!p)) {
  1031. error("attempted to free pid %d that is not allocated.", pid);
  1032. return;
  1033. }
  1034. debug_log("process %d %s exited, deleting it.", pid, p->comm);
  1035. if (ebpf_root_of_pids == p)
  1036. ebpf_root_of_pids = p->next;
  1037. if (p->next)
  1038. p->next->prev = p->prev;
  1039. if (p->prev)
  1040. p->prev->next = p->next;
  1041. freez(p->stat_filename);
  1042. freez(p->status_filename);
  1043. freez(p->io_filename);
  1044. freez(p->cmdline_filename);
  1045. freez(p->cmdline);
  1046. ebpf_pid_stat_release(p);
  1047. ebpf_all_pids[pid] = NULL;
  1048. ebpf_all_pids_count--;
  1049. }
  1050. /**
  1051. * Get command string associated with a PID.
  1052. * This can only safely be used when holding the `collect_data_mutex` lock.
  1053. *
  1054. * @param pid the pid to search the data.
  1055. * @param n the maximum amount of bytes to copy into dest.
  1056. * if this is greater than the size of the command, it is clipped.
  1057. * @param dest the target memory buffer to write the command into.
  1058. * @return -1 if the PID hasn't been scraped yet, 0 otherwise.
  1059. */
  1060. int get_pid_comm(pid_t pid, size_t n, char *dest)
  1061. {
  1062. struct ebpf_pid_stat *stat;
  1063. stat = ebpf_all_pids[pid];
  1064. if (unlikely(stat == NULL)) {
  1065. return -1;
  1066. }
  1067. if (unlikely(n > sizeof(stat->comm))) {
  1068. n = sizeof(stat->comm);
  1069. }
  1070. strncpyz(dest, stat->comm, n);
  1071. return 0;
  1072. }
  1073. /**
  1074. * Cleanup variable from other threads
  1075. *
  1076. * @param pid current pid.
  1077. */
  1078. void cleanup_variables_from_other_threads(uint32_t pid)
  1079. {
  1080. // Clean socket structures
  1081. if (socket_bandwidth_curr) {
  1082. ebpf_socket_release(socket_bandwidth_curr[pid]);
  1083. socket_bandwidth_curr[pid] = NULL;
  1084. }
  1085. // Clean cachestat structure
  1086. if (cachestat_pid) {
  1087. ebpf_cachestat_release(cachestat_pid[pid]);
  1088. cachestat_pid[pid] = NULL;
  1089. }
  1090. // Clean directory cache structure
  1091. if (dcstat_pid) {
  1092. ebpf_dcstat_release(dcstat_pid[pid]);
  1093. dcstat_pid[pid] = NULL;
  1094. }
  1095. // Clean swap structure
  1096. if (swap_pid) {
  1097. freez(swap_pid[pid]);
  1098. swap_pid[pid] = NULL;
  1099. }
  1100. // Clean vfs structure
  1101. if (vfs_pid) {
  1102. ebpf_vfs_release(vfs_pid[pid]);
  1103. vfs_pid[pid] = NULL;
  1104. }
  1105. // Clean fd structure
  1106. if (fd_pid) {
  1107. ebpf_fd_release(fd_pid[pid]);
  1108. fd_pid[pid] = NULL;
  1109. }
  1110. // Clean shm structure
  1111. if (shm_pid) {
  1112. ebpf_shm_release(shm_pid[pid]);
  1113. shm_pid[pid] = NULL;
  1114. }
  1115. }
  1116. /**
  1117. * Remove PIDs when they are not running more.
  1118. */
  1119. void cleanup_exited_pids()
  1120. {
  1121. struct ebpf_pid_stat *p = NULL;
  1122. for (p = ebpf_root_of_pids; p;) {
  1123. if (!p->updated && (!p->keep || p->keeploops > 0)) {
  1124. if (unlikely(debug_enabled && (p->keep || p->keeploops)))
  1125. debug_log(" > CLEANUP cannot keep exited process %d (%s) anymore - removing it.", p->pid, p->comm);
  1126. pid_t r = p->pid;
  1127. p = p->next;
  1128. // Clean process structure
  1129. ebpf_process_stat_release(global_process_stats[r]);
  1130. global_process_stats[r] = NULL;
  1131. cleanup_variables_from_other_threads(r);
  1132. del_pid_entry(r);
  1133. } else {
  1134. if (unlikely(p->keep))
  1135. p->keeploops++;
  1136. p->keep = 0;
  1137. p = p->next;
  1138. }
  1139. }
  1140. }
  1141. /**
  1142. * Read proc filesystem for the first time.
  1143. *
  1144. * @return It returns 0 on success and -1 otherwise.
  1145. */
  1146. static inline void read_proc_filesystem()
  1147. {
  1148. char dirname[FILENAME_MAX + 1];
  1149. snprintfz(dirname, FILENAME_MAX, "%s/proc", netdata_configured_host_prefix);
  1150. DIR *dir = opendir(dirname);
  1151. if (!dir)
  1152. return;
  1153. struct dirent *de = NULL;
  1154. while ((de = readdir(dir))) {
  1155. char *endptr = de->d_name;
  1156. if (unlikely(de->d_type != DT_DIR || de->d_name[0] < '0' || de->d_name[0] > '9'))
  1157. continue;
  1158. pid_t pid = (pid_t)strtoul(de->d_name, &endptr, 10);
  1159. // make sure we read a valid number
  1160. if (unlikely(endptr == de->d_name || *endptr != '\0'))
  1161. continue;
  1162. collect_data_for_pid(pid, NULL);
  1163. }
  1164. closedir(dir);
  1165. }
  1166. /**
  1167. * Aggregated PID on target
  1168. *
  1169. * @param w the target output
  1170. * @param p the pid with information to update
  1171. * @param o never used
  1172. */
  1173. static inline void aggregate_pid_on_target(struct ebpf_target *w, struct ebpf_pid_stat *p, struct ebpf_target *o)
  1174. {
  1175. UNUSED(o);
  1176. if (unlikely(!p->updated)) {
  1177. // the process is not running
  1178. return;
  1179. }
  1180. if (unlikely(!w)) {
  1181. error("pid %d %s was left without a target!", p->pid, p->comm);
  1182. return;
  1183. }
  1184. w->processes++;
  1185. struct ebpf_pid_on_target *pid_on_target = mallocz(sizeof(struct ebpf_pid_on_target));
  1186. pid_on_target->pid = p->pid;
  1187. pid_on_target->next = w->root_pid;
  1188. w->root_pid = pid_on_target;
  1189. }
  1190. /**
  1191. * Process Accumulator
  1192. *
  1193. * Sum all values read from kernel and store in the first address.
  1194. *
  1195. * @param out the vector with read values.
  1196. * @param maps_per_core do I need to read all cores?
  1197. */
  1198. void ebpf_process_apps_accumulator(ebpf_process_stat_t *out, int maps_per_core)
  1199. {
  1200. int i, end = (maps_per_core) ? ebpf_nprocs : 1;
  1201. ebpf_process_stat_t *total = &out[0];
  1202. for (i = 1; i < end; i++) {
  1203. ebpf_process_stat_t *w = &out[i];
  1204. total->exit_call += w->exit_call;
  1205. total->task_err += w->task_err;
  1206. total->create_thread += w->create_thread;
  1207. total->create_process += w->create_process;
  1208. total->release_call += w->release_call;
  1209. }
  1210. }
  1211. /**
  1212. * Collect data for all process
  1213. *
  1214. * Read data from hash table and store it in appropriate vectors.
  1215. * It also creates the link between targets and PIDs.
  1216. *
  1217. * @param tbl_pid_stats_fd The mapped file descriptor for the hash table.
  1218. * @param maps_per_core do I have hash maps per core?
  1219. */
  1220. void collect_data_for_all_processes(int tbl_pid_stats_fd, int maps_per_core)
  1221. {
  1222. if (unlikely(!ebpf_all_pids))
  1223. return;
  1224. struct ebpf_pid_stat *pids = ebpf_root_of_pids; // global list of all processes running
  1225. while (pids) {
  1226. if (pids->updated_twice) {
  1227. pids->read = 0; // mark it as not read, so that collect_data_for_pid() will read it
  1228. pids->updated = 0;
  1229. pids->merged = 0;
  1230. pids->children_count = 0;
  1231. pids->parent = NULL;
  1232. } else {
  1233. if (pids->updated)
  1234. pids->updated_twice = 1;
  1235. }
  1236. pids = pids->next;
  1237. }
  1238. read_proc_filesystem();
  1239. uint32_t key;
  1240. pids = ebpf_root_of_pids; // global list of all processes running
  1241. // while (bpf_map_get_next_key(tbl_pid_stats_fd, &key, &next_key) == 0) {
  1242. size_t length = sizeof(ebpf_process_stat_t);
  1243. if (maps_per_core)
  1244. length *= ebpf_nprocs;
  1245. while (pids) {
  1246. key = pids->pid;
  1247. ebpf_process_stat_t *w = global_process_stats[key];
  1248. if (!w) {
  1249. w = ebpf_process_stat_get();
  1250. global_process_stats[key] = w;
  1251. }
  1252. if (bpf_map_lookup_elem(tbl_pid_stats_fd, &key, process_stat_vector)) {
  1253. // Clean Process structures
  1254. ebpf_process_stat_release(w);
  1255. global_process_stats[key] = NULL;
  1256. cleanup_variables_from_other_threads(key);
  1257. pids = pids->next;
  1258. continue;
  1259. }
  1260. ebpf_process_apps_accumulator(process_stat_vector, maps_per_core);
  1261. memcpy(w, process_stat_vector, sizeof(ebpf_process_stat_t));
  1262. memset(process_stat_vector, 0, length);
  1263. pids = pids->next;
  1264. }
  1265. link_all_processes_to_their_parents();
  1266. apply_apps_groups_targets_inheritance();
  1267. apps_groups_targets_count = zero_all_targets(apps_groups_root_target);
  1268. // this has to be done, before the cleanup
  1269. // // concentrate everything on the targets
  1270. for (pids = ebpf_root_of_pids; pids; pids = pids->next)
  1271. aggregate_pid_on_target(pids->target, pids, NULL);
  1272. post_aggregate_targets(apps_groups_root_target);
  1273. }