@cryptotaxi247 / netdata-1 / commits / 0b09b6199

VFS new thread (#11187)

Split process thread in two different threads.

thiagoftsm committed May 28, 2021 at 18:57 UTC 0b09b6199715870df7d394545709f7ff009bdee9
18 files changed +1245 -394
CMakeLists.txt
+2
@@ -498,6 +498,8 @@ set(EBPF_PROCESS_PLUGIN_FILES
498 collectors/ebpf.plugin/ebpf_sync.h
499 collectors/ebpf.plugin/ebpf_swap.c
500 collectors/ebpf.plugin/ebpf_swap.h
501 + collectors/ebpf.plugin/ebpf_vfs.c
502 + collectors/ebpf.plugin/ebpf_vfs.h
503 collectors/ebpf.plugin/ebpf_apps.c
504 collectors/ebpf.plugin/ebpf_apps.h
505 )
Makefile.am
+2
@@ -297,6 +297,8 @@ EBPF_PLUGIN_FILES = \
297 collectors/ebpf.plugin/ebpf_sync.h \
298 collectors/ebpf.plugin/ebpf_swap.c \
299 collectors/ebpf.plugin/ebpf_swap.h \
300 + collectors/ebpf.plugin/ebpf_vfs.c \
301 + collectors/ebpf.plugin/ebpf_vfs.h \
302 collectors/ebpf.plugin/ebpf.h \
303 collectors/ebpf.plugin/ebpf_apps.c \
304 collectors/ebpf.plugin/ebpf_apps.h \
collectors/all.h
+11
@@ -138,6 +138,17 @@
138 #define NETDATA_CHART_PRIO_MDSTAT_FINISH 2105
139 #define NETDATA_CHART_PRIO_MDSTAT_SPEED 2106
140
141 +// Filesystem
142 +#define NETDATA_CHART_PRIO_FILESYSTEM_VFS_CLEAN 2150
143 +#define NETDATA_CHART_PRIO_FILESYSTEM_VFS_IO_COUNT 2151
144 +#define NETDATA_CHART_PRIO_FILESYSTEM_VFS_IO_BYTES 2152
145 +#define NETDATA_CHART_PRIO_FILESYSTEM_VFS_IO_EBYTES 2153
146 +#define NETDATA_CHART_PRIO_FILESYSTEM_VFS_IO_FSYNC 2154
147 +#define NETDATA_CHART_PRIO_FILESYSTEM_VFS_IO_EFSYNC 2155
148 +#define NETDATA_CHART_PRIO_FILESYSTEM_VFS_IO_OPEN 2156
149 +#define NETDATA_CHART_PRIO_FILESYSTEM_VFS_IO_EOPEN 2157
150 +#define NETDATA_CHART_PRIO_FILESYSTEM_VFS_IO_CREATE 2158
151 +#define NETDATA_CHART_PRIO_FILESYSTEM_VFS_IO_ECREATE 2159
152
153 // NFS (server)
154
collectors/ebpf.plugin/Makefile.am
+1
@@ -38,4 +38,5 @@ dist_ebpfconfig_DATA = \
38 ebpf.d/process.conf \
39 ebpf.d/sync.conf \
40 ebpf.d/swap.conf \
41 + ebpf.d/vfs.conf \
42 $(NULL)
collectors/ebpf.plugin/README.md
+16 -1
@@ -82,6 +82,19 @@ The Agent displays the number of bytes written as negative because they are movi
82
83 The Agent counts and shows the number of instances where a running program experiences a read or write error.
84
85 +#### Create
86 +
87 +This chart shows the number of calls for `vfs_create`. This function is responsible to create files.
88 +
89 +#### Synchronization
90 +
91 +This chart shows the number of calls for `vfs_fsync`. This function is responsible to perform a fsync or fdatasync
92 +on a file.
93 +
94 +#### Open
95 +
96 +This chart shows the number of calls for `vfs_open`. This function is responsible to open files.
97 +
98 ### Process
99
100 For this group, the eBPF collector monitors process/thread creation and process end, and then displays any errors in the
@@ -203,11 +216,12 @@ The eBPF collector enables and runs the following eBPF programs by default:
216 - `dcstat` : This eBPF program creates charts that show information about file access using directory cache. It appends
217 `kprobes` for `lookup_fast()` and `d_lookup()` to identify if files are inside directory cache, outside and
218 files are not found.
206 -- `process`: This eBPF program creates charts that show information about process creation, VFS IO, and files removed.
219 +- `process`: This eBPF program creates charts that show information about process creation, calls to open files.
220 When in `return` mode, it also creates charts showing errors when these operations are executed.
221 - `network viewer`: This eBPF program creates charts with information about `TCP` and `UDP` functions, including the
222 bandwidth consumed by each.
223 - `sync`: Montitor calls for syscalls sync(2), fsync(2), fdatasync(2), syncfs(2), msync(2), and sync_file_range(2).
224 +- `vfs`: This eBPF program creates charts that show information about VFS (Virtual File System) functions.
225
226 ## Thread configuration
227
@@ -229,6 +243,7 @@ The following configuration files are available:
243 - `network.conf`: Configuration for the `network viewer` thread. This config file overwrites the global options and
244 also lets you specify which network the eBPF collector monitors.
245 - `sync.conf`: Configuration for the `sync` thread.
246 +- `vfs.conf`: Configuration for the `vfs` thread.
247
248 ### Network configuration
249
collectors/ebpf.plugin/ebpf.c
+31
@@ -104,6 +104,11 @@ ebpf_module_t ebpf_modules[] = {
104 .update_time = 1, .global_charts = 1, .apps_charts = 1, .mode = MODE_ENTRY,
105 .optional = 0, .apps_routine = ebpf_swap_create_apps_charts, .maps = NULL,
106 .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL },
107 + { .thread_name = "vfs", .config_name = "swap", .enabled = 0, .start_routine = ebpf_vfs_thread,
108 + .update_time = 1, .global_charts = 1, .apps_charts = 1, .mode = MODE_ENTRY,
109 + .optional = 0, .apps_routine = ebpf_vfs_create_apps_charts, .maps = NULL,
110 + .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &vfs_config,
111 + .config_file = NETDATA_DIRECTORY_VFS_CONFIG_FILE },
112 { .thread_name = NULL, .enabled = 0, .start_routine = NULL, .update_time = 1,
113 .global_charts = 0, .apps_charts = 1, .mode = MODE_ENTRY,
114 .optional = 0, .apps_routine = NULL, .maps = NULL, .pid_map_size = 0, .names = NULL,
@@ -172,6 +177,12 @@ static void ebpf_exit(int sig)
177 freez(swap_pid);
178 }
179
180 + if (ebpf_modules[EBPF_MODULE_VFS_IDX].enabled) {
181 + ebpf_modules[EBPF_MODULE_VFS_IDX].enabled = 0;
182 + clean_vfs_pid_structures();
183 + freez(vfs_pid);
184 + }
185 +
186 /*
187 int ret = fork();
188 if (ret < 0) // error
@@ -624,6 +635,8 @@ void ebpf_print_help()
635 "\n"
636 " --swap or -w Enable chart related to swap run time.\n"
637 "\n"
638 + " --vfs or -f Enable chart related to vfs run time.\n"
639 + "\n"
640 VERSION,
641 (year >= 116) ? year + 1900 : 2020);
642 }
@@ -920,6 +933,13 @@ static void read_collector_values(int *disable_apps)
933 started++;
934 }
935
936 + enabled = appconfig_get_boolean(&collector_config, EBPF_PROGRAMS_SECTION, "vfs",
937 + CONFIG_BOOLEAN_NO);
938 + if (enabled) {
939 + ebpf_enable_chart(EBPF_MODULE_VFS_IDX, *disable_apps);
940 + started++;
941 + }
942 +
943 if (!started){
944 ebpf_enable_all_charts(*disable_apps);
945 // Read network viewer section
@@ -1009,6 +1029,7 @@ static void parse_args(int argc, char **argv)
1029 {"return", no_argument, 0, 'r' },
1030 {"sync", no_argument, 0, 's' },
1031 {"swap", no_argument, 0, 'w' },
1032 + {"vfs", no_argument, 0, 'f' },
1033 {0, 0, 0, 0}
1034 };
1035
@@ -1107,6 +1128,14 @@ static void parse_args(int argc, char **argv)
1128 ebpf_enable_chart(EBPF_MODULE_SWAP_IDX, disable_apps);
1129 #ifdef NETDATA_INTERNAL_CHECKS
1130 info("EBPF enabling \"swap\" chart, because it was started with the option \"--swap\" or \"-w\".");
1131 +#endif
1132 + break;
1133 + }
1134 + case 'f': {
1135 + enabled = 1;
1136 + ebpf_enable_chart(EBPF_MODULE_VFS_IDX, disable_apps);
1137 +#ifdef NETDATA_INTERNAL_CHECKS
1138 + info("EBPF enabling \"vfs\" chart, because it was started with the option \"--vfs\" or \"-f\".");
1139 #endif
1140 break;
1141 }
@@ -1254,6 +1283,8 @@ int main(int argc, char **argv)
1283 NULL, NULL, ebpf_modules[EBPF_MODULE_DCSTAT_IDX].start_routine},
1284 {"EBPF SWAP" , NULL, NULL, 1,
1285 NULL, NULL, ebpf_modules[EBPF_MODULE_SWAP_IDX].start_routine},
1286 + {"EBPF VFS" , NULL, NULL, 1,
1287 + NULL, NULL, ebpf_modules[EBPF_MODULE_VFS_IDX].start_routine},
1288 {NULL , NULL, NULL, 0,
1289 NULL, NULL, NULL}
1290 };
collectors/ebpf.plugin/ebpf.d.conf
+4 -3
@@ -26,12 +26,13 @@
26 # The eBPF collector enables and runs the following eBPF programs by default:
27 #
28 # `cachestat`: Make charts for kernel functions related to page cache.
29 -# `process` : This eBPF program creates charts that show information about process creation, VFS IO, and
30 -# files removed.
29 +# `process` : This eBPF program creates charts that show information about process creation, and file manipulation.
30 # `socket` : This eBPF program creates charts with information about `TCP` and `UDP` functions, including the
31 # bandwidth consumed by each.
32 # `sync` : Montitor calls for syscall sync(2).
33 # `swap` : Monitor calls for internal swap functions.
34 +# `vfs` : This eBPF program creates charts that show information about process VFS IO, VFS file manipulation and
35 +# files removed.
36 [ebpf programs]
37 cachestat = no
38 dcstat = no
@@ -39,5 +40,5 @@
40 socket = yes
41 sync = yes
42 swap = no
43 + vfs = yes
44 network connections = no
43 -
collectors/ebpf.plugin/ebpf.d/vfs.conf new
+14
@@ -0,0 +1,14 @@
1 +# The `ebpf load mode` option accepts the following values :
2 +# `entry` : The eBPF collector only monitors calls for the functions, and does not show charts related to errors.
3 +# `return : In the `return` mode, the eBPF collector monitors the same kernel functions as `entry`, but also creates
4 +# new charts for the return of these functions, such as errors.
5 +#
6 +# The eBPF collector also creates charts for each running application through an integration with the `apps plugin`.
7 +# If you want to disable the integration with `apps.plugin` along with the above charts, change the setting `apps` to
8 +# 'no'.
9 +#
10 +[global]
11 + ebpf load mode = entry
12 + apps = yes
13 + update every = 1
14 + pid table size = 32768
collectors/ebpf.plugin/ebpf.h
+2 -1
@@ -79,7 +79,8 @@ enum ebpf_module_indexes {
79 EBPF_MODULE_CACHESTAT_IDX,
80 EBPF_MODULE_SYNC_IDX,
81 EBPF_MODULE_DCSTAT_IDX,
82 - EBPF_MODULE_SWAP_IDX
82 + EBPF_MODULE_SWAP_IDX,
83 + EBPF_MODULE_VFS_IDX
84 };
85
86 // Copied from musl header
collectors/ebpf.plugin/ebpf_apps.c
+6
@@ -939,6 +939,12 @@ void cleanup_variables_from_other_threads(uint32_t pid)
939 freez(swap_pid[pid]);
940 swap_pid[pid] = NULL;
941 }
942 +
943 + // Clean vfs structure
944 + if (vfs_pid) {
945 + freez(vfs_pid[pid]);
946 + vfs_pid[pid] = NULL;
947 + }
948 }
949
950 /**
collectors/ebpf.plugin/ebpf_apps.h
+2 -16
@@ -23,6 +23,7 @@
23 #include "ebpf_cachestat.h"
24 #include "ebpf_sync.h"
25 #include "ebpf_swap.h"
26 +#include "ebpf_vfs.h"
27
28 #define MAX_COMPARE_NAME 100
29 #define MAX_NAME 100
@@ -115,6 +116,7 @@ struct target {
116 netdata_publish_cachestat_t cachestat;
117 netdata_publish_dcstat_t dcstat;
118 netdata_publish_swap_t swap;
119 + netdata_publish_vfs_t vfs;
120
121 /* These variables are not necessary for eBPF collector
122 kernel_uint_t minflt;
@@ -344,30 +346,14 @@ typedef struct ebpf_process_stat {
346
347 //Counter
348 uint32_t open_call;
347 - uint32_t write_call;
348 - uint32_t writev_call;
349 - uint32_t read_call;
350 - uint32_t readv_call;
351 - uint32_t unlink_call;
349 uint32_t exit_call;
350 uint32_t release_call;
351 uint32_t fork_call;
352 uint32_t clone_call;
353 uint32_t close_call;
354
358 - //Accumulator
359 - uint64_t write_bytes;
360 - uint64_t writev_bytes;
361 - uint64_t readv_bytes;
362 - uint64_t read_bytes;
363 -
355 //Counter
356 uint32_t open_err;
366 - uint32_t write_err;
367 - uint32_t writev_err;
368 - uint32_t read_err;
369 - uint32_t readv_err;
370 - uint32_t unlink_err;
357 uint32_t fork_err;
358 uint32_t clone_err;
359 uint32_t close_err;
collectors/ebpf.plugin/ebpf_process.c
+42 -294
@@ -11,11 +11,10 @@
11 *
12 *****************************************************************/
13
14 -static char *process_dimension_names[NETDATA_KEY_PUBLISH_PROCESS_END] = { "open", "close", "delete", "read", "write",
15 - "process", "task", "process", "thread" };
16 -static char *process_id_names[NETDATA_KEY_PUBLISH_PROCESS_END] = { "do_sys_open", "__close_fd", "vfs_unlink",
17 - "vfs_read", "vfs_write", "do_exit",
18 - "release_task", "_do_fork", "sys_clone" };
14 +static char *process_dimension_names[NETDATA_KEY_PUBLISH_PROCESS_END] = { "open", "close", "process",
15 + "task", "process", "thread" };
16 +static char *process_id_names[NETDATA_KEY_PUBLISH_PROCESS_END] = { "do_sys_open", "__close_fd", "do_exit",
17 + "release_task", "_do_fork", "sys_clone" };
18 static char *status[] = { "process", "zombie" };
19
20 static ebpf_local_maps_t process_maps[] = {{.name = "tbl_pid_stats", .internal_input = ND_EBPF_DEFAULT_PID_SIZE,
@@ -56,16 +55,16 @@ struct config process_config = { .first_section = NULL,
55 * @param pvc the second output structure with correlated dimensions
56 * @param input the structure with the input data.
57 */
59 -static void ebpf_update_global_publish(
60 - netdata_publish_syscall_t *publish, netdata_publish_vfs_common_t *pvc, netdata_syscall_stat_t *input)
58 +static void ebpf_update_global_publish(netdata_publish_syscall_t *publish, netdata_publish_vfs_common_t *pvc,
59 + netdata_syscall_stat_t *input)
60 {
61 netdata_publish_syscall_t *move = publish;
62 int selector = NETDATA_KEY_PUBLISH_PROCESS_OPEN;
63 while (move) {
65 - // Until NETDATA_KEY_PUBLISH_PROCESS_READ we are creating accumulators, so it is possible
64 + // Until NETDATA_KEY_PUBLISH_PROCESS_EXIT we are creating accumulators, so it is possible
65 // to use incremental charts, but after this we will do some math with the values, so we are storing
66 // absolute values
68 - if (selector < NETDATA_KEY_PUBLISH_PROCESS_READ) {
67 + if (selector < NETDATA_KEY_PUBLISH_PROCESS_EXIT) {
68 move->ncall = input->call;
69 move->nbyte = input->bytes;
70 move->nerr = input->ecall;
@@ -84,12 +83,11 @@ static void ebpf_update_global_publish(
83 selector++;
84 }
85
87 - pvc->write = -((long)publish[NETDATA_KEY_PUBLISH_PROCESS_WRITE].nbyte);
88 - pvc->read = (long)publish[NETDATA_KEY_PUBLISH_PROCESS_READ].nbyte;
89 -
90 - pvc->running = (long)publish[NETDATA_KEY_PUBLISH_PROCESS_FORK].ncall - (long)publish[NETDATA_KEY_PUBLISH_PROCESS_CLONE].ncall;
86 + pvc->running = (long)publish[NETDATA_KEY_PUBLISH_PROCESS_FORK].ncall -
87 + (long)publish[NETDATA_KEY_PUBLISH_PROCESS_CLONE].ncall;
88 publish[NETDATA_KEY_PUBLISH_PROCESS_RELEASE_TASK].ncall = -publish[NETDATA_KEY_PUBLISH_PROCESS_RELEASE_TASK].ncall;
92 - pvc->zombie = (long)publish[NETDATA_KEY_PUBLISH_PROCESS_EXIT].ncall + (long)publish[NETDATA_KEY_PUBLISH_PROCESS_RELEASE_TASK].ncall;
89 + pvc->zombie = (long)publish[NETDATA_KEY_PUBLISH_PROCESS_EXIT].ncall +
90 + (long)publish[NETDATA_KEY_PUBLISH_PROCESS_RELEASE_TASK].ncall;
91 }
92
93 /**
@@ -118,33 +116,20 @@ static void ebpf_process_send_data(ebpf_module_t *em)
116 netdata_publish_vfs_common_t pvc;
117 ebpf_update_global_publish(process_publish_aggregated, &pvc, process_aggregated_data);
118
121 - write_count_chart(
122 - NETDATA_FILE_OPEN_CLOSE_COUNT, NETDATA_EBPF_FAMILY, process_publish_aggregated, 2);
123 -
124 - write_count_chart(
125 - NETDATA_VFS_FILE_CLEAN_COUNT, NETDATA_EBPF_FAMILY, &process_publish_aggregated[NETDATA_DEL_START], 1);
126 -
127 - write_count_chart(
128 - NETDATA_VFS_FILE_IO_COUNT, NETDATA_EBPF_FAMILY, &process_publish_aggregated[NETDATA_IN_START_BYTE], 2);
119 + write_count_chart(NETDATA_FILE_OPEN_CLOSE_COUNT, NETDATA_EBPF_FAMILY, process_publish_aggregated, 2);
120
130 - write_count_chart(
131 - NETDATA_EXIT_SYSCALL, NETDATA_EBPF_FAMILY, &process_publish_aggregated[NETDATA_EXIT_START], 2);
132 - write_count_chart(
133 - NETDATA_PROCESS_SYSCALL, NETDATA_EBPF_FAMILY, &process_publish_aggregated[NETDATA_PROCESS_START], 2);
121 + write_count_chart(NETDATA_EXIT_SYSCALL, NETDATA_EBPF_FAMILY,
122 + &process_publish_aggregated[NETDATA_KEY_PUBLISH_PROCESS_EXIT], 2);
123 + write_count_chart(NETDATA_PROCESS_SYSCALL, NETDATA_EBPF_FAMILY,
124 + &process_publish_aggregated[NETDATA_KEY_PUBLISH_PROCESS_FORK], 2);
125
126 write_status_chart(NETDATA_EBPF_FAMILY, &pvc);
127 if (em->mode < MODE_ENTRY) {
137 - write_err_chart(
138 - NETDATA_FILE_OPEN_ERR_COUNT, NETDATA_EBPF_FAMILY, process_publish_aggregated, 2);
139 - write_err_chart(
140 - NETDATA_VFS_FILE_ERR_COUNT, NETDATA_EBPF_FAMILY, &process_publish_aggregated[2], NETDATA_VFS_ERRORS);
141 - write_err_chart(
142 - NETDATA_PROCESS_ERROR_NAME, NETDATA_EBPF_FAMILY, &process_publish_aggregated[NETDATA_PROCESS_START], 2);
128 + write_err_chart(NETDATA_FILE_OPEN_ERR_COUNT, NETDATA_EBPF_FAMILY,
129 + process_publish_aggregated, 2);
130 + write_err_chart(NETDATA_PROCESS_ERROR_NAME, NETDATA_EBPF_FAMILY,
131 + &process_publish_aggregated[NETDATA_KEY_PUBLISH_PROCESS_FORK], 2);
132 }
144 -
145 - write_io_chart(NETDATA_VFS_IO_FILE_BYTES, NETDATA_EBPF_FAMILY,
146 - process_id_names[NETDATA_KEY_PUBLISH_PROCESS_WRITE], (long long) pvc.write,
147 - process_id_names[NETDATA_KEY_PUBLISH_PROCESS_READ], (long long)pvc.read);
133 }
134
135 /**
@@ -220,8 +205,8 @@ void ebpf_process_send_apps_data(ebpf_module_t *em, struct target *root)
205 write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_SYSCALL_APPS_FILE_OPEN_ERROR);
206 for (w = root; w; w = w->next) {
207 if (unlikely(w->exposed && w->processes)) {
223 - value = ebpf_process_sum_values_for_pids(
224 - w->root_pid, offsetof(ebpf_process_publish_apps_t, ecall_sys_open));
208 + value = ebpf_process_sum_values_for_pids(w->root_pid,
209 + offsetof(ebpf_process_publish_apps_t, ecall_sys_open));
210 write_chart_dimension(w->name, value);
211 }
212 }
@@ -231,8 +216,7 @@ void ebpf_process_send_apps_data(ebpf_module_t *em, struct target *root)
216 write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_SYSCALL_APPS_FILE_CLOSED);
217 for (w = root; w; w = w->next) {
218 if (unlikely(w->exposed && w->processes)) {
234 - value =
235 - ebpf_process_sum_values_for_pids(w->root_pid, offsetof(ebpf_process_publish_apps_t, call_close_fd));
219 + value = ebpf_process_sum_values_for_pids(w->root_pid, offsetof(ebpf_process_publish_apps_t, call_close_fd));
220 write_chart_dimension(w->name, value);
221 }
222 }
@@ -242,93 +226,18 @@ void ebpf_process_send_apps_data(ebpf_module_t *em, struct target *root)
226 write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_SYSCALL_APPS_FILE_CLOSE_ERROR);
227 for (w = root; w; w = w->next) {
228 if (unlikely(w->exposed && w->processes)) {
245 - value = ebpf_process_sum_values_for_pids(
246 - w->root_pid, offsetof(ebpf_process_publish_apps_t, ecall_close_fd));
229 + value = ebpf_process_sum_values_for_pids(w->root_pid,
230 + offsetof(ebpf_process_publish_apps_t, ecall_close_fd));
231 write_chart_dimension(w->name, value);
232 }
233 }
234 write_end_chart();
235 }
236
253 - write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_SYSCALL_APPS_FILE_DELETED);
254 - for (w = root; w; w = w->next) {
255 - if (unlikely(w->exposed && w->processes)) {
256 - value =
257 - ebpf_process_sum_values_for_pids(w->root_pid, offsetof(ebpf_process_publish_apps_t, call_vfs_unlink));
258 - write_chart_dimension(w->name, value);
259 - }
260 - }
261 - write_end_chart();
262 -
263 - write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_SYSCALL_APPS_VFS_WRITE_CALLS);
264 - for (w = root; w; w = w->next) {
265 - if (unlikely(w->exposed && w->processes)) {
266 - value = ebpf_process_sum_values_for_pids(
267 - w->root_pid, offsetof(ebpf_process_publish_apps_t, call_write));
268 - write_chart_dimension(w->name, value);
269 - }
270 - }
271 - write_end_chart();
272 -
273 - if (em->mode < MODE_ENTRY) {
274 - write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_SYSCALL_APPS_VFS_WRITE_CALLS_ERROR);
275 - for (w = root; w; w = w->next) {
276 - if (unlikely(w->exposed && w->processes)) {
277 - value = ebpf_process_sum_values_for_pids(
278 - w->root_pid, offsetof(ebpf_process_publish_apps_t, ecall_write));
279 - write_chart_dimension(w->name, value);
280 - }
281 - }
282 - write_end_chart();
283 - }
284 -
285 - write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_SYSCALL_APPS_VFS_READ_CALLS);
286 - for (w = root; w; w = w->next) {
287 - if (unlikely(w->exposed && w->processes)) {
288 - value =
289 - ebpf_process_sum_values_for_pids(w->root_pid, offsetof(ebpf_process_publish_apps_t, call_read));
290 - write_chart_dimension(w->name, value);
291 - }
292 - }
293 - write_end_chart();
294 -
295 - if (em->mode < MODE_ENTRY) {
296 - write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_SYSCALL_APPS_VFS_READ_CALLS_ERROR);
297 - for (w = root; w; w = w->next) {
298 - if (unlikely(w->exposed && w->processes)) {
299 - value = ebpf_process_sum_values_for_pids(
300 - w->root_pid, offsetof(ebpf_process_publish_apps_t, ecall_read));
301 - write_chart_dimension(w->name, value);
302 - }
303 - }
304 - write_end_chart();
305 - }
306 -
307 - write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_SYSCALL_APPS_VFS_WRITE_BYTES);
308 - for (w = root; w; w = w->next) {
309 - if (unlikely(w->exposed && w->processes)) {
310 - value = ebpf_process_sum_values_for_pids(
311 - w->root_pid, offsetof(ebpf_process_publish_apps_t, bytes_written));
312 - write_chart_dimension(w->name, value);
313 - }
314 - }
315 - write_end_chart();
316 -
317 - write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_SYSCALL_APPS_VFS_READ_BYTES);
318 - for (w = root; w; w = w->next) {
319 - if (unlikely(w->exposed && w->processes)) {
320 - value = ebpf_process_sum_values_for_pids(
321 - w->root_pid, offsetof(ebpf_process_publish_apps_t, bytes_read));
322 - write_chart_dimension(w->name, value);
323 - }
324 - }
325 - write_end_chart();
326 -
237 write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_SYSCALL_APPS_TASK_PROCESS);
238 for (w = root; w; w = w->next) {
239 if (unlikely(w->exposed && w->processes)) {
330 - value =
331 - ebpf_process_sum_values_for_pids(w->root_pid, offsetof(ebpf_process_publish_apps_t, call_do_fork));
240 + value = ebpf_process_sum_values_for_pids(w->root_pid, offsetof(ebpf_process_publish_apps_t, call_do_fork));
241 write_chart_dimension(w->name, value);
242 }
243 }
@@ -337,8 +246,7 @@ void ebpf_process_send_apps_data(ebpf_module_t *em, struct target *root)
246 write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_SYSCALL_APPS_TASK_THREAD);
247 for (w = root; w; w = w->next) {
248 if (unlikely(w->exposed && w->processes)) {
340 - value =
341 - ebpf_process_sum_values_for_pids(w->root_pid, offsetof(ebpf_process_publish_apps_t, call_sys_clone));
249 + value = ebpf_process_sum_values_for_pids(w->root_pid, offsetof(ebpf_process_publish_apps_t, call_sys_clone));
250 write_chart_dimension(w->name, value);
251 }
252 }
@@ -369,10 +277,10 @@ void ebpf_process_send_apps_data(ebpf_module_t *em, struct target *root)
277 static void read_hash_global_tables()
278 {
279 uint64_t idx;
372 - netdata_idx_t res[NETDATA_GLOBAL_VECTOR];
280 + netdata_idx_t res[NETDATA_KEY_END_VECTOR];
281
282 netdata_idx_t *val = process_hash_values;
375 - for (idx = 0; idx < NETDATA_GLOBAL_VECTOR; idx++) {
283 + for (idx = 0; idx < NETDATA_KEY_END_VECTOR; idx++) {
284 if (!bpf_map_lookup_elem(map_fd[1], &idx, val)) {
285 uint64_t total = 0;
286 int i;
@@ -388,9 +296,6 @@ static void read_hash_global_tables()
296
297 process_aggregated_data[NETDATA_KEY_PUBLISH_PROCESS_OPEN].call = res[NETDATA_KEY_CALLS_DO_SYS_OPEN];
298 process_aggregated_data[NETDATA_KEY_PUBLISH_PROCESS_CLOSE].call = res[NETDATA_KEY_CALLS_CLOSE_FD];
391 - process_aggregated_data[NETDATA_KEY_PUBLISH_PROCESS_UNLINK].call = res[NETDATA_KEY_CALLS_VFS_UNLINK];
392 - process_aggregated_data[NETDATA_KEY_PUBLISH_PROCESS_READ].call = res[NETDATA_KEY_CALLS_VFS_READ] + res[NETDATA_KEY_CALLS_VFS_READV];
393 - process_aggregated_data[NETDATA_KEY_PUBLISH_PROCESS_WRITE].call = res[NETDATA_KEY_CALLS_VFS_WRITE] + res[NETDATA_KEY_CALLS_VFS_WRITEV];
299 process_aggregated_data[NETDATA_KEY_PUBLISH_PROCESS_EXIT].call = res[NETDATA_KEY_CALLS_DO_EXIT];
300 process_aggregated_data[NETDATA_KEY_PUBLISH_PROCESS_RELEASE_TASK].call = res[NETDATA_KEY_CALLS_RELEASE_TASK];
301 process_aggregated_data[NETDATA_KEY_PUBLISH_PROCESS_FORK].call = res[NETDATA_KEY_CALLS_DO_FORK];
@@ -398,16 +303,8 @@ static void read_hash_global_tables()
303
304 process_aggregated_data[NETDATA_KEY_PUBLISH_PROCESS_OPEN].ecall = res[NETDATA_KEY_ERROR_DO_SYS_OPEN];
305 process_aggregated_data[NETDATA_KEY_PUBLISH_PROCESS_CLOSE].ecall = res[NETDATA_KEY_ERROR_CLOSE_FD];
401 - process_aggregated_data[NETDATA_KEY_PUBLISH_PROCESS_UNLINK].ecall = res[NETDATA_KEY_ERROR_VFS_UNLINK];
402 - process_aggregated_data[NETDATA_KEY_PUBLISH_PROCESS_READ].ecall = res[NETDATA_KEY_ERROR_VFS_READ] + res[NETDATA_KEY_ERROR_VFS_READV];
403 - process_aggregated_data[NETDATA_KEY_PUBLISH_PROCESS_WRITE].ecall = res[NETDATA_KEY_ERROR_VFS_WRITE] + res[NETDATA_KEY_ERROR_VFS_WRITEV];
306 process_aggregated_data[NETDATA_KEY_PUBLISH_PROCESS_FORK].ecall = res[NETDATA_KEY_ERROR_DO_FORK];
307 process_aggregated_data[NETDATA_KEY_PUBLISH_PROCESS_CLONE].ecall = res[NETDATA_KEY_ERROR_SYS_CLONE];
406 -
407 - process_aggregated_data[NETDATA_KEY_PUBLISH_PROCESS_WRITE].bytes = (uint64_t)res[NETDATA_KEY_BYTES_VFS_WRITE] +
408 - (uint64_t)res[NETDATA_KEY_BYTES_VFS_WRITEV];
409 - process_aggregated_data[NETDATA_KEY_PUBLISH_PROCESS_READ].bytes = (uint64_t)res[NETDATA_KEY_BYTES_VFS_READ] +
410 - (uint64_t)res[NETDATA_KEY_BYTES_VFS_READV];
308 }
309
310 /**
@@ -433,9 +330,6 @@ static void ebpf_process_update_apps_data()
330 //Read data
331 cad->call_sys_open = ps->open_call;
332 cad->call_close_fd = ps->close_call;
436 - cad->call_vfs_unlink = ps->unlink_call;
437 - cad->call_read = ps->read_call + ps->readv_call;
438 - cad->call_write = ps->write_call + ps->writev_call;
333 cad->call_do_exit = ps->exit_call;
334 cad->call_release_task = ps->release_call;
335 cad->call_do_fork = ps->fork_call;
@@ -443,15 +337,9 @@ static void ebpf_process_update_apps_data()
337
338 cad->ecall_sys_open = ps->open_err;
339 cad->ecall_close_fd = ps->close_err;
446 - cad->ecall_vfs_unlink = ps->unlink_err;
447 - cad->ecall_read = ps->read_err + ps->readv_err;
448 - cad->ecall_write = ps->write_err + ps->writev_err;
340 cad->ecall_do_fork = ps->fork_err;
341 cad->ecall_sys_clone = ps->clone_err;
342
452 - cad->bytes_written = (uint64_t)ps->write_bytes + (uint64_t)ps->write_bytes;
453 - cad->bytes_read = (uint64_t)ps->read_bytes + (uint64_t)ps->readv_bytes;
454 -
343 pids = pids->next;
344 }
345 }
@@ -462,36 +350,6 @@ static void ebpf_process_update_apps_data()
350 *
351 *****************************************************************/
352
465 -/**
466 - * Create IO chart
467 - *
468 - * @param family the chart family
469 - * @param name the chart name
470 - * @param axis the axis label
471 - * @param web the group name used to attach the chart on dashboard
472 - * @param order the order number of the specified chart
473 - * @param algorithm the algorithm used to make the charts.
474 - */
475 -static void ebpf_create_io_chart(char *family, char *name, char *axis, char *web, int order, int algorithm)
476 -{
477 - printf("CHART %s.%s '' 'Bytes written and read' '%s' '%s' '' line %d %d\n",
478 - family,
479 - name,
480 - axis,
481 - web,
482 - order,
483 - update_every);
484 -
485 - printf("DIMENSION %s %s %s 1 1\n",
486 - process_id_names[NETDATA_KEY_PUBLISH_PROCESS_READ],
487 - process_dimension_names[NETDATA_KEY_PUBLISH_PROCESS_READ],
488 - ebpf_algorithms[algorithm]);
489 - printf("DIMENSION %s %s %s 1 1\n",
490 - process_id_names[NETDATA_KEY_PUBLISH_PROCESS_WRITE],
491 - process_dimension_names[NETDATA_KEY_PUBLISH_PROCESS_WRITE],
492 - ebpf_algorithms[algorithm]);
493 -}
494 -
353 /**
354 * Create process status chart
355 *
@@ -551,50 +409,6 @@ static void ebpf_create_global_charts(ebpf_module_t *em)
409 2);
410 }
411
554 - ebpf_create_chart(NETDATA_EBPF_FAMILY,
555 - NETDATA_VFS_FILE_CLEAN_COUNT,
556 - "Remove files",
557 - EBPF_COMMON_DIMENSION_CALL,
558 - NETDATA_VFS_GROUP,
559 - NULL,
560 - NETDATA_EBPF_CHART_TYPE_LINE,
561 - 21002,
562 - ebpf_create_global_dimension,
563 - &process_publish_aggregated[NETDATA_DEL_START],
564 - 1);
565 -
566 - ebpf_create_chart(NETDATA_EBPF_FAMILY,
567 - NETDATA_VFS_FILE_IO_COUNT,
568 - "Calls to IO",
569 - EBPF_COMMON_DIMENSION_CALL,
570 - NETDATA_VFS_GROUP,
571 - NULL,
572 - NETDATA_EBPF_CHART_TYPE_LINE,
573 - 21003,
574 - ebpf_create_global_dimension,
575 - &process_publish_aggregated[NETDATA_IN_START_BYTE],
576 - 2);
577 -
578 - ebpf_create_io_chart(NETDATA_EBPF_FAMILY,
579 - NETDATA_VFS_IO_FILE_BYTES, EBPF_COMMON_DIMENSION_BYTES,
580 - NETDATA_VFS_GROUP,
581 - 21004,
582 - NETDATA_EBPF_ABSOLUTE_IDX);
583 -
584 - if (em->mode < MODE_ENTRY) {
585 - ebpf_create_chart(NETDATA_EBPF_FAMILY,
586 - NETDATA_VFS_FILE_ERR_COUNT,
587 - "Fails to write or read",
588 - EBPF_COMMON_DIMENSION_CALL,
589 - NETDATA_VFS_GROUP,
590 - NULL,
591 - NETDATA_EBPF_CHART_TYPE_LINE,
592 - 21005,
593 - ebpf_create_global_dimension,
594 - &process_publish_aggregated[2],
595 - NETDATA_VFS_ERRORS);
596 - }
597 -
412 ebpf_create_chart(NETDATA_EBPF_FAMILY,
413 NETDATA_PROCESS_SYSCALL,
414 "Start process",
@@ -602,9 +416,9 @@ static void ebpf_create_global_charts(ebpf_module_t *em)
416 NETDATA_PROCESS_GROUP,
417 NULL,
418 NETDATA_EBPF_CHART_TYPE_LINE,
605 - 21006,
419 + 21002,
420 ebpf_create_global_dimension,
607 - &process_publish_aggregated[NETDATA_PROCESS_START],
421 + &process_publish_aggregated[NETDATA_KEY_PUBLISH_PROCESS_FORK],
422 2);
423
424 ebpf_create_chart(NETDATA_EBPF_FAMILY,
@@ -614,9 +428,9 @@ static void ebpf_create_global_charts(ebpf_module_t *em)
428 NETDATA_PROCESS_GROUP,
429 NULL,
430 NETDATA_EBPF_CHART_TYPE_LINE,
617 - 21007,
431 + 21003,
432 ebpf_create_global_dimension,
619 - &process_publish_aggregated[NETDATA_EXIT_START],
433 + &process_publish_aggregated[NETDATA_KEY_PUBLISH_PROCESS_EXIT],
434 2);
435
436 ebpf_process_status_chart(NETDATA_EBPF_FAMILY,
@@ -624,7 +438,7 @@ static void ebpf_create_global_charts(ebpf_module_t *em)
438 EBPF_COMMON_DIMENSION_DIFFERENCE,
439 NETDATA_PROCESS_GROUP,
440 ebpf_algorithms[NETDATA_EBPF_ABSOLUTE_IDX],
627 - 21008);
441 + 21004);
442
443 if (em->mode < MODE_ENTRY) {
444 ebpf_create_chart(NETDATA_EBPF_FAMILY,
@@ -634,9 +448,9 @@ static void ebpf_create_global_charts(ebpf_module_t *em)
448 NETDATA_PROCESS_GROUP,
449 NULL,
450 NETDATA_EBPF_CHART_TYPE_LINE,
637 - 21009,
451 + 21005,
452 ebpf_create_global_dimension,
639 - &process_publish_aggregated[NETDATA_PROCESS_START],
453 + &process_publish_aggregated[NETDATA_KEY_PUBLISH_PROCESS_FORK],
454 2);
455 }
456 }
@@ -692,77 +506,12 @@ void ebpf_process_create_apps_charts(struct ebpf_module *em, void *ptr)
506 root);
507 }
508
695 - ebpf_create_charts_on_apps(NETDATA_SYSCALL_APPS_FILE_DELETED,
696 - "Files deleted",
697 - EBPF_COMMON_DIMENSION_CALL,
698 - NETDATA_APPS_VFS_GROUP,
699 - NETDATA_EBPF_CHART_TYPE_STACKED,
700 - 20065,
701 - ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
702 - root);
703 -
704 - ebpf_create_charts_on_apps(NETDATA_SYSCALL_APPS_VFS_WRITE_CALLS,
705 - "Write to disk",
706 - EBPF_COMMON_DIMENSION_CALL,
707 - NETDATA_APPS_VFS_GROUP,
708 - NETDATA_EBPF_CHART_TYPE_STACKED,
709 - 20066,
710 - ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
711 - apps_groups_root_target);
712 -
713 - if (em->mode < MODE_ENTRY) {
714 - ebpf_create_charts_on_apps(NETDATA_SYSCALL_APPS_VFS_WRITE_CALLS_ERROR,
715 - "Fails to write",
716 - EBPF_COMMON_DIMENSION_CALL,
717 - NETDATA_APPS_VFS_GROUP,
718 - NETDATA_EBPF_CHART_TYPE_STACKED,
719 - 20067,
720 - ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
721 - root);
722 - }
723 -
724 - ebpf_create_charts_on_apps(NETDATA_SYSCALL_APPS_VFS_READ_CALLS,
725 - "Read from disk",
726 - EBPF_COMMON_DIMENSION_CALL,
727 - NETDATA_APPS_VFS_GROUP,
728 - NETDATA_EBPF_CHART_TYPE_STACKED,
729 - 20068,
730 - ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
731 - root);
732 -
733 - if (em->mode < MODE_ENTRY) {
734 - ebpf_create_charts_on_apps(NETDATA_SYSCALL_APPS_VFS_READ_CALLS_ERROR,
735 - "Fails to read",
736 - EBPF_COMMON_DIMENSION_CALL,
737 - NETDATA_APPS_VFS_GROUP,
738 - NETDATA_EBPF_CHART_TYPE_STACKED,
739 - 20069,
740 - ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
741 - root);
742 - }
743 -
744 - ebpf_create_charts_on_apps(NETDATA_SYSCALL_APPS_VFS_WRITE_BYTES,
745 - "Bytes written on disk", EBPF_COMMON_DIMENSION_BYTES,
746 - NETDATA_APPS_VFS_GROUP,
747 - NETDATA_EBPF_CHART_TYPE_STACKED,
748 - 20070,
749 - ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
750 - root);
751 -
752 - ebpf_create_charts_on_apps(NETDATA_SYSCALL_APPS_VFS_READ_BYTES,
753 - "Bytes read from disk", EBPF_COMMON_DIMENSION_BYTES,
754 - NETDATA_APPS_VFS_GROUP,
755 - NETDATA_EBPF_CHART_TYPE_STACKED,
756 - 20071,
757 - ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
758 - root);
759 -
509 ebpf_create_charts_on_apps(NETDATA_SYSCALL_APPS_TASK_PROCESS,
510 "Process started",
511 EBPF_COMMON_DIMENSION_CALL,
512 NETDATA_APPS_PROCESS_GROUP,
513 NETDATA_EBPF_CHART_TYPE_STACKED,
765 - 20072,
514 + 20065,
515 ebpf_algorithms[NETDATA_EBPF_ABSOLUTE_IDX],
516 root);
517
@@ -771,7 +520,7 @@ void ebpf_process_create_apps_charts(struct ebpf_module *em, void *ptr)
520 EBPF_COMMON_DIMENSION_CALL,
521 NETDATA_APPS_PROCESS_GROUP,
522 NETDATA_EBPF_CHART_TYPE_STACKED,
774 - 20073,
523 + 20066,
524 ebpf_algorithms[NETDATA_EBPF_ABSOLUTE_IDX],
525 root);
526
@@ -780,7 +529,7 @@ void ebpf_process_create_apps_charts(struct ebpf_module *em, void *ptr)
529 EBPF_COMMON_DIMENSION_CALL,
530 NETDATA_APPS_PROCESS_GROUP,
531 NETDATA_EBPF_CHART_TYPE_STACKED,
783 - 20074,
532 + 20067,
533 ebpf_algorithms[NETDATA_EBPF_ABSOLUTE_IDX],
534 root);
535 }
@@ -971,7 +720,7 @@ static void ebpf_process_allocate_global_vectors(size_t length)
720 static void change_syscalls()
721 {
722 static char *lfork = { "do_fork" };
974 - process_id_names[7] = lfork;
723 + process_id_names[NETDATA_KEY_PUBLISH_PROCESS_FORK] = lfork;
724 }
725
726 /**
@@ -1056,8 +805,7 @@ void *ebpf_process_thread(void *ptr)
805 }
806
807 int algorithms[NETDATA_KEY_PUBLISH_PROCESS_END] = {
1059 - NETDATA_EBPF_INCREMENTAL_IDX, NETDATA_EBPF_INCREMENTAL_IDX,NETDATA_EBPF_INCREMENTAL_IDX, //open, close, unlink
1060 - NETDATA_EBPF_ABSOLUTE_IDX, NETDATA_EBPF_ABSOLUTE_IDX, NETDATA_EBPF_ABSOLUTE_IDX,
808 + NETDATA_EBPF_INCREMENTAL_IDX, NETDATA_EBPF_INCREMENTAL_IDX, NETDATA_EBPF_ABSOLUTE_IDX,
809 NETDATA_EBPF_ABSOLUTE_IDX, NETDATA_EBPF_ABSOLUTE_IDX, NETDATA_EBPF_ABSOLUTE_IDX
810 };
811
collectors/ebpf.plugin/ebpf_process.h
+1 -55
@@ -5,41 +5,20 @@
5
6 // Groups used on Dashboard
7 #define NETDATA_FILE_GROUP "File"
8 -#define NETDATA_VFS_GROUP "VFS"
8 #define NETDATA_PROCESS_GROUP "Process"
9
11 -// Internal constants
12 -#define NETDATA_GLOBAL_VECTOR 24
13 -#define NETDATA_VFS_ERRORS 3
14 -
15 -// Map index
16 -#define NETDATA_DEL_START 2
17 -#define NETDATA_IN_START_BYTE 3
18 -#define NETDATA_EXIT_START 5
19 -#define NETDATA_PROCESS_START 7
20 -
10 // Global chart name
11 #define NETDATA_FILE_OPEN_CLOSE_COUNT "file_descriptor"
12 #define NETDATA_FILE_OPEN_ERR_COUNT "file_error"
24 -#define NETDATA_VFS_FILE_CLEAN_COUNT "deleted_objects"
25 -#define NETDATA_VFS_FILE_IO_COUNT "io"
26 -#define NETDATA_VFS_FILE_ERR_COUNT "io_error"
13
14 #define NETDATA_EXIT_SYSCALL "exit"
15 #define NETDATA_PROCESS_SYSCALL "process_thread"
16 #define NETDATA_PROCESS_ERROR_NAME "task_error"
17 #define NETDATA_PROCESS_STATUS_NAME "process_status"
18
33 -#define NETDATA_VFS_IO_FILE_BYTES "io_bytes"
34 -
19 // Charts created on Apps submenu
20 #define NETDATA_SYSCALL_APPS_FILE_OPEN "file_open"
21 #define NETDATA_SYSCALL_APPS_FILE_CLOSED "file_closed"
38 -#define NETDATA_SYSCALL_APPS_FILE_DELETED "file_deleted"
39 -#define NETDATA_SYSCALL_APPS_VFS_WRITE_CALLS "vfs_write_call"
40 -#define NETDATA_SYSCALL_APPS_VFS_READ_CALLS "vfs_read_call"
41 -#define NETDATA_SYSCALL_APPS_VFS_WRITE_BYTES "vfs_write_bytes"
42 -#define NETDATA_SYSCALL_APPS_VFS_READ_BYTES "vfs_read_bytes"
22 #define NETDATA_SYSCALL_APPS_TASK_PROCESS "process_create"
23 #define NETDATA_SYSCALL_APPS_TASK_THREAD "thread_create"
24 #define NETDATA_SYSCALL_APPS_TASK_CLOSE "task_close"
@@ -48,8 +27,6 @@
27
28 #define NETDATA_SYSCALL_APPS_FILE_OPEN_ERROR "file_open_error"
29 #define NETDATA_SYSCALL_APPS_FILE_CLOSE_ERROR "file_close_error"
51 -#define NETDATA_SYSCALL_APPS_VFS_WRITE_CALLS_ERROR "vfs_write_error"
52 -#define NETDATA_SYSCALL_APPS_VFS_READ_CALLS_ERROR "vfs_read_error"
30
31 // Process configuration name
32 #define NETDATA_PROCESS_CONFIG_FILE "process.conf"
@@ -59,17 +36,6 @@ typedef enum ebpf_process_index {
36 NETDATA_KEY_CALLS_DO_SYS_OPEN,
37 NETDATA_KEY_ERROR_DO_SYS_OPEN,
38
62 - NETDATA_KEY_CALLS_VFS_WRITE,
63 - NETDATA_KEY_ERROR_VFS_WRITE,
64 - NETDATA_KEY_BYTES_VFS_WRITE,
65 -
66 - NETDATA_KEY_CALLS_VFS_READ,
67 - NETDATA_KEY_ERROR_VFS_READ,
68 - NETDATA_KEY_BYTES_VFS_READ,
69 -
70 - NETDATA_KEY_CALLS_VFS_UNLINK,
71 - NETDATA_KEY_ERROR_VFS_UNLINK,
72 -
39 NETDATA_KEY_CALLS_DO_EXIT,
40
41 NETDATA_KEY_CALLS_RELEASE_TASK,
@@ -83,14 +49,7 @@ typedef enum ebpf_process_index {
49 NETDATA_KEY_CALLS_SYS_CLONE,
50 NETDATA_KEY_ERROR_SYS_CLONE,
51
86 - NETDATA_KEY_CALLS_VFS_WRITEV,
87 - NETDATA_KEY_ERROR_VFS_WRITEV,
88 - NETDATA_KEY_BYTES_VFS_WRITEV,
89 -
90 - NETDATA_KEY_CALLS_VFS_READV,
91 - NETDATA_KEY_ERROR_VFS_READV,
92 - NETDATA_KEY_BYTES_VFS_READV
93 -
52 + NETDATA_KEY_END_VECTOR
53 } ebpf_process_index_t;
54
55 // This enum acts as an index for publish vector.
@@ -101,9 +60,6 @@ typedef enum ebpf_process_index {
60 typedef enum netdata_publish_process {
61 NETDATA_KEY_PUBLISH_PROCESS_OPEN,
62 NETDATA_KEY_PUBLISH_PROCESS_CLOSE,
104 - NETDATA_KEY_PUBLISH_PROCESS_UNLINK,
105 - NETDATA_KEY_PUBLISH_PROCESS_READ,
106 - NETDATA_KEY_PUBLISH_PROCESS_WRITE,
63 NETDATA_KEY_PUBLISH_PROCESS_EXIT,
64 NETDATA_KEY_PUBLISH_PROCESS_RELEASE_TASK,
65 NETDATA_KEY_PUBLISH_PROCESS_FORK,
@@ -116,9 +72,6 @@ typedef struct ebpf_process_publish_apps {
72 // Number of calls during the last read
73 uint64_t call_sys_open;
74 uint64_t call_close_fd;
119 - uint64_t call_vfs_unlink;
120 - uint64_t call_read;
121 - uint64_t call_write;
75 uint64_t call_do_exit;
76 uint64_t call_release_task;
77 uint64_t call_do_fork;
@@ -127,15 +80,8 @@ typedef struct ebpf_process_publish_apps {
80 // Number of errors during the last read
81 uint64_t ecall_sys_open;
82 uint64_t ecall_close_fd;
130 - uint64_t ecall_vfs_unlink;
131 - uint64_t ecall_read;
132 - uint64_t ecall_write;
83 uint64_t ecall_do_fork;
84 uint64_t ecall_sys_clone;
135 -
136 - // Number of bytes during the last read
137 - uint64_t bytes_written;
138 - uint64_t bytes_read;
85 } ebpf_process_publish_apps_t;
86
87 extern struct config process_config;
collectors/ebpf.plugin/ebpf_vfs.c new
+930
@@ -0,0 +1,930 @@
1 +// SPDX-License-Identifier: GPL-3.0-or-later
2 +
3 +#include <sys/resource.h>
4 +
5 +#include "ebpf.h"
6 +#include "ebpf_vfs.h"
7 +
8 +static char *vfs_dimension_names[NETDATA_KEY_PUBLISH_VFS_END] = { "delete", "read", "write",
9 + "fsync", "open", "create" };
10 +static char *vfs_id_names[NETDATA_KEY_PUBLISH_VFS_END] = { "vfs_unlink", "vfs_read", "vfs_write",
11 + "vfs_fsync", "vfs_open", "vfs_create"};
12 +
13 +static netdata_idx_t *vfs_hash_values = NULL;
14 +static netdata_syscall_stat_t vfs_aggregated_data[NETDATA_KEY_PUBLISH_PROCESS_END];
15 +static netdata_publish_syscall_t vfs_publish_aggregated[NETDATA_KEY_PUBLISH_PROCESS_END];
16 +netdata_publish_vfs_t **vfs_pid = NULL;
17 +netdata_publish_vfs_t *vfs_vector = NULL;
18 +
19 +static ebpf_data_t vfs_data;
20 +
21 +static ebpf_local_maps_t vfs_maps[] = {{.name = "tbl_vfs_pid", .internal_input = ND_EBPF_DEFAULT_PID_SIZE,
22 + .user_input = 0},
23 + {.name = NULL, .internal_input = 0, .user_input = 0}};
24 +
25 +struct config vfs_config = { .first_section = NULL,
26 + .last_section = NULL,
27 + .mutex = NETDATA_MUTEX_INITIALIZER,
28 + .index = { .avl_tree = { .root = NULL, .compar = appconfig_section_compare },
29 + .rwlock = AVL_LOCK_INITIALIZER } };
30 +
31 +static struct bpf_object *objects = NULL;
32 +static struct bpf_link **probe_links = NULL;
33 +
34 +struct netdata_static_thread vfs_threads = {"VFS KERNEL",
35 + NULL, NULL, 1, NULL,
36 + NULL, NULL};
37 +
38 +static int *map_fd = NULL;
39 +
40 +static int read_thread_closed = 1;
41 +
42 +/*****************************************************************
43 + *
44 + * FUNCTIONS TO CLOSE THE THREAD
45 + *
46 + *****************************************************************/
47 +
48 +/**
49 + * Clean PID structures
50 + *
51 + * Clean the allocated structures.
52 + */
53 +void clean_vfs_pid_structures() {
54 + struct pid_stat *pids = root_of_pids;
55 + while (pids) {
56 + freez(vfs_pid[pids->pid]);
57 +
58 + pids = pids->next;
59 + }
60 +}
61 +
62 +/**
63 +* Clean up the main thread.
64 +*
65 +* @param ptr thread data.
66 +**/
67 +static void ebpf_vfs_cleanup(void *ptr)
68 +{
69 + ebpf_module_t *em = (ebpf_module_t *)ptr;
70 + if (!em->enabled)
71 + return;
72 +
73 + heartbeat_t hb;
74 + heartbeat_init(&hb);
75 + uint32_t tick = 50 * USEC_PER_MS;
76 + while (!read_thread_closed) {
77 + usec_t dt = heartbeat_next(&hb, tick);
78 + UNUSED(dt);
79 + }
80 +
81 + freez(vfs_data.map_fd);
82 + freez(vfs_hash_values);
83 + freez(vfs_vector);
84 +
85 + if (probe_links) {
86 + struct bpf_program *prog;
87 + size_t i = 0 ;
88 + bpf_object__for_each_program(prog, objects) {
89 + bpf_link__destroy(probe_links[i]);
90 + i++;
91 + }
92 + bpf_object__close(objects);
93 + }
94 +}
95 +
96 +/*****************************************************************
97 + *
98 + * FUNCTIONS WITH THE MAIN LOOP
99 + *
100 + *****************************************************************/
101 +
102 +/**
103 + * Send data to Netdata calling auxiliar functions.
104 + *
105 + * @param em the structure with thread information
106 +*/
107 +static void ebpf_vfs_send_data(ebpf_module_t *em)
108 +{
109 + netdata_publish_vfs_common_t pvc;
110 +
111 + pvc.write = (long)vfs_aggregated_data[NETDATA_KEY_PUBLISH_VFS_WRITE].bytes;
112 + pvc.read = (long)vfs_aggregated_data[NETDATA_KEY_PUBLISH_VFS_READ].bytes;
113 +
114 + write_count_chart(NETDATA_VFS_FILE_CLEAN_COUNT, NETDATA_FILESYSTEM_FAMILY,
115 + &vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_UNLINK], 1);
116 +
117 + write_count_chart(NETDATA_VFS_FILE_IO_COUNT, NETDATA_FILESYSTEM_FAMILY,
118 + &vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_READ], 2);
119 +
120 + if (em->mode < MODE_ENTRY) {
121 + write_err_chart(NETDATA_VFS_FILE_ERR_COUNT, NETDATA_FILESYSTEM_FAMILY,
122 + &vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_READ], 2);
123 + }
124 +
125 + write_io_chart(NETDATA_VFS_IO_FILE_BYTES, NETDATA_FILESYSTEM_FAMILY, vfs_id_names[NETDATA_KEY_PUBLISH_VFS_WRITE],
126 + (long long)pvc.write, vfs_id_names[NETDATA_KEY_PUBLISH_VFS_READ], (long long)pvc.read);
127 +
128 + write_count_chart(NETDATA_VFS_FSYNC, NETDATA_FILESYSTEM_FAMILY,
129 + &vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_FSYNC], 1);
130 +
131 + if (em->mode < MODE_ENTRY) {
132 + write_err_chart(NETDATA_VFS_FSYNC_ERR, NETDATA_FILESYSTEM_FAMILY,
133 + &vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_FSYNC], 1);
134 + }
135 +
136 + write_count_chart(NETDATA_VFS_OPEN, NETDATA_FILESYSTEM_FAMILY,
137 + &vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_OPEN], 1);
138 +
139 + if (em->mode < MODE_ENTRY) {
140 + write_err_chart(NETDATA_VFS_OPEN_ERR, NETDATA_FILESYSTEM_FAMILY,
141 + &vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_OPEN], 1);
142 + }
143 +
144 + write_count_chart(NETDATA_VFS_CREATE, NETDATA_FILESYSTEM_FAMILY,
145 + &vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_CREATE], 1);
146 +
147 + if (em->mode < MODE_ENTRY) {
148 + write_err_chart(
149 + NETDATA_VFS_CREATE_ERR,
150 + NETDATA_FILESYSTEM_FAMILY,
151 + &vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_CREATE],
152 + 1);
153 + }
154 +}
155 +
156 +/**
157 + * Read the hash table and store data to allocated vectors.
158 + */
159 +static void read_global_table()
160 +{
161 + uint64_t idx;
162 + netdata_idx_t res[NETDATA_VFS_COUNTER];
163 +
164 + netdata_idx_t *val = vfs_hash_values;
165 + int fd = map_fd[NETDATA_VFS_ALL];
166 + for (idx = 0; idx < NETDATA_VFS_COUNTER; idx++) {
167 + uint64_t total = 0;
168 + if (!bpf_map_lookup_elem(fd, &idx, val)) {
169 + int i;
170 + int end = (running_on_kernel < NETDATA_KERNEL_V4_15) ? 1 : ebpf_nprocs;
171 + for (i = 0; i < end; i++)
172 + total += val[i];
173 + }
174 + res[idx] = total;
175 + }
176 +
177 + vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_UNLINK].ncall = res[NETDATA_KEY_CALLS_VFS_UNLINK];
178 + vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_READ].ncall = res[NETDATA_KEY_CALLS_VFS_READ] +
179 + res[NETDATA_KEY_CALLS_VFS_READV];
180 + vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_WRITE].ncall = res[NETDATA_KEY_CALLS_VFS_WRITE] +
181 + res[NETDATA_KEY_CALLS_VFS_WRITEV];
182 + vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_FSYNC].ncall = res[NETDATA_KEY_CALLS_VFS_FSYNC];
183 + vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_OPEN].ncall = res[NETDATA_KEY_CALLS_VFS_OPEN];
184 + vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_CREATE].ncall = res[NETDATA_KEY_CALLS_VFS_CREATE];
185 +
186 + vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_UNLINK].nerr = res[NETDATA_KEY_ERROR_VFS_UNLINK];
187 + vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_READ].nerr = res[NETDATA_KEY_ERROR_VFS_READ] +
188 + res[NETDATA_KEY_ERROR_VFS_READV];
189 + vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_WRITE].nerr = res[NETDATA_KEY_ERROR_VFS_WRITE] +
190 + res[NETDATA_KEY_ERROR_VFS_WRITEV];
191 + vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_FSYNC].nerr = res[NETDATA_KEY_ERROR_VFS_FSYNC];
192 + vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_OPEN].nerr = res[NETDATA_KEY_ERROR_VFS_OPEN];
193 + vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_CREATE].nerr = res[NETDATA_KEY_ERROR_VFS_CREATE];
194 +
195 + vfs_aggregated_data[NETDATA_KEY_PUBLISH_VFS_WRITE].bytes = (uint64_t)res[NETDATA_KEY_BYTES_VFS_WRITE] +
196 + (uint64_t)res[NETDATA_KEY_BYTES_VFS_WRITEV];
197 + vfs_aggregated_data[NETDATA_KEY_PUBLISH_VFS_READ].bytes = (uint64_t)res[NETDATA_KEY_BYTES_VFS_READ] +
198 + (uint64_t)res[NETDATA_KEY_BYTES_VFS_READV];
199 +}
200 +
201 +/**
202 + * Sum PIDs
203 + *
204 + * Sum values for all targets.
205 + *
206 + * @param swap output structure
207 + * @param root link list with structure to be used
208 + */
209 +static void ebpf_vfs_sum_pids(netdata_publish_vfs_t *vfs, struct pid_on_target *root)
210 +{
211 + netdata_publish_vfs_t accumulator;
212 + memset(&accumulator, 0, sizeof(accumulator));
213 +
214 + while (root) {
215 + int32_t pid = root->pid;
216 + netdata_publish_vfs_t *w = vfs_pid[pid];
217 + if (w) {
218 + accumulator.write_call += w->write_call;
219 + accumulator.writev_call += w->writev_call;
220 + accumulator.read_call += w->read_call;
221 + accumulator.readv_call += w->readv_call;
222 + accumulator.unlink_call += w->unlink_call;
223 + accumulator.fsync_call += w->fsync_call;
224 + accumulator.open_call += w->open_call;
225 + accumulator.create_call += w->create_call;
226 +
227 + accumulator.write_bytes += w->write_bytes;
228 + accumulator.writev_bytes += w->writev_bytes;
229 + accumulator.read_bytes += w->read_bytes;
230 + accumulator.readv_bytes += w->readv_bytes;
231 +
232 + accumulator.write_err += w->write_err;
233 + accumulator.writev_err += w->writev_err;
234 + accumulator.read_err += w->read_err;
235 + accumulator.readv_err += w->readv_err;
236 + accumulator.unlink_err += w->unlink_err;
237 + accumulator.fsync_err += w->fsync_err;
238 + accumulator.open_err += w->open_err;
239 + accumulator.create_err += w->create_err;
240 + }
241 + root = root->next;
242 + }
243 +
244 + // These conditions were added, because we are using incremental algorithm
245 + vfs->write_call = (accumulator.write_call >= vfs->write_call) ? accumulator.write_call : vfs->write_call;
246 + vfs->writev_call = (accumulator.writev_call >= vfs->writev_call) ? accumulator.writev_call : vfs->writev_call;
247 + vfs->read_call = (accumulator.read_call >= vfs->read_call) ? accumulator.read_call : vfs->read_call;
248 + vfs->readv_call = (accumulator.readv_call >= vfs->readv_call) ? accumulator.readv_call : vfs->readv_call;
249 + vfs->unlink_call = (accumulator.unlink_call >= vfs->unlink_call) ? accumulator.unlink_call : vfs->unlink_call;
250 + vfs->fsync_call = (accumulator.fsync_call >= vfs->fsync_call) ? accumulator.fsync_call : vfs->fsync_call;
251 + vfs->open_call = (accumulator.open_call >= vfs->open_call) ? accumulator.open_call : vfs->open_call;
252 + vfs->create_call = (accumulator.create_call >= vfs->create_call) ? accumulator.create_call : vfs->create_call;
253 +
254 + vfs->write_bytes = (accumulator.write_bytes >= vfs->write_bytes) ? accumulator.write_bytes : vfs->write_bytes;
255 + vfs->writev_bytes = (accumulator.writev_bytes >= vfs->writev_bytes) ? accumulator.writev_bytes : vfs->writev_bytes;
256 + vfs->read_bytes = (accumulator.read_bytes >= vfs->read_bytes) ? accumulator.read_bytes : vfs->read_bytes;
257 + vfs->readv_bytes = (accumulator.readv_bytes >= vfs->readv_bytes) ? accumulator.readv_bytes : vfs->readv_bytes;
258 +
259 + vfs->write_err = (accumulator.write_err >= vfs->write_err) ? accumulator.write_err : vfs->write_err;
260 + vfs->writev_err = (accumulator.writev_err >= vfs->writev_err) ? accumulator.writev_err : vfs->writev_err;
261 + vfs->read_err = (accumulator.read_err >= vfs->read_err) ? accumulator.read_err : vfs->read_err;
262 + vfs->readv_err = (accumulator.readv_err >= vfs->readv_err) ? accumulator.readv_err : vfs->readv_err;
263 + vfs->unlink_err = (accumulator.unlink_err >= vfs->unlink_err) ? accumulator.unlink_err : vfs->unlink_err;
264 + vfs->fsync_err = (accumulator.fsync_err >= vfs->fsync_err) ? accumulator.fsync_err : vfs->fsync_err;
265 + vfs->open_err = (accumulator.open_err >= vfs->open_err) ? accumulator.open_err : vfs->open_err;
266 + vfs->create_err = (accumulator.create_err >= vfs->create_err) ? accumulator.create_err : vfs->create_err;
267 +}
268 +
269 +/**
270 + * Send data to Netdata calling auxiliar functions.
271 + *
272 + * @param em the structure with thread information
273 + * @param root the target list.
274 + */
275 +void ebpf_vfs_send_apps_data(ebpf_module_t *em, struct target *root)
276 +{
277 + struct target *w;
278 + for (w = root; w; w = w->next) {
279 + if (unlikely(w->exposed && w->processes)) {
280 + ebpf_vfs_sum_pids(&w->vfs, w->root_pid);
281 + }
282 + }
283 +
284 + write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_SYSCALL_APPS_FILE_DELETED);
285 + for (w = root; w; w = w->next) {
286 + if (unlikely(w->exposed && w->processes)) {
287 + write_chart_dimension(w->name, w->vfs.unlink_call);
288 + }
289 + }
290 + write_end_chart();
291 +
292 + write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_SYSCALL_APPS_VFS_WRITE_CALLS);
293 + for (w = root; w; w = w->next) {
294 + if (unlikely(w->exposed && w->processes)) {
295 + write_chart_dimension(w->name, w->vfs.write_call + w->vfs.writev_call);
296 + }
297 + }
298 + write_end_chart();
299 +
300 + if (em->mode < MODE_ENTRY) {
301 + write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_SYSCALL_APPS_VFS_WRITE_CALLS_ERROR);
302 + for (w = root; w; w = w->next) {
303 + if (unlikely(w->exposed && w->processes)) {
304 + write_chart_dimension(w->name, w->vfs.write_err + w->vfs.writev_err);
305 + }
306 + }
307 + write_end_chart();
308 + }
309 +
310 + write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_SYSCALL_APPS_VFS_READ_CALLS);
311 + for (w = root; w; w = w->next) {
312 + if (unlikely(w->exposed && w->processes)) {
313 + write_chart_dimension(w->name, w->vfs.read_call + w->vfs.readv_call);
314 + }
315 + }
316 + write_end_chart();
317 +
318 + if (em->mode < MODE_ENTRY) {
319 + write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_SYSCALL_APPS_VFS_READ_CALLS_ERROR);
320 + for (w = root; w; w = w->next) {
321 + if (unlikely(w->exposed && w->processes)) {
322 + write_chart_dimension(w->name, w->vfs.read_err + w->vfs.readv_err);
323 + }
324 + }
325 + write_end_chart();
326 + }
327 +
328 + write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_SYSCALL_APPS_VFS_WRITE_BYTES);
329 + for (w = root; w; w = w->next) {
330 + if (unlikely(w->exposed && w->processes)) {
331 + write_chart_dimension(w->name, w->vfs.write_bytes + w->vfs.writev_bytes);
332 + }
333 + }
334 + write_end_chart();
335 +
336 + write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_SYSCALL_APPS_VFS_READ_BYTES);
337 + for (w = root; w; w = w->next) {
338 + if (unlikely(w->exposed && w->processes)) {
339 + write_chart_dimension(w->name, w->vfs.read_bytes + w->vfs.readv_bytes);
340 + }
341 + }
342 + write_end_chart();
343 +
344 + write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_SYSCALL_APPS_VFS_FSYNC);
345 + for (w = root; w; w = w->next) {
346 + if (unlikely(w->exposed && w->processes)) {
347 + write_chart_dimension(w->name, w->vfs.fsync_call);
348 + }
349 + }
350 + write_end_chart();
351 +
352 + if (em->mode < MODE_ENTRY) {
353 + write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_SYSCALL_APPS_VFS_FSYNC_CALLS_ERROR);
354 + for (w = root; w; w = w->next) {
355 + if (unlikely(w->exposed && w->processes)) {
356 + write_chart_dimension(w->name, w->vfs.fsync_err);
357 + }
358 + }
359 + write_end_chart();
360 + }
361 +
362 + write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_SYSCALL_APPS_VFS_OPEN);
363 + for (w = root; w; w = w->next) {
364 + if (unlikely(w->exposed && w->processes)) {
365 + write_chart_dimension(w->name, w->vfs.open_call);
366 + }
367 + }
368 + write_end_chart();
369 +
370 + if (em->mode < MODE_ENTRY) {
371 + write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_SYSCALL_APPS_VFS_OPEN_CALLS_ERROR);
372 + for (w = root; w; w = w->next) {
373 + if (unlikely(w->exposed && w->processes)) {
374 + write_chart_dimension(w->name, w->vfs.open_err);
375 + }
376 + }
377 + write_end_chart();
378 + }
379 +
380 + write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_SYSCALL_APPS_VFS_CREATE);
381 + for (w = root; w; w = w->next) {
382 + if (unlikely(w->exposed && w->processes)) {
383 + write_chart_dimension(w->name, w->vfs.create_call);
384 + }
385 + }
386 + write_end_chart();
387 +
388 + if (em->mode < MODE_ENTRY) {
389 + write_begin_chart(NETDATA_APPS_FAMILY, NETDATA_SYSCALL_APPS_VFS_CREATE_CALLS_ERROR);
390 + for (w = root; w; w = w->next) {
391 + if (unlikely(w->exposed && w->processes)) {
392 + write_chart_dimension(w->name, w->vfs.create_err);
393 + }
394 + }
395 + write_end_chart();
396 + }
397 +}
398 +
399 +/**
400 + * Apps Accumulator
401 + *
402 + * Sum all values read from kernel and store in the first address.
403 + *
404 + * @param out the vector with read values.
405 + */
406 +static void vfs_apps_accumulator(netdata_publish_vfs_t *out)
407 +{
408 + int i, end = (running_on_kernel >= NETDATA_KERNEL_V4_15) ? ebpf_nprocs : 1;
409 + netdata_publish_vfs_t *total = &out[0];
410 + for (i = 1; i < end; i++) {
411 + netdata_publish_vfs_t *w = &out[i];
412 +
413 + total->write_call += w->write_call;
414 + total->writev_call += w->writev_call;
415 + total->read_call += w->read_call;
416 + total->readv_call += w->readv_call;
417 + total->unlink_call += w->unlink_call;
418 +
419 + total->write_bytes += w->write_bytes;
420 + total->writev_bytes += w->writev_bytes;
421 + total->read_bytes += w->read_bytes;
422 + total->readv_bytes += w->readv_bytes;
423 +
424 + total->write_err += w->write_err;
425 + total->writev_err += w->writev_err;
426 + total->read_err += w->read_err;
427 + total->readv_err += w->readv_err;
428 + total->unlink_err += w->unlink_err;
429 + }
430 +}
431 +
432 +/**
433 + * Fill PID
434 + *
435 + * Fill PID structures
436 + *
437 + * @param current_pid pid that we are collecting data
438 + * @param out values read from hash tables;
439 + */
440 +static void vfs_fill_pid(uint32_t current_pid, netdata_publish_vfs_t *publish)
441 +{
442 + netdata_publish_vfs_t *curr = vfs_pid[current_pid];
443 + if (!curr) {
444 + curr = callocz(1, sizeof(netdata_publish_vfs_t));
445 + vfs_pid[current_pid] = curr;
446 + }
447 +
448 + memcpy(curr, &publish[0], sizeof(netdata_publish_vfs_t));
449 +}
450 +
451 +/**
452 + * Read the hash table and store data to allocated vectors.
453 + */
454 +static void ebpf_vfs_read_apps()
455 +{
456 + struct pid_stat *pids = root_of_pids;
457 + netdata_publish_vfs_t *vv = vfs_vector;
458 + int fd = map_fd[NETDATA_VFS_PID];
459 + size_t length = sizeof(netdata_publish_vfs_t) * ebpf_nprocs;
460 + while (pids) {
461 + uint32_t key = pids->pid;
462 +
463 + if (bpf_map_lookup_elem(fd, &key, vv)) {
464 + pids = pids->next;
465 + continue;
466 + }
467 +
468 + vfs_apps_accumulator(vv);
469 +
470 + vfs_fill_pid(key, vv);
471 +
472 + // We are cleaning to avoid passing data read from one process to other.
473 + memset(vv, 0, length);
474 +
475 + pids = pids->next;
476 + }
477 +}
478 +
479 +/**
480 + * VFS read hash
481 + *
482 + * This is the thread callback.
483 + * This thread is necessary, because we cannot freeze the whole plugin to read the data.
484 + *
485 + * @param ptr It is a NULL value for this thread.
486 + *
487 + * @return It always returns NULL.
488 + */
489 +void *ebpf_vfs_read_hash(void *ptr)
490 +{
491 + read_thread_closed = 0;
492 +
493 + heartbeat_t hb;
494 + heartbeat_init(&hb);
495 +
496 + ebpf_module_t *em = (ebpf_module_t *)ptr;
497 +
498 + usec_t step = NETDATA_LATENCY_VFS_SLEEP_MS * em->update_time;
499 + while (!close_ebpf_plugin) {
500 + usec_t dt = heartbeat_next(&hb, step);
501 + (void)dt;
502 +
503 + read_global_table();
504 + }
505 +
506 + read_thread_closed = 1;
507 +
508 + return NULL;
509 +}
510 +
511 +/**
512 + * Main loop for this collector.
513 + *
514 + * @param step the number of microseconds used with heart beat
515 + * @param em the structure with thread information
516 + */
517 +static void vfs_collector(ebpf_module_t *em)
518 +{
519 + vfs_threads.thread = mallocz(sizeof(netdata_thread_t));
520 + vfs_threads.start_routine = ebpf_vfs_read_hash;
521 +
522 + map_fd = vfs_data.map_fd;
523 +
524 + netdata_thread_create(vfs_threads.thread, vfs_threads.name, NETDATA_THREAD_OPTION_JOINABLE,
525 + ebpf_vfs_read_hash, em);
526 +
527 + int apps = em->apps_charts;
528 + while (!close_ebpf_plugin) {
529 + pthread_mutex_lock(&collect_data_mutex);
530 + pthread_cond_wait(&collect_data_cond_var, &collect_data_mutex);
531 +
532 + if (apps)
533 + ebpf_vfs_read_apps();
534 +
535 + pthread_mutex_lock(&lock);
536 +
537 + ebpf_vfs_send_data(em);
538 + fflush(stdout);
539 +
540 + if (apps)
541 + ebpf_vfs_send_apps_data(em, apps_groups_root_target);
542 +
543 + pthread_mutex_unlock(&lock);
544 + pthread_mutex_unlock(&collect_data_mutex);
545 + }
546 +}
547 +
548 +/*****************************************************************
549 + *
550 + * FUNCTIONS TO CREATE CHARTS
551 + *
552 + *****************************************************************/
553 +
554 +/**
555 + * Create IO chart
556 + *
557 + * @param family the chart family
558 + * @param name the chart name
559 + * @param axis the axis label
560 + * @param web the group name used to attach the chart on dashboard
561 + * @param order the order number of the specified chart
562 + * @param algorithm the algorithm used to make the charts.
563 + */
564 +static void ebpf_create_io_chart(char *family, char *name, char *axis, char *web, int order, int algorithm)
565 +{
566 + printf("CHART %s.%s '' 'Bytes written and read' '%s' '%s' '' line %d %d\n",
567 + family,
568 + name,
569 + axis,
570 + web,
571 + order,
572 + update_every);
573 +
574 + printf("DIMENSION %s %s %s 1 1\n",
575 + vfs_id_names[NETDATA_KEY_PUBLISH_VFS_READ],
576 + vfs_dimension_names[NETDATA_KEY_PUBLISH_VFS_READ],
577 + ebpf_algorithms[algorithm]);
578 + printf("DIMENSION %s %s %s -1 1\n",
579 + vfs_id_names[NETDATA_KEY_PUBLISH_VFS_WRITE],
580 + vfs_dimension_names[NETDATA_KEY_PUBLISH_VFS_WRITE],
581 + ebpf_algorithms[algorithm]);
582 +}
583 +
584 +/**
585 + * Create global charts
586 + *
587 + * Call ebpf_create_chart to create the charts for the collector.
588 + *
589 + * @param em a pointer to the structure with the default values.
590 + */
591 +static void ebpf_create_global_charts(ebpf_module_t *em)
592 +{
593 + ebpf_create_chart(NETDATA_FILESYSTEM_FAMILY,
594 + NETDATA_VFS_FILE_CLEAN_COUNT,
595 + "Remove files",
596 + EBPF_COMMON_DIMENSION_CALL,
597 + NETDATA_VFS_GROUP,
598 + NULL,
599 + NETDATA_EBPF_CHART_TYPE_LINE,
600 + NETDATA_CHART_PRIO_FILESYSTEM_VFS_CLEAN,
601 + ebpf_create_global_dimension,
602 + &vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_UNLINK],
603 + 1);
604 +
605 + ebpf_create_chart(NETDATA_FILESYSTEM_FAMILY,
606 + NETDATA_VFS_FILE_IO_COUNT,
607 + "Calls to IO",
608 + EBPF_COMMON_DIMENSION_CALL,
609 + NETDATA_VFS_GROUP,
610 + NULL,
611 + NETDATA_EBPF_CHART_TYPE_LINE,
612 + NETDATA_CHART_PRIO_FILESYSTEM_VFS_IO_COUNT,
613 + ebpf_create_global_dimension,
614 + &vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_READ],
615 + 2);
616 +
617 + ebpf_create_io_chart(NETDATA_FILESYSTEM_FAMILY,
618 + NETDATA_VFS_IO_FILE_BYTES, EBPF_COMMON_DIMENSION_BYTES,
619 + NETDATA_VFS_GROUP,
620 + NETDATA_CHART_PRIO_FILESYSTEM_VFS_IO_BYTES,
621 + NETDATA_EBPF_INCREMENTAL_IDX);
622 +
623 + if (em->mode < MODE_ENTRY) {
624 + ebpf_create_chart(NETDATA_FILESYSTEM_FAMILY,
625 + NETDATA_VFS_FILE_ERR_COUNT,
626 + "Fails to write or read",
627 + EBPF_COMMON_DIMENSION_CALL,
628 + NETDATA_VFS_GROUP,
629 + NULL,
630 + NETDATA_EBPF_CHART_TYPE_LINE,
631 + NETDATA_CHART_PRIO_FILESYSTEM_VFS_IO_EBYTES,
632 + ebpf_create_global_dimension,
633 + &vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_READ],
634 + 2);
635 + }
636 +
637 + ebpf_create_chart(NETDATA_FILESYSTEM_FAMILY,
638 + NETDATA_VFS_FSYNC,
639 + "Calls to vfs_fsync",
640 + EBPF_COMMON_DIMENSION_CALL,
641 + NETDATA_VFS_GROUP,
642 + NULL,
643 + NETDATA_EBPF_CHART_TYPE_LINE,
644 + NETDATA_CHART_PRIO_FILESYSTEM_VFS_IO_FSYNC,
645 + ebpf_create_global_dimension,
646 + &vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_FSYNC],
647 + 1);
648 +
649 + if (em->mode < MODE_ENTRY) {
650 + ebpf_create_chart(NETDATA_FILESYSTEM_FAMILY,
651 + NETDATA_VFS_FSYNC_ERR,
652 + "Fails to synchronize",
653 + EBPF_COMMON_DIMENSION_CALL,
654 + NETDATA_VFS_GROUP,
655 + NULL,
656 + NETDATA_EBPF_CHART_TYPE_LINE,
657 + NETDATA_CHART_PRIO_FILESYSTEM_VFS_IO_EFSYNC,
658 + ebpf_create_global_dimension,
659 + &vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_FSYNC],
660 + 1);
661 + }
662 +
663 + ebpf_create_chart(NETDATA_FILESYSTEM_FAMILY,
664 + NETDATA_VFS_OPEN,
665 + "Calls to vfs_open",
666 + EBPF_COMMON_DIMENSION_CALL,
667 + NETDATA_VFS_GROUP,
668 + NULL,
669 + NETDATA_EBPF_CHART_TYPE_LINE,
670 + NETDATA_CHART_PRIO_FILESYSTEM_VFS_IO_OPEN,
671 + ebpf_create_global_dimension,
672 + &vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_OPEN],
673 + 1);
674 +
675 + if (em->mode < MODE_ENTRY) {
676 + ebpf_create_chart(NETDATA_FILESYSTEM_FAMILY,
677 + NETDATA_VFS_OPEN_ERR,
678 + "Fails to open a file",
679 + EBPF_COMMON_DIMENSION_CALL,
680 + NETDATA_VFS_GROUP,
681 + NULL,
682 + NETDATA_EBPF_CHART_TYPE_LINE,
683 + NETDATA_CHART_PRIO_FILESYSTEM_VFS_IO_EOPEN,
684 + ebpf_create_global_dimension,
685 + &vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_OPEN],
686 + 1);
687 + }
688 +
689 + ebpf_create_chart(NETDATA_FILESYSTEM_FAMILY,
690 + NETDATA_VFS_CREATE,
691 + "Calls to vfs_create",
692 + EBPF_COMMON_DIMENSION_CALL,
693 + NETDATA_VFS_GROUP,
694 + NULL,
695 + NETDATA_EBPF_CHART_TYPE_LINE,
696 + NETDATA_CHART_PRIO_FILESYSTEM_VFS_IO_CREATE,
697 + ebpf_create_global_dimension,
698 + &vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_CREATE],
699 + 1);
700 +
701 + if (em->mode < MODE_ENTRY) {
702 + ebpf_create_chart(NETDATA_FILESYSTEM_FAMILY,
703 + NETDATA_VFS_CREATE_ERR,
704 + "Fails to create a file.",
705 + EBPF_COMMON_DIMENSION_CALL,
706 + NETDATA_VFS_GROUP,
707 + NULL,
708 + NETDATA_EBPF_CHART_TYPE_LINE,
709 + NETDATA_CHART_PRIO_FILESYSTEM_VFS_IO_ECREATE,
710 + ebpf_create_global_dimension,
711 + &vfs_publish_aggregated[NETDATA_KEY_PUBLISH_VFS_CREATE],
712 + 1);
713 + }
714 +}
715 +
716 +/**
717 + * Create process apps charts
718 + *
719 + * Call ebpf_create_chart to create the charts on apps submenu.
720 + *
721 + * @param em a pointer to the structure with the default values.
722 + * @param ptr a pointer for the targets.
723 + **/
724 +void ebpf_vfs_create_apps_charts(struct ebpf_module *em, void *ptr)
725 +{
726 + struct target *root = ptr;
727 +
728 + ebpf_create_charts_on_apps(NETDATA_SYSCALL_APPS_FILE_DELETED,
729 + "Files deleted",
730 + EBPF_COMMON_DIMENSION_CALL,
731 + NETDATA_APPS_VFS_GROUP,
732 + NETDATA_EBPF_CHART_TYPE_STACKED,
733 + 20065,
734 + ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
735 + root);
736 +
737 + ebpf_create_charts_on_apps(NETDATA_SYSCALL_APPS_VFS_WRITE_CALLS,
738 + "Write to disk",
739 + EBPF_COMMON_DIMENSION_CALL,
740 + NETDATA_APPS_VFS_GROUP,
741 + NETDATA_EBPF_CHART_TYPE_STACKED,
742 + 20066,
743 + ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
744 + apps_groups_root_target);
745 +
746 + if (em->mode < MODE_ENTRY) {
747 + ebpf_create_charts_on_apps(NETDATA_SYSCALL_APPS_VFS_WRITE_CALLS_ERROR,
748 + "Fails to write",
749 + EBPF_COMMON_DIMENSION_CALL,
750 + NETDATA_APPS_VFS_GROUP,
751 + NETDATA_EBPF_CHART_TYPE_STACKED,
752 + 20067,
753 + ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
754 + root);
755 + }
756 +
757 + ebpf_create_charts_on_apps(NETDATA_SYSCALL_APPS_VFS_READ_CALLS,
758 + "Read from disk",
759 + EBPF_COMMON_DIMENSION_CALL,
760 + NETDATA_APPS_VFS_GROUP,
761 + NETDATA_EBPF_CHART_TYPE_STACKED,
762 + 20068,
763 + ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
764 + root);
765 +
766 + if (em->mode < MODE_ENTRY) {
767 + ebpf_create_charts_on_apps(NETDATA_SYSCALL_APPS_VFS_READ_CALLS_ERROR,
768 + "Fails to read",
769 + EBPF_COMMON_DIMENSION_CALL,
770 + NETDATA_APPS_VFS_GROUP,
771 + NETDATA_EBPF_CHART_TYPE_STACKED,
772 + 20069,
773 + ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
774 + root);
775 + }
776 +
777 + ebpf_create_charts_on_apps(NETDATA_SYSCALL_APPS_VFS_WRITE_BYTES,
778 + "Bytes written on disk", EBPF_COMMON_DIMENSION_BYTES,
779 + NETDATA_APPS_VFS_GROUP,
780 + NETDATA_EBPF_CHART_TYPE_STACKED,
781 + 20070,
782 + ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
783 + root);
784 +
785 + ebpf_create_charts_on_apps(NETDATA_SYSCALL_APPS_VFS_READ_BYTES,
786 + "Bytes read from disk", EBPF_COMMON_DIMENSION_BYTES,
787 + NETDATA_APPS_VFS_GROUP,
788 + NETDATA_EBPF_CHART_TYPE_STACKED,
789 + 20071,
790 + ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
791 + root);
792 +
793 + ebpf_create_charts_on_apps(NETDATA_SYSCALL_APPS_VFS_FSYNC,
794 + "Calls for <code>vfs_fsync</code>", EBPF_COMMON_DIMENSION_CALL,
795 + NETDATA_APPS_VFS_GROUP,
796 + NETDATA_EBPF_CHART_TYPE_STACKED,
797 + 20072,
798 + ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
799 + root);
800 +
801 + if (em->mode < MODE_ENTRY) {
802 + ebpf_create_charts_on_apps(NETDATA_SYSCALL_APPS_VFS_FSYNC_CALLS_ERROR,
803 + "Sync error",
804 + EBPF_COMMON_DIMENSION_CALL,
805 + NETDATA_APPS_VFS_GROUP,
806 + NETDATA_EBPF_CHART_TYPE_STACKED,
807 + 20073,
808 + ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
809 + root);
810 + }
811 +
812 + ebpf_create_charts_on_apps(NETDATA_SYSCALL_APPS_VFS_OPEN,
813 + "Calls for <code>vfs_open</code>", EBPF_COMMON_DIMENSION_CALL,
814 + NETDATA_APPS_VFS_GROUP,
815 + NETDATA_EBPF_CHART_TYPE_STACKED,
816 + 20074,
817 + ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
818 + root);
819 +
820 + if (em->mode < MODE_ENTRY) {
821 + ebpf_create_charts_on_apps(NETDATA_SYSCALL_APPS_VFS_OPEN_CALLS_ERROR,
822 + "Open error",
823 + EBPF_COMMON_DIMENSION_CALL,
824 + NETDATA_APPS_VFS_GROUP,
825 + NETDATA_EBPF_CHART_TYPE_STACKED,
826 + 20075,
827 + ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
828 + root);
829 + }
830 +
831 + ebpf_create_charts_on_apps(NETDATA_SYSCALL_APPS_VFS_CREATE,
832 + "Calls for <code>vfs_create</code>", EBPF_COMMON_DIMENSION_CALL,
833 + NETDATA_APPS_VFS_GROUP,
834 + NETDATA_EBPF_CHART_TYPE_STACKED,
835 + 20076,
836 + ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
837 + root);
838 +
839 + if (em->mode < MODE_ENTRY) {
840 + ebpf_create_charts_on_apps(NETDATA_SYSCALL_APPS_VFS_CREATE_CALLS_ERROR,
841 + "Create error",
842 + EBPF_COMMON_DIMENSION_CALL,
843 + NETDATA_APPS_VFS_GROUP,
844 + NETDATA_EBPF_CHART_TYPE_STACKED,
845 + 20077,
846 + ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX],
847 + root);
848 + }
849 +}
850 +
851 +/*****************************************************************
852 + *
853 + * FUNCTIONS TO START THREAD
854 + *
855 + *****************************************************************/
856 +
857 +/**
858 + * Allocate vectors used with this thread.
859 + * We are not testing the return, because callocz does this and shutdown the software
860 + * case it was not possible to allocate.
861 + *
862 + * @param length is the length for the vectors used inside the collector.
863 + */
864 +static void ebpf_vfs_allocate_global_vectors()
865 +{
866 + memset(vfs_aggregated_data, 0, sizeof(vfs_aggregated_data));
867 + memset(vfs_publish_aggregated, 0, sizeof(vfs_publish_aggregated));
868 +
869 + vfs_hash_values = callocz(ebpf_nprocs, sizeof(netdata_idx_t));
870 + vfs_vector = callocz(ebpf_nprocs, sizeof(netdata_publish_vfs_t));
871 + vfs_pid = callocz((size_t)pid_max, sizeof(netdata_publish_vfs_t *));
872 +}
873 +
874 +/*****************************************************************
875 + *
876 + * EBPF PROCESS THREAD
877 + *
878 + *****************************************************************/
879 +
880 +/**
881 + * Process thread
882 + *
883 + * Thread used to generate process charts.
884 + *
885 + * @param ptr a pointer to `struct ebpf_module`
886 + *
887 + * @return It always return NULL
888 + */
889 +void *ebpf_vfs_thread(void *ptr)
890 +{
891 + netdata_thread_cleanup_push(ebpf_vfs_cleanup, ptr);
892 +
893 + ebpf_module_t *em = (ebpf_module_t *)ptr;
894 + em->maps = vfs_maps;
895 + fill_ebpf_data(&vfs_data);
896 +
897 + ebpf_update_pid_table(&vfs_maps[0], em);
898 +
899 + ebpf_vfs_allocate_global_vectors();
900 +
901 + if (!em->enabled)
902 + goto endvfs;
903 +
904 + if (ebpf_update_kernel(&vfs_data)) {
905 + goto endvfs;
906 + }
907 +
908 + probe_links = ebpf_load_program(ebpf_plugin_dir, em, kernel_string, &objects, vfs_data.map_fd);
909 + if (!probe_links) {
910 + goto endvfs;
911 + }
912 +
913 + int algorithms[NETDATA_KEY_PUBLISH_PROCESS_END] = {
914 + NETDATA_EBPF_INCREMENTAL_IDX, NETDATA_EBPF_INCREMENTAL_IDX,NETDATA_EBPF_INCREMENTAL_IDX,
915 + NETDATA_EBPF_INCREMENTAL_IDX, NETDATA_EBPF_INCREMENTAL_IDX,NETDATA_EBPF_INCREMENTAL_IDX
916 + };
917 +
918 + ebpf_global_labels(vfs_aggregated_data, vfs_publish_aggregated, vfs_dimension_names,
919 + vfs_id_names, algorithms, NETDATA_KEY_PUBLISH_VFS_END);
920 +
921 + pthread_mutex_lock(&lock);
922 + ebpf_create_global_charts(em);
923 + pthread_mutex_unlock(&lock);
924 +
925 + vfs_collector(em);
926 +
927 +endvfs:
928 + netdata_thread_cleanup_pop(1);
929 + return NULL;
930 +}
collectors/ebpf.plugin/ebpf_vfs.h new
+130
@@ -0,0 +1,130 @@
1 +// SPDX-License-Identifier: GPL-3.0-or-later
2 +
3 +#ifndef NETDATA_EBPF_VFS_H
4 +#define NETDATA_EBPF_VFS_H 1
5 +
6 +#define NETDATA_DIRECTORY_VFS_CONFIG_FILE "vfs.conf"
7 +
8 +#define NETDATA_LATENCY_VFS_SLEEP_MS 750000ULL
9 +
10 +// Global chart name
11 +#define NETDATA_VFS_FILE_CLEAN_COUNT "vfs_deleted_objects"
12 +#define NETDATA_VFS_FILE_IO_COUNT "vfs_io"
13 +#define NETDATA_VFS_FILE_ERR_COUNT "vfs_io_error"
14 +#define NETDATA_VFS_IO_FILE_BYTES "vfs_io_bytes"
15 +#define NETDATA_VFS_FSYNC "vfs_fsync"
16 +#define NETDATA_VFS_FSYNC_ERR "vfs_fsync_error"
17 +#define NETDATA_VFS_OPEN "vfs_open"
18 +#define NETDATA_VFS_OPEN_ERR "vfs_open_error"
19 +#define NETDATA_VFS_CREATE "vfs_create"
20 +#define NETDATA_VFS_CREATE_ERR "vfs_create_error"
21 +
22 +// Charts created on Apps submenu
23 +#define NETDATA_SYSCALL_APPS_FILE_DELETED "file_deleted"
24 +#define NETDATA_SYSCALL_APPS_VFS_WRITE_CALLS "vfs_write_call"
25 +#define NETDATA_SYSCALL_APPS_VFS_READ_CALLS "vfs_read_call"
26 +#define NETDATA_SYSCALL_APPS_VFS_WRITE_BYTES "vfs_write_bytes"
27 +#define NETDATA_SYSCALL_APPS_VFS_READ_BYTES "vfs_read_bytes"
28 +#define NETDATA_SYSCALL_APPS_VFS_FSYNC "vfs_fsync"
29 +#define NETDATA_SYSCALL_APPS_VFS_OPEN "vfs_open"
30 +#define NETDATA_SYSCALL_APPS_VFS_CREATE "vfs_create"
31 +
32 +#define NETDATA_SYSCALL_APPS_VFS_WRITE_CALLS_ERROR "vfs_write_error"
33 +#define NETDATA_SYSCALL_APPS_VFS_READ_CALLS_ERROR "vfs_read_error"
34 +#define NETDATA_SYSCALL_APPS_VFS_FSYNC_CALLS_ERROR "vfs_fsync_error"
35 +#define NETDATA_SYSCALL_APPS_VFS_OPEN_CALLS_ERROR "vfs_open_error"
36 +#define NETDATA_SYSCALL_APPS_VFS_CREATE_CALLS_ERROR "vfs_create_error"
37 +
38 +// Group used on Dashboard
39 +#define NETDATA_VFS_GROUP "VFS (eBPF)"
40 +
41 +typedef struct netdata_publish_vfs {
42 + uint64_t pid_tgid;
43 + uint32_t pid;
44 + uint32_t pad;
45 +
46 + //Counter
47 + uint32_t write_call;
48 + uint32_t writev_call;
49 + uint32_t read_call;
50 + uint32_t readv_call;
51 + uint32_t unlink_call;
52 + uint32_t fsync_call;
53 + uint32_t open_call;
54 + uint32_t create_call;
55 +
56 + //Accumulator
57 + uint64_t write_bytes;
58 + uint64_t writev_bytes;
59 + uint64_t readv_bytes;
60 + uint64_t read_bytes;
61 +
62 + //Counter
63 + uint32_t write_err;
64 + uint32_t writev_err;
65 + uint32_t read_err;
66 + uint32_t readv_err;
67 + uint32_t unlink_err;
68 + uint32_t fsync_err;
69 + uint32_t open_err;
70 + uint32_t create_err;
71 +} netdata_publish_vfs_t;
72 +
73 +enum netdata_publish_vfs_list {
74 + NETDATA_KEY_PUBLISH_VFS_UNLINK,
75 + NETDATA_KEY_PUBLISH_VFS_READ,
76 + NETDATA_KEY_PUBLISH_VFS_WRITE,
77 + NETDATA_KEY_PUBLISH_VFS_FSYNC,
78 + NETDATA_KEY_PUBLISH_VFS_OPEN,
79 + NETDATA_KEY_PUBLISH_VFS_CREATE,
80 +
81 + NETDATA_KEY_PUBLISH_VFS_END
82 +};
83 +
84 +enum vfs_counters {
85 + NETDATA_KEY_CALLS_VFS_WRITE,
86 + NETDATA_KEY_ERROR_VFS_WRITE,
87 + NETDATA_KEY_BYTES_VFS_WRITE,
88 +
89 + NETDATA_KEY_CALLS_VFS_WRITEV,
90 + NETDATA_KEY_ERROR_VFS_WRITEV,
91 + NETDATA_KEY_BYTES_VFS_WRITEV,
92 +
93 + NETDATA_KEY_CALLS_VFS_READ,
94 + NETDATA_KEY_ERROR_VFS_READ,
95 + NETDATA_KEY_BYTES_VFS_READ,
96 +
97 + NETDATA_KEY_CALLS_VFS_READV,
98 + NETDATA_KEY_ERROR_VFS_READV,
99 + NETDATA_KEY_BYTES_VFS_READV,
100 +
101 + NETDATA_KEY_CALLS_VFS_UNLINK,
102 + NETDATA_KEY_ERROR_VFS_UNLINK,
103 +
104 + NETDATA_KEY_CALLS_VFS_FSYNC,
105 + NETDATA_KEY_ERROR_VFS_FSYNC,
106 +
107 + NETDATA_KEY_CALLS_VFS_OPEN,
108 + NETDATA_KEY_ERROR_VFS_OPEN,
109 +
110 + NETDATA_KEY_CALLS_VFS_CREATE,
111 + NETDATA_KEY_ERROR_VFS_CREATE,
112 +
113 + // Keep this as last and don't skip numbers as it is used as element counter
114 + NETDATA_VFS_COUNTER
115 +};
116 +
117 +enum netdata_vfs_tables {
118 + NETDATA_VFS_PID,
119 + NETDATA_VFS_ALL
120 +};
121 +
122 +extern netdata_publish_vfs_t **vfs_pid;
123 +
124 +extern void *ebpf_vfs_thread(void *ptr);
125 +extern void ebpf_vfs_create_apps_charts(struct ebpf_module *em, void *ptr);
126 +extern void clean_vfs_pid_structures();
127 +
128 +extern struct config vfs_config;
129 +
130 +#endif /* NETDATA_EBPF_VFS_H */
packaging/ebpf.checksums
+3 -3
@@ -1,3 +1,3 @@
1 -6102337e8d38c4902c02371b44e962b65d9d7f4e793fc0e093ec6352e3cf8b14 netdata-kernel-collector-glibc-v0.6.5.tar.xz
2 -12e95abfe9173566d20467b5946e5850c830533bc0ab46c0f95470c95e7ccc19 netdata-kernel-collector-musl-v0.6.5.tar.xz
3 -d26a976d684cc4635a530d17cf0caaa70223a80d795339923f8cc6ba55413741 netdata-kernel-collector-static-v0.6.5.tar.xz
1 +49c50bdca3389a7a5df3c2753d9ed790983fae1350e1ee95bdaa5bc36e8ed398 netdata-kernel-collector-glibc-v0.6.6.tar.xz
2 +3cfe2ab7ebec5e508a4e769d79e97a8bdfe03e1d0f2147320643dcae2a3b525a netdata-kernel-collector-musl-v0.6.6.tar.xz
3 +66c04aa186540dc27317265bad5ee9ce4eec962c176d3cb04f4d56032171e566 netdata-kernel-collector-static-v0.6.6.tar.xz
packaging/ebpf.version
+1 -1
@@ -1 +1 @@
1 -v0.6.5
1 +v0.6.6
web/gui/dashboard_info.js
+47 -20
@@ -3413,6 +3413,53 @@ netdataDashboard.context = {
3413 info: 'Size of metric samples written to disk.'
3414 },
3415
3416 + // ------------------------------------------------------------------------
3417 + // Filesystem
3418 +
3419 + 'filesystem.vfs_deleted_objects': {
3420 + title : 'VFS remove',
3421 + info: 'This chart does not show all events that remove files from the file system, because file systems can create their own functions to remove files, it shows calls for the function <code>vfs_unlink</code>. '
3422 + },
3423 +
3424 + 'filesystem.vfs_io': {
3425 + title : 'VFS IO',
3426 + info: 'Successful or failed calls to functions <code>vfs_read</code> and <code>vfs_write</code>. This chart may not show all file system events if it uses other functions to store data on disk.'
3427 + },
3428 +
3429 + 'filesystem.vfs_io_bytes': {
3430 + title : 'VFS bytes written',
3431 + info: 'Total of bytes read or written with success using the functions <code>vfs_read</code> and <code>vfs_write</code>.'
3432 + },
3433 +
3434 + 'filesystem.vfs_io_error': {
3435 + title : 'VFS IO error',
3436 + info: 'Failed calls to functions <code>vfs_read</code> and <code>vfs_write</code>.'
3437 + },
3438 +
3439 + 'filesystem.vfs_fsync': {
3440 + info: 'Successful or failed calls to functions <code>vfs_fsync</code>.'
3441 + },
3442 +
3443 + 'filesystem.vfs_fsync_error': {
3444 + info: 'Failed calls to functions <code>vfs_fsync</code>.'
3445 + },
3446 +
3447 + 'filesystem.vfs_open': {
3448 + info: 'Successful or failed calls to functions <code>vfs_open</code>.'
3449 + },
3450 +
3451 + 'filesystem.vfs_open_error': {
3452 + info: 'Failed calls to functions <code>vfs_open</code>.'
3453 + },
3454 +
3455 + 'filesystem.vfs_create': {
3456 + info: 'Successful or failed calls to functions <code>vfs_create</code>.'
3457 + },
3458 +
3459 + 'filesystem.vfs_create_error': {
3460 + info: 'Failed calls to functions <code>vfs_create</code>.'
3461 + },
3462 +
3463 // ------------------------------------------------------------------------
3464 // eBPF
3465
@@ -3464,26 +3511,6 @@ netdataDashboard.context = {
3511 ' <a href="https://www.man7.org/linux/man-pages/man2/close.2.html" target="_blank">close(2)</a>. '
3512 },
3513
3467 - 'ebpf.deleted_objects': {
3468 - title : 'VFS remove',
3469 - info: 'This chart does not show all events that remove files from the file system, because file systems can create their own functions to remove files, it shows calls for the function <a href="https://www.kernel.org/doc/htmldocs/filesystems/API-vfs-unlink.html" target="_blank">vfs_unlink</a>. '
3470 - },
3471 -
3472 - 'ebpf.io': {
3473 - title : 'VFS IO',
3474 - info: 'Successful or failed calls to functions <a href="https://topic.alibabacloud.com/a/kernel-state-file-operation-__-work-information-kernel_8_8_20287135.html" target="_blank">vfs_read</a> and <a href="https://topic.alibabacloud.com/a/kernel-state-file-operation-__-work-information-kernel_8_8_20287135.html" target="_blank">vfs_write</a>. This chart may not show all file system events if it uses other functions to store data on disk.'
3475 - },
3476 -
3477 - 'ebpf.io_bytes': {
3478 - title : 'VFS bytes written',
3479 - info: 'Total of bytes read or written with success using the functions <a href="https://topic.alibabacloud.com/a/kernel-state-file-operation-__-work-information-kernel_8_8_20287135.html" target="_blank">vfs_read</a> and <a href="https://topic.alibabacloud.com/a/kernel-state-file-operation-__-work-information-kernel_8_8_20287135.html" target="_blank">vfs_write</a>.'
3480 - },
3481 -
3482 - 'ebpf.io_error': {
3483 - title : 'VFS IO error',
3484 - info: 'Failed calls to functions <a href="https://topic.alibabacloud.com/a/kernel-state-file-operation-__-work-information-kernel_8_8_20287135.html" target="_blank">vfs_read</a> and <a href="https://topic.alibabacloud.com/a/kernel-state-file-operation-__-work-information-kernel_8_8_20287135.html" target="_blank">vfs_write</a>.'
3485 - },
3486 -
3514 'ebpf.process_thread': {
3515 title : 'Task creation',
3516 info: 'Number of times that either <a href="https://www.ece.uic.edu/~yshi1/linux/lkse/node4.html#SECTION00421000000000000000" target="_blank">do_fork</a>, or <code>kernel_clone</code> if you are running kernel newer than 5.9.16, is called to create a new task, which is the common name used to define process and tasks inside the kernel. Netdata identifies the threads by counting the number of calls for <a href="https://linux.die.net/man/2/clone" target="_blank">sys_clone</a> that has the flag <code>CLONE_THREAD</code> set.'