@cryptotaxi247 / netdata-1 / commits / 28ce8f444

eBPF plugin CO-RE and monitoring (#11992)

thiagoftsm committed Jan 19, 2022 at 15:20 UTC 28ce8f4445394714077150ea1abc3de2a8a42c27
23 files changed +646 -149
collectors/ebpf.plugin/ebpf.c
+102 -20
@@ -27,7 +27,6 @@ struct config collector_config = { .first_section = NULL,
27 .rwlock = AVL_LOCK_INITIALIZER } };
28
29 int running_on_kernel = 0;
30 -char kernel_string[64];
30 int ebpf_nprocs;
31 int isrh = 0;
32 uint32_t finalized_threads = 1;
@@ -42,94 +41,127 @@ ebpf_module_t ebpf_modules[] = {
41 .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
42 .apps_routine = ebpf_process_create_apps_charts, .maps = NULL,
43 .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &process_config,
45 - .config_file = NETDATA_PROCESS_CONFIG_FILE},
44 + .config_file = NETDATA_PROCESS_CONFIG_FILE,
45 + .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4 | NETDATA_V5_10,
46 + .load = EBPF_LOAD_LEGACY, .targets = NULL},
47 { .thread_name = "socket", .config_name = "socket", .enabled = 0, .start_routine = ebpf_socket_thread,
48 .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO,
49 .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
50 .apps_routine = ebpf_socket_create_apps_charts, .maps = NULL,
51 .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &socket_config,
51 - .config_file = NETDATA_NETWORK_CONFIG_FILE},
52 + .config_file = NETDATA_NETWORK_CONFIG_FILE,
53 + .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4,
54 + .load = EBPF_LOAD_LEGACY, .targets = NULL},
55 { .thread_name = "cachestat", .config_name = "cachestat", .enabled = 0, .start_routine = ebpf_cachestat_thread,
56 .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO,
57 .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
58 .apps_routine = ebpf_cachestat_create_apps_charts, .maps = NULL,
59 .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &cachestat_config,
57 - .config_file = NETDATA_CACHESTAT_CONFIG_FILE},
60 + .config_file = NETDATA_CACHESTAT_CONFIG_FILE,
61 + .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4 | NETDATA_V5_15,
62 + .load = EBPF_LOAD_LEGACY, .targets = NULL},
63 { .thread_name = "sync", .config_name = "sync", .enabled = 0, .start_routine = ebpf_sync_thread,
64 .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO,
65 .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0, .apps_routine = NULL, .maps = NULL,
66 .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &sync_config,
62 - .config_file = NETDATA_SYNC_CONFIG_FILE},
67 + .config_file = NETDATA_SYNC_CONFIG_FILE,
68 + // All syscalls have the same kernels
69 + .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4,
70 + .load = EBPF_LOAD_LEGACY, .targets = NULL},
71 { .thread_name = "dc", .config_name = "dc", .enabled = 0, .start_routine = ebpf_dcstat_thread,
72 .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO,
73 .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
74 .apps_routine = ebpf_dcstat_create_apps_charts, .maps = NULL,
75 .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &dcstat_config,
68 - .config_file = NETDATA_DIRECTORY_DCSTAT_CONFIG_FILE},
76 + .config_file = NETDATA_DIRECTORY_DCSTAT_CONFIG_FILE,
77 + .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4,
78 + .load = EBPF_LOAD_LEGACY, .targets = NULL},
79 { .thread_name = "swap", .config_name = "swap", .enabled = 0, .start_routine = ebpf_swap_thread,
80 .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO,
81 .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
82 .apps_routine = ebpf_swap_create_apps_charts, .maps = NULL,
83 .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &swap_config,
74 - .config_file = NETDATA_DIRECTORY_SWAP_CONFIG_FILE},
84 + .config_file = NETDATA_DIRECTORY_SWAP_CONFIG_FILE,
85 + .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4,
86 + .load = EBPF_LOAD_LEGACY, .targets = NULL},
87 { .thread_name = "vfs", .config_name = "vfs", .enabled = 0, .start_routine = ebpf_vfs_thread,
88 .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO,
89 .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
90 .apps_routine = ebpf_vfs_create_apps_charts, .maps = NULL,
91 .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &vfs_config,
80 - .config_file = NETDATA_DIRECTORY_VFS_CONFIG_FILE },
92 + .config_file = NETDATA_DIRECTORY_VFS_CONFIG_FILE,
93 + .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4,
94 + .load = EBPF_LOAD_LEGACY, .targets = NULL},
95 { .thread_name = "filesystem", .config_name = "filesystem", .enabled = 0, .start_routine = ebpf_filesystem_thread,
96 .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO,
97 .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0, .apps_routine = NULL, .maps = NULL,
98 .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &fs_config,
85 - .config_file = NETDATA_FILESYSTEM_CONFIG_FILE},
99 + .config_file = NETDATA_FILESYSTEM_CONFIG_FILE,
100 + //We are setting kernels as zero, because we load eBPF programs according the kernel running.
101 + .kernels = 0, .load = EBPF_LOAD_LEGACY, .targets = NULL },
102 { .thread_name = "disk", .config_name = "disk", .enabled = 0, .start_routine = ebpf_disk_thread,
103 .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO,
104 .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0, .apps_routine = NULL, .maps = NULL,
105 .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &disk_config,
90 - .config_file = NETDATA_DISK_CONFIG_FILE},
106 + .config_file = NETDATA_DISK_CONFIG_FILE,
107 + .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4,
108 + .load = EBPF_LOAD_LEGACY, .targets = NULL},
109 { .thread_name = "mount", .config_name = "mount", .enabled = 0, .start_routine = ebpf_mount_thread,
110 .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO,
111 .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0, .apps_routine = NULL, .maps = NULL,
112 .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &mount_config,
95 - .config_file = NETDATA_MOUNT_CONFIG_FILE},
113 + .config_file = NETDATA_MOUNT_CONFIG_FILE,
114 + .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4,
115 + .load = EBPF_LOAD_LEGACY, .targets = NULL},
116 { .thread_name = "fd", .config_name = "fd", .enabled = 0, .start_routine = ebpf_fd_thread,
117 .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO,
118 .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
119 .apps_routine = ebpf_fd_create_apps_charts, .maps = NULL,
120 .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &fd_config,
101 - .config_file = NETDATA_FD_CONFIG_FILE},
121 + .config_file = NETDATA_FD_CONFIG_FILE,
122 + .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4 | NETDATA_V5_11,
123 + .load = EBPF_LOAD_LEGACY, .targets = NULL},
124 { .thread_name = "hardirq", .config_name = "hardirq", .enabled = 0, .start_routine = ebpf_hardirq_thread,
125 .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO,
126 .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0, .apps_routine = NULL, .maps = NULL,
127 .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &hardirq_config,
106 - .config_file = NETDATA_HARDIRQ_CONFIG_FILE},
128 + .config_file = NETDATA_HARDIRQ_CONFIG_FILE,
129 + .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4,
130 + .load = EBPF_LOAD_LEGACY, .targets = NULL},
131 { .thread_name = "softirq", .config_name = "softirq", .enabled = 0, .start_routine = ebpf_softirq_thread,
132 .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO,
133 .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0, .apps_routine = NULL, .maps = NULL,
134 .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &softirq_config,
111 - .config_file = NETDATA_SOFTIRQ_CONFIG_FILE},
135 + .config_file = NETDATA_SOFTIRQ_CONFIG_FILE,
136 + .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4,
137 + .load = EBPF_LOAD_LEGACY, .targets = NULL},
138 { .thread_name = "oomkill", .config_name = "oomkill", .enabled = 0, .start_routine = ebpf_oomkill_thread,
139 .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO,
140 .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
141 .apps_routine = ebpf_oomkill_create_apps_charts, .maps = NULL,
142 .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &oomkill_config,
117 - .config_file = NETDATA_OOMKILL_CONFIG_FILE},
143 + .config_file = NETDATA_OOMKILL_CONFIG_FILE,
144 + .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4,
145 + .load = EBPF_LOAD_LEGACY, .targets = NULL},
146 { .thread_name = "shm", .config_name = "shm", .enabled = 0, .start_routine = ebpf_shm_thread,
147 .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO,
148 .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
149 .apps_routine = ebpf_shm_create_apps_charts, .maps = NULL,
150 .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &shm_config,
123 - .config_file = NETDATA_DIRECTORY_SHM_CONFIG_FILE},
151 + .config_file = NETDATA_DIRECTORY_SHM_CONFIG_FILE,
152 + .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4,
153 + .load = EBPF_LOAD_LEGACY, .targets = NULL},
154 { .thread_name = "mdflush", .config_name = "mdflush", .enabled = 0, .start_routine = ebpf_mdflush_thread,
155 .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO,
156 .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0, .apps_routine = NULL, .maps = NULL,
157 .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &mdflush_config,
128 - .config_file = NETDATA_DIRECTORY_MDFLUSH_CONFIG_FILE},
129 - { .thread_name = NULL, .enabled = 0, .start_routine = NULL, .update_every = EBPF_DEFAULT_UPDATE_EVERY,
158 + .config_file = NETDATA_DIRECTORY_MDFLUSH_CONFIG_FILE,
159 + .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4,
160 + .load = EBPF_LOAD_LEGACY, .targets = NULL},
161 + { .thread_name = NULL, .enabled = 0, .start_routine = NULL, .update_every = EBPF_DEFAULT_UPDATE_EVERY,
162 .global_charts = 0, .apps_charts = CONFIG_BOOLEAN_NO, .cgroup_charts = CONFIG_BOOLEAN_NO,
163 .mode = MODE_ENTRY, .optional = 0, .apps_routine = NULL, .maps = NULL, .pid_map_size = 0, .names = NULL,
132 - .cfg = NULL, .config_name = NULL},
164 + .cfg = NULL, .config_name = NULL, .kernels = 0, .load = EBPF_LOAD_LEGACY, .targets = NULL},
165 };
166
167 // Link with apps.plugin
@@ -144,6 +176,10 @@ pthread_mutex_t mutex_cgroup_shm;
176 //Network viewer
177 ebpf_network_viewer_options_t network_viewer_opt;
178
179 +// Statistic
180 +ebpf_plugin_stats_t plugin_statistics = {.core = 0, .legacy = 0, .running = 0, .threads = 0, .tracepoints = 0,
181 + .probes = 0, .retprobes = 0, .trampolines = 0};
182 +
183 /*****************************************************************
184 *
185 * FUNCTIONS USED TO CLEAN MEMORY AND OPERATE SYSTEM FILES
@@ -726,6 +762,20 @@ static inline void ebpf_disable_cgroups()
762 }
763 }
764
765 +/**
766 + * Update Disabled Plugins
767 + *
768 + * This function calls ebpf_update_stats to update statistics for collector.
769 + *
770 + * @param em a pointer to `struct ebpf_module`
771 + */
772 +void ebpf_update_disabled_plugin_stats(ebpf_module_t *em)
773 +{
774 + pthread_mutex_lock(&lock);
775 + ebpf_update_stats(&plugin_statistics, em);
776 + pthread_mutex_unlock(&lock);
777 +}
778 +
779 /**
780 * Print help on standard error for user knows how to use the collector.
781 */
@@ -792,6 +842,10 @@ void ebpf_print_help()
842 " [-]-swap Enable chart related to swap run time.\n"
843 "\n"
844 " [-]-vfs Enable chart related to vfs run time.\n"
845 + "\n"
846 + " [-]-legacy Load legacy eBPF programs.\n"
847 + "\n"
848 + " [-]-core Use CO-RE when available(Working in progress).\n"
849 "\n",
850 VERSION,
851 (year >= 116) ? year + 1900 : 2020);
@@ -1302,7 +1356,6 @@ void set_global_variables()
1356 isrh = get_redhat_release();
1357 pid_max = get_system_pid_max();
1358 running_on_kernel = ebpf_get_kernel_version();
1305 - ebpf_update_kernel(kernel_string, 63, isrh, running_on_kernel);
1359 }
1360
1361 /**
@@ -1318,6 +1371,19 @@ static inline void ebpf_load_thread_config()
1371 }
1372 }
1373
1374 +/**
1375 + * Set Load mode
1376 + *
1377 + * @param load default load mode.
1378 + */
1379 +static inline void ebpf_set_load_mode(netdata_ebpf_load_mode_t load)
1380 +{
1381 + int i;
1382 + for (i = 0; ebpf_modules[i].thread_name; i++) {
1383 + ebpf_modules[i].load = load;
1384 + }
1385 +}
1386 +
1387 /**
1388 * Parse arguments given from user.
1389 *
@@ -1354,6 +1420,8 @@ static void ebpf_parse_args(int argc, char **argv)
1420 {"help", no_argument, 0, 0 },
1421 {"global", no_argument, 0, 0 },
1422 {"return", no_argument, 0, 0 },
1423 + {"legacy", no_argument, 0, 0 },
1424 + {"core", no_argument, 0, 0 },
1425 {0, 0, 0, 0}
1426 };
1427
@@ -1527,6 +1595,20 @@ static void ebpf_parse_args(int argc, char **argv)
1595 ebpf_set_thread_mode(MODE_RETURN);
1596 #ifdef NETDATA_INTERNAL_CHECKS
1597 info("EBPF running in \"RETURN\" mode, because it was started with the option \"[-]-return\".");
1598 +#endif
1599 + break;
1600 + }
1601 + case EBPF_OPTION_LEGACY: {
1602 + ebpf_set_load_mode(EBPF_LOAD_LEGACY);
1603 +#ifdef NETDATA_INTERNAL_CHECKS
1604 + info("EBPF running with \"LEGACY\" code, because it was started with the option \"[-]-legacy\".");
1605 +#endif
1606 + break;
1607 + }
1608 + case EBPF_OPTION_CORE: {
1609 + ebpf_set_load_mode(EBPF_LOAD_CORE);
1610 +#ifdef NETDATA_INTERNAL_CHECKS
1611 + info("EBPF running with \"CO-RE\" code, because it was started with the option \"[-]-core\".");
1612 #endif
1613 break;
1614 }
collectors/ebpf.plugin/ebpf.h
+10 -2
@@ -97,7 +97,9 @@ enum ebpf_main_index {
97 EBPF_OPTION_VERSION,
98 EBPF_OPTION_HELP,
99 EBPF_OPTION_GLOBAL_CHART,
100 - EBPF_OPTION_RETURN_MODE
100 + EBPF_OPTION_RETURN_MODE,
101 + EBPF_OPTION_LEGACY,
102 + EBPF_OPTION_CORE
103 };
104
105 typedef struct ebpf_tracepoint {
@@ -127,6 +129,11 @@ typedef struct ebpf_tracepoint {
129 #define NETDATA_SYSTEM_SWAP_SUBMENU "swap"
130 #define NETDATA_SYSTEM_CGROUP_SWAP_SUBMENU "swap (eBPF)"
131 #define NETDATA_SYSTEM_IPC_SHM_SUBMENU "ipc shared memory"
132 +#define NETDATA_MONITORING_FAMILY "netdata"
133 +
134 +// Statistics charts
135 +#define NETDATA_EBPF_THREADS "ebpf_threads"
136 +#define NETDATA_EBPF_LOAD_METHOD "ebpf_load_methods"
137
138 // Log file
139 #define NETDATA_DEVELOPER_LOG_FILE "developer.log"
@@ -160,7 +167,6 @@ extern int ebpf_nprocs;
167 extern int running_on_kernel;
168 extern int isrh;
169 extern char *ebpf_plugin_dir;
163 -extern char kernel_string[64];
170
171 extern pthread_mutex_t collect_data_mutex;
172 extern pthread_cond_t collect_data_cond_var;
@@ -257,6 +263,7 @@ extern sem_t *shm_sem_ebpf_cgroup;
263 extern pthread_mutex_t mutex_cgroup_shm;
264 extern size_t all_pids_count;
265 extern uint32_t finalized_threads;
266 +extern ebpf_plugin_stats_t plugin_statistics;
267
268 // Socket functions and variables
269 // Common functions
@@ -269,6 +276,7 @@ extern void ebpf_update_pid_table(ebpf_local_maps_t *pid, ebpf_module_t *em);
276 extern void ebpf_write_chart_obsolete(char *type, char *id, char *title, char *units, char *family,
277 char *charttype, char *context, int order, int update_every);
278 extern void write_histogram_chart(char *family, char *name, const netdata_idx_t *hist, char **dimensions, uint32_t end);
279 +void ebpf_update_disabled_plugin_stats(ebpf_module_t *em);
280
281 #define EBPF_MAX_SYNCHRONIZATION_TIME 300
282
collectors/ebpf.plugin/ebpf_cachestat.c
+7 -1
@@ -985,12 +985,15 @@ void *ebpf_cachestat_thread(void *ptr)
985 pthread_mutex_lock(&lock);
986 ebpf_cachestat_allocate_global_vectors(em->apps_charts);
987
988 - probe_links = ebpf_load_program(ebpf_plugin_dir, em, kernel_string, &objects);
988 + probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &objects);
989 if (!probe_links) {
990 pthread_mutex_unlock(&lock);
991 + em->enabled = CONFIG_BOOLEAN_NO;
992 goto endcachestat;
993 }
994
995 + ebpf_update_stats(&plugin_statistics, em);
996 +
997 int algorithms[NETDATA_CACHESTAT_END] = {
998 NETDATA_EBPF_ABSOLUTE_IDX, NETDATA_EBPF_INCREMENTAL_IDX, NETDATA_EBPF_ABSOLUTE_IDX, NETDATA_EBPF_ABSOLUTE_IDX
999 };
@@ -1006,6 +1009,9 @@ void *ebpf_cachestat_thread(void *ptr)
1009 cachestat_collector(em);
1010
1011 endcachestat:
1012 + if (!em->enabled)
1013 + ebpf_update_disabled_plugin_stats(em);
1014 +
1015 netdata_thread_cleanup_pop(1);
1016 return NULL;
1017 }
collectors/ebpf.plugin/ebpf_dcstat.c
+7 -1
@@ -964,9 +964,10 @@ void *ebpf_dcstat_thread(void *ptr)
964
965 pthread_mutex_lock(&lock);
966
967 - probe_links = ebpf_load_program(ebpf_plugin_dir, em, kernel_string, &objects);
967 + probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &objects);
968 if (!probe_links) {
969 pthread_mutex_unlock(&lock);
970 + em->enabled = CONFIG_BOOLEAN_NO;
971 goto enddcstat;
972 }
973
@@ -980,11 +981,16 @@ void *ebpf_dcstat_thread(void *ptr)
981 algorithms, NETDATA_DCSTAT_IDX_END);
982
983 ebpf_create_filesystem_charts(em->update_every);
984 + ebpf_update_stats(&plugin_statistics, em);
985 +
986 pthread_mutex_unlock(&lock);
987
988 dcstat_collector(em);
989
990 enddcstat:
991 + if (!em->enabled)
992 + ebpf_update_disabled_plugin_stats(em);
993 +
994 netdata_thread_cleanup_pop(1);
995 return NULL;
996 }
collectors/ebpf.plugin/ebpf_disk.c
+10 -1
@@ -817,12 +817,14 @@ void *ebpf_disk_thread(void *ptr)
817 }
818
819 if (pthread_mutex_init(&plot_mutex, NULL)) {
820 + em->enabled = 0;
821 error("Cannot initialize local mutex");
822 goto enddisk;
823 }
824
824 - probe_links = ebpf_load_program(ebpf_plugin_dir, em, kernel_string, &objects);
825 + probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &objects);
826 if (!probe_links) {
827 + em->enabled = 0;
828 goto enddisk;
829 }
830
@@ -833,9 +835,16 @@ void *ebpf_disk_thread(void *ptr)
835 ebpf_global_labels(disk_aggregated_data, disk_publish_aggregated, dimensions, dimensions, algorithms,
836 NETDATA_EBPF_HIST_MAX_BINS);
837
838 + pthread_mutex_lock(&lock);
839 + ebpf_update_stats(&plugin_statistics, em);
840 + pthread_mutex_unlock(&lock);
841 +
842 disk_collector(em);
843
844 enddisk:
845 + if (!em->enabled)
846 + ebpf_update_disabled_plugin_stats(em);
847 +
848 netdata_thread_cleanup_pop(1);
849
850 return NULL;
collectors/ebpf.plugin/ebpf_fd.c
+6 -1
@@ -841,8 +841,9 @@ void *ebpf_fd_thread(void *ptr)
841
842 ebpf_fd_allocate_global_vectors(em->apps_charts);
843
844 - probe_links = ebpf_load_program(ebpf_plugin_dir, em, kernel_string, &objects);
844 + probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &objects);
845 if (!probe_links) {
846 + em->enabled = CONFIG_BOOLEAN_NO;
847 goto endfd;
848 }
849
@@ -855,11 +856,15 @@ void *ebpf_fd_thread(void *ptr)
856
857 pthread_mutex_lock(&lock);
858 ebpf_create_fd_global_charts(em);
859 + ebpf_update_stats(&plugin_statistics, em);
860 pthread_mutex_unlock(&lock);
861
862 fd_collector(em);
863
864 endfd:
865 + if (!em->enabled)
866 + ebpf_update_disabled_plugin_stats(em);
867 +
868 netdata_thread_cleanup_pop(1);
869 return NULL;
870 }
collectors/ebpf.plugin/ebpf_filesystem.c
+22 -8
@@ -38,7 +38,8 @@ ebpf_filesystem_partitions_t localfs[] =
38 .probe_links = NULL,
39 .flags = NETDATA_FILESYSTEM_FLAG_NO_PARTITION,
40 .enabled = CONFIG_BOOLEAN_YES,
41 - .addresses = {.function = NULL, .addr = 0}},
41 + .addresses = {.function = NULL, .addr = 0},
42 + .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4},
43 {.filesystem = "xfs",
44 .optional_filesystem = NULL,
45 .family = "xfs",
@@ -46,7 +47,8 @@ ebpf_filesystem_partitions_t localfs[] =
47 .probe_links = NULL,
48 .flags = NETDATA_FILESYSTEM_FLAG_NO_PARTITION,
49 .enabled = CONFIG_BOOLEAN_YES,
49 - .addresses = {.function = NULL, .addr = 0}},
50 + .addresses = {.function = NULL, .addr = 0},
51 + .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4},
52 {.filesystem = "nfs",
53 .optional_filesystem = "nfs4",
54 .family = "nfs",
@@ -54,7 +56,8 @@ ebpf_filesystem_partitions_t localfs[] =
56 .probe_links = NULL,
57 .flags = NETDATA_FILESYSTEM_ATTR_CHARTS,
58 .enabled = CONFIG_BOOLEAN_YES,
57 - .addresses = {.function = NULL, .addr = 0}},
59 + .addresses = {.function = NULL, .addr = 0},
60 + .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4},
61 {.filesystem = "zfs",
62 .optional_filesystem = NULL,
63 .family = "zfs",
@@ -62,7 +65,8 @@ ebpf_filesystem_partitions_t localfs[] =
65 .probe_links = NULL,
66 .flags = NETDATA_FILESYSTEM_FLAG_NO_PARTITION,
67 .enabled = CONFIG_BOOLEAN_YES,
65 - .addresses = {.function = NULL, .addr = 0}},
68 + .addresses = {.function = NULL, .addr = 0},
69 + .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4},
70 {.filesystem = "btrfs",
71 .optional_filesystem = NULL,
72 .family = "btrfs",
@@ -70,7 +74,8 @@ ebpf_filesystem_partitions_t localfs[] =
74 .probe_links = NULL,
75 .flags = NETDATA_FILESYSTEM_FILL_ADDRESS_TABLE,
76 .enabled = CONFIG_BOOLEAN_YES,
73 - .addresses = {.function = "btrfs_file_operations", .addr = 0}},
77 + .addresses = {.function = "btrfs_file_operations", .addr = 0},
78 + .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4 | NETDATA_V5_10},
79 {.filesystem = NULL,
80 .optional_filesystem = NULL,
81 .family = NULL,
@@ -78,7 +83,8 @@ ebpf_filesystem_partitions_t localfs[] =
83 .probe_links = NULL,
84 .flags = NETDATA_FILESYSTEM_FLAG_NO_PARTITION,
85 .enabled = CONFIG_BOOLEAN_YES,
81 - .addresses = {.function = NULL, .addr = 0}}};
86 + .addresses = {.function = NULL, .addr = 0},
87 + .kernels = 0}};
88
89 struct netdata_static_thread filesystem_threads = {"EBPF FS READ",
90 NULL, NULL, 1, NULL,
@@ -224,13 +230,16 @@ int ebpf_filesystem_initialize_ebpf_data(ebpf_module_t *em)
230 {
231 int i;
232 const char *saved_name = em->thread_name;
233 + uint64_t kernels = em->kernels;
234 for (i = 0; localfs[i].filesystem; i++) {
235 ebpf_filesystem_partitions_t *efp = &localfs[i];
236 if (!efp->probe_links && efp->flags & NETDATA_FILESYSTEM_LOAD_EBPF_PROGRAM) {
237 em->thread_name = efp->filesystem;
231 - efp->probe_links = ebpf_load_program(ebpf_plugin_dir, em, kernel_string, &efp->objects);
238 + em->kernels = efp->kernels;
239 + efp->probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &efp->objects);
240 if (!efp->probe_links) {
241 em->thread_name = saved_name;
242 + em->kernels = kernels;
243 return -1;
244 }
245 efp->flags |= NETDATA_FILESYSTEM_FLAG_HAS_PARTITION;
@@ -243,6 +252,7 @@ int ebpf_filesystem_initialize_ebpf_data(ebpf_module_t *em)
252 efp->flags &= ~NETDATA_FILESYSTEM_LOAD_EBPF_PROGRAM;
253 }
254 em->thread_name = saved_name;
255 + em->kernels = kernels;
256
257 if (!dimensions) {
258 dimensions = ebpf_fill_histogram_dimension(NETDATA_EBPF_HIST_MAX_BINS);
@@ -640,7 +650,7 @@ void *ebpf_filesystem_thread(void *ptr)
650 if (em->optional)
651 info("Netdata cannot monitor the filesystems used on this host.");
652
643 - em->enabled = 0;
653 + em->enabled = CONFIG_BOOLEAN_NO;
654 goto endfilesystem;
655 }
656
@@ -651,11 +661,15 @@ void *ebpf_filesystem_thread(void *ptr)
661
662 pthread_mutex_lock(&lock);
663 ebpf_create_fs_charts(em->update_every);
664 + ebpf_update_stats(&plugin_statistics, em);
665 pthread_mutex_unlock(&lock);
666
667 filesystem_collector(em);
668
669 endfilesystem:
670 + if (!em->enabled)
671 + ebpf_update_disabled_plugin_stats(em);
672 +
673 netdata_thread_cleanup_pop(1);
674 return NULL;
675 }
collectors/ebpf.plugin/ebpf_filesystem.h
+1
@@ -60,6 +60,7 @@ typedef struct ebpf_filesystem_partitions {
60 uint32_t enabled;
61
62 ebpf_addresses_t addresses;
63 + uint64_t kernels;
64 } ebpf_filesystem_partitions_t;
65
66 extern void *ebpf_filesystem_thread(void *ptr);
collectors/ebpf.plugin/ebpf_hardirq.c
+6 -1
@@ -428,6 +428,7 @@ static void hardirq_collector(ebpf_module_t *em)
428 pthread_mutex_lock(&lock);
429 hardirq_create_charts(em->update_every);
430 hardirq_create_static_dims();
431 + ebpf_update_stats(&plugin_statistics, em);
432 pthread_mutex_unlock(&lock);
433
434 // loop and read from published data until ebpf plugin is closed.
@@ -480,14 +481,18 @@ void *ebpf_hardirq_thread(void *ptr)
481 goto endhardirq;
482 }
483
483 - probe_links = ebpf_load_program(ebpf_plugin_dir, em, kernel_string, &objects);
484 + probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &objects);
485 if (!probe_links) {
486 + em->enabled = CONFIG_BOOLEAN_NO;
487 goto endhardirq;
488 }
489
490 hardirq_collector(em);
491
492 endhardirq:
493 + if (!em->enabled)
494 + ebpf_update_disabled_plugin_stats(em);
495 +
496 netdata_thread_cleanup_pop(1);
497
498 return NULL;
collectors/ebpf.plugin/ebpf_mdflush.c
+6 -1
@@ -256,6 +256,7 @@ static void mdflush_collector(ebpf_module_t *em)
256 // create chart and static dims.
257 pthread_mutex_lock(&lock);
258 mdflush_create_charts(em->update_every);
259 + ebpf_update_stats(&plugin_statistics, em);
260 pthread_mutex_unlock(&lock);
261
262 // loop and read from published data until ebpf plugin is closed.
@@ -305,14 +306,18 @@ void *ebpf_mdflush_thread(void *ptr)
306 goto endmdflush;
307 }
308
308 - probe_links = ebpf_load_program(ebpf_plugin_dir, em, kernel_string, &objects);
309 + probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &objects);
310 if (!probe_links) {
311 + em->enabled = CONFIG_BOOLEAN_NO;
312 goto endmdflush;
313 }
314
315 mdflush_collector(em);
316
317 endmdflush:
318 + if (!em->enabled)
319 + ebpf_update_disabled_plugin_stats(em);
320 +
321 netdata_thread_cleanup_pop(1);
322
323 return NULL;
collectors/ebpf.plugin/ebpf_mount.c
+6 -1
@@ -238,8 +238,9 @@ void *ebpf_mount_thread(void *ptr)
238 if (!em->enabled)
239 goto endmount;
240
241 - probe_links = ebpf_load_program(ebpf_plugin_dir, em, kernel_string, &objects);
241 + probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &objects);
242 if (!probe_links) {
243 + em->enabled = CONFIG_BOOLEAN_NO;
244 goto endmount;
245 }
246
@@ -250,11 +251,15 @@ void *ebpf_mount_thread(void *ptr)
251
252 pthread_mutex_lock(&lock);
253 ebpf_create_mount_charts(em->update_every);
254 + ebpf_update_stats(&plugin_statistics, em);
255 pthread_mutex_unlock(&lock);
256
257 mount_collector(em);
258
259 endmount:
260 + if (!em->enabled)
261 + ebpf_update_disabled_plugin_stats(em);
262 +
263 netdata_thread_cleanup_pop(1);
264 return NULL;
265 }
collectors/ebpf.plugin/ebpf_oomkill.c
+9 -1
@@ -386,14 +386,22 @@ void *ebpf_oomkill_thread(void *ptr)
386 goto endoomkill;
387 }
388
389 - probe_links = ebpf_load_program(ebpf_plugin_dir, em, kernel_string, &objects);
389 + probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &objects);
390 if (!probe_links) {
391 + em->enabled = CONFIG_BOOLEAN_NO;
392 goto endoomkill;
393 }
394
395 + pthread_mutex_lock(&lock);
396 + ebpf_update_stats(&plugin_statistics, em);
397 + pthread_mutex_unlock(&lock);
398 +
399 oomkill_collector(em);
400
401 endoomkill:
402 + if (!em->enabled)
403 + ebpf_update_disabled_plugin_stats(em);
404 +
405 netdata_thread_cleanup_pop(1);
406
407 return NULL;
collectors/ebpf.plugin/ebpf_process.c
+106 -5
@@ -58,6 +58,10 @@ struct config process_config = { .first_section = NULL,
58
59 static struct netdata_static_thread cgroup_thread = {"EBPF CGROUP", NULL, NULL,
60 1, NULL, NULL, NULL};
61 +
62 +static char *threads_stat[NETDATA_EBPF_THREAD_STAT_END] = {"total", "running"};
63 +static char *load_event_stat[NETDATA_EBPF_LOAD_STAT_END] = {"legacy", "co-re"};
64 +
65 /*****************************************************************
66 *
67 * PROCESS DATA AND SEND TO NETDATA
@@ -434,6 +438,78 @@ static void ebpf_create_global_charts(ebpf_module_t *em)
438 }
439 }
440
441 +/**
442 + * Create chart for Statistic Thread
443 + *
444 + * Write to standard output current values for threads.
445 + *
446 + * @param em a pointer to the structure with the default values.
447 + */
448 +static inline void ebpf_create_statistic_thread_chart(ebpf_module_t *em)
449 +{
450 + ebpf_write_chart_cmd(NETDATA_MONITORING_FAMILY,
451 + NETDATA_EBPF_THREADS,
452 + "Threads info.",
453 + "threads",
454 + NETDATA_EBPF_FAMILY,
455 + NETDATA_EBPF_CHART_TYPE_LINE,
456 + NULL,
457 + 140000,
458 + em->update_every,
459 + NETDATA_EBPF_MODULE_NAME_PROCESS);
460 +
461 + ebpf_write_global_dimension(threads_stat[NETDATA_EBPF_THREAD_STAT_TOTAL],
462 + threads_stat[NETDATA_EBPF_THREAD_STAT_TOTAL],
463 + ebpf_algorithms[NETDATA_EBPF_ABSOLUTE_IDX]);
464 +
465 + ebpf_write_global_dimension(threads_stat[NETDATA_EBPF_THREAD_STAT_RUNNING],
466 + threads_stat[NETDATA_EBPF_THREAD_STAT_RUNNING],
467 + ebpf_algorithms[NETDATA_EBPF_ABSOLUTE_IDX]);
468 +}
469 +
470 +/**
471 + * Create chart for Load Thread
472 + *
473 + * Write to standard output current values for load mode.
474 + *
475 + * @param em a pointer to the structure with the default values.
476 + */
477 +static inline void ebpf_create_statistic_load_chart(ebpf_module_t *em)
478 +{
479 + ebpf_write_chart_cmd(NETDATA_MONITORING_FAMILY,
480 + NETDATA_EBPF_LOAD_METHOD,
481 + "Load info.",
482 + "methods",
483 + NETDATA_EBPF_FAMILY,
484 + NETDATA_EBPF_CHART_TYPE_LINE,
485 + NULL,
486 + 140001,
487 + em->update_every,
488 + NETDATA_EBPF_MODULE_NAME_PROCESS);
489 +
490 + ebpf_write_global_dimension(load_event_stat[NETDATA_EBPF_LOAD_STAT_LEGACY],
491 + load_event_stat[NETDATA_EBPF_LOAD_STAT_LEGACY],
492 + ebpf_algorithms[NETDATA_EBPF_ABSOLUTE_IDX]);
493 +
494 + ebpf_write_global_dimension(load_event_stat[NETDATA_EBPF_LOAD_STAT_CORE],
495 + load_event_stat[NETDATA_EBPF_LOAD_STAT_CORE],
496 + ebpf_algorithms[NETDATA_EBPF_ABSOLUTE_IDX]);
497 +}
498 +
499 +/**
500 + * Create Statistics Charts
501 + *
502 + * Create charts that will show statistics related to eBPF plugin.
503 + *
504 + * @param em a pointer to the structure with the default values.
505 + */
506 +static void ebpf_create_statistic_charts(ebpf_module_t *em)
507 +{
508 + ebpf_create_statistic_thread_chart(em);
509 +
510 + ebpf_create_statistic_load_chart(em);
511 +}
512 +
513 /**
514 * Create process apps charts
515 *
@@ -912,6 +988,24 @@ void ebpf_process_update_cgroup_algorithm()
988 }
989 }
990
991 +/**
992 + * Send Statistic Data
993 + *
994 + * Send statistic information to netdata.
995 + */
996 +void ebpf_send_statistic_data()
997 +{
998 + write_begin_chart(NETDATA_MONITORING_FAMILY, NETDATA_EBPF_THREADS);
999 + write_chart_dimension(threads_stat[NETDATA_EBPF_THREAD_STAT_TOTAL], (long long)plugin_statistics.threads);
1000 + write_chart_dimension(threads_stat[NETDATA_EBPF_THREAD_STAT_RUNNING], (long long)plugin_statistics.running);
1001 + write_end_chart();
1002 +
1003 + write_begin_chart(NETDATA_MONITORING_FAMILY, NETDATA_EBPF_LOAD_METHOD);
1004 + write_chart_dimension(load_event_stat[NETDATA_EBPF_LOAD_STAT_LEGACY], (long long)plugin_statistics.legacy);
1005 + write_chart_dimension(load_event_stat[NETDATA_EBPF_LOAD_STAT_CORE], (long long)plugin_statistics.core);
1006 + write_end_chart();
1007 +}
1008 +
1009 /**
1010 * Main loop for this collector.
1011 *
@@ -967,8 +1061,10 @@ static void process_collector(ebpf_module_t *em)
1061 }
1062 }
1063
1064 + pthread_mutex_lock(&lock);
1065 + ebpf_send_statistic_data();
1066 +
1067 if (thread_enabled) {
971 - pthread_mutex_lock(&lock);
1068 if (publish_global) {
1069 ebpf_process_send_data(em);
1070 }
@@ -980,12 +1076,10 @@ static void process_collector(ebpf_module_t *em)
1076 if (cgroups) {
1077 ebpf_process_send_cgroup_data(em);
1078 }
983 - pthread_mutex_unlock(&lock);
1079 }
1080 + pthread_mutex_unlock(&lock);
1081 }
1082
987 - pthread_mutex_unlock(&lock);
988 -
1083 fflush(stdout);
1084 }
1085 }
@@ -1212,8 +1306,9 @@ void *ebpf_process_thread(void *ptr)
1306 ebpf_update_pid_table(&process_maps[0], em);
1307
1308 set_local_pointers();
1215 - probe_links = ebpf_load_program(ebpf_plugin_dir, em, kernel_string, &objects);
1309 + probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &objects);
1310 if (!probe_links) {
1311 + em->enabled = CONFIG_BOOLEAN_NO;
1312 pthread_mutex_unlock(&lock);
1313 goto endprocess;
1314 }
@@ -1230,11 +1325,17 @@ void *ebpf_process_thread(void *ptr)
1325 ebpf_create_global_charts(em);
1326 }
1327
1328 + ebpf_update_stats(&plugin_statistics, em);
1329 + ebpf_create_statistic_charts(em);
1330 +
1331 pthread_mutex_unlock(&lock);
1332
1333 process_collector(em);
1334
1335 endprocess:
1336 + if (!em->enabled)
1337 + ebpf_update_disabled_plugin_stats(em);
1338 +
1339 wait_for_all_threads_die();
1340 netdata_thread_cleanup_pop(1);
1341 return NULL;
collectors/ebpf.plugin/ebpf_process.h
+15
@@ -39,6 +39,21 @@
39 #define NETDATA_SYSTEMD_PROCESS_EXIT_CONTEXT "services.task_exit"
40 #define NETDATA_SYSTEMD_PROCESS_ERROR_CONTEXT "services.task_error"
41
42 +// Statistical information
43 +enum netdata_ebpf_thread_stats{
44 + NETDATA_EBPF_THREAD_STAT_TOTAL,
45 + NETDATA_EBPF_THREAD_STAT_RUNNING,
46 +
47 + NETDATA_EBPF_THREAD_STAT_END
48 +};
49 +
50 +enum netdata_ebpf_load_mode_stats{
51 + NETDATA_EBPF_LOAD_STAT_LEGACY,
52 + NETDATA_EBPF_LOAD_STAT_CORE,
53 +
54 + NETDATA_EBPF_LOAD_STAT_END
55 +};
56 +
57 // Index from kernel
58 typedef enum ebpf_process_index {
59 NETDATA_KEY_CALLS_DO_EXIT,
collectors/ebpf.plugin/ebpf_shm.c
+6 -1
@@ -821,8 +821,9 @@ void *ebpf_shm_thread(void *ptr)
821 goto endshm;
822 }
823
824 - probe_links = ebpf_load_program(ebpf_plugin_dir, em, kernel_string, &objects);
824 + probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &objects);
825 if (!probe_links) {
826 + em->enabled = CONFIG_BOOLEAN_NO;
827 goto endshm;
828 }
829
@@ -845,11 +846,15 @@ void *ebpf_shm_thread(void *ptr)
846
847 pthread_mutex_lock(&lock);
848 ebpf_create_shm_charts(em->update_every);
849 + ebpf_update_stats(&plugin_statistics, em);
850 pthread_mutex_unlock(&lock);
851
852 shm_collector(em);
853
854 endshm:
855 + if (!em->enabled)
856 + ebpf_update_disabled_plugin_stats(em);
857 +
858 netdata_thread_cleanup_pop(1);
859 return NULL;
860 }
collectors/ebpf.plugin/ebpf_socket.c
+8 -1
@@ -3363,6 +3363,7 @@ void *ebpf_socket_thread(void *ptr)
3363 goto endsocket;
3364
3365 if (pthread_mutex_init(&nv_mutex, NULL)) {
3366 + em->enabled = CONFIG_BOOLEAN_NO;
3367 error("Cannot initialize local mutex");
3368 goto endsocket;
3369 }
@@ -3374,8 +3375,9 @@ void *ebpf_socket_thread(void *ptr)
3375 if (running_on_kernel < NETDATA_EBPF_KERNEL_5_0)
3376 em->mode = MODE_ENTRY;
3377
3377 - probe_links = ebpf_load_program(ebpf_plugin_dir, em, kernel_string, &objects);
3378 + probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &objects);
3379 if (!probe_links) {
3380 + em->enabled = CONFIG_BOOLEAN_NO;
3381 pthread_mutex_unlock(&lock);
3382 goto endsocket;
3383 }
@@ -3390,12 +3392,17 @@ void *ebpf_socket_thread(void *ptr)
3392
3393 ebpf_create_global_charts(em);
3394
3395 + ebpf_update_stats(&plugin_statistics, em);
3396 +
3397 finalized_threads = 0;
3398 pthread_mutex_unlock(&lock);
3399
3400 socket_collector((usec_t)(em->update_every * USEC_PER_SEC), em);
3401
3402 endsocket:
3403 + if (!em->enabled)
3404 + ebpf_update_disabled_plugin_stats(em);
3405 +
3406 netdata_thread_cleanup_pop(1);
3407 return NULL;
3408 }
collectors/ebpf.plugin/ebpf_softirq.c
+6 -1
@@ -209,6 +209,7 @@ static void softirq_collector(ebpf_module_t *em)
209 pthread_mutex_lock(&lock);
210 softirq_create_charts(em->update_every);
211 softirq_create_dims();
212 + ebpf_update_stats(&plugin_statistics, em);
213 pthread_mutex_unlock(&lock);
214
215 // loop and read from published data until ebpf plugin is closed.
@@ -259,14 +260,18 @@ void *ebpf_softirq_thread(void *ptr)
260 goto endsoftirq;
261 }
262
262 - probe_links = ebpf_load_program(ebpf_plugin_dir, em, kernel_string, &objects);
263 + probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &objects);
264 if (!probe_links) {
265 + em->enabled = CONFIG_BOOLEAN_NO;
266 goto endsoftirq;
267 }
268
269 softirq_collector(em);
270
271 endsoftirq:
272 + if (!em->enabled)
273 + ebpf_update_disabled_plugin_stats(em);
274 +
275 netdata_thread_cleanup_pop(1);
276
277 return NULL;
collectors/ebpf.plugin/ebpf_swap.c
+6 -1
@@ -675,8 +675,9 @@ void *ebpf_swap_thread(void *ptr)
675 if (!em->enabled)
676 goto endswap;
677
678 - probe_links = ebpf_load_program(ebpf_plugin_dir, em, kernel_string, &objects);
678 + probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &objects);
679 if (!probe_links) {
680 + em->enabled = CONFIG_BOOLEAN_NO;
681 goto endswap;
682 }
683
@@ -688,11 +689,15 @@ void *ebpf_swap_thread(void *ptr)
689
690 pthread_mutex_lock(&lock);
691 ebpf_create_swap_charts(em->update_every);
692 + ebpf_update_stats(&plugin_statistics, em);
693 pthread_mutex_unlock(&lock);
694
695 swap_collector(em);
696
697 endswap:
698 + if (!em->enabled)
699 + ebpf_update_disabled_plugin_stats(em);
700 +
701 netdata_thread_cleanup_pop(1);
702 return NULL;
703 }
collectors/ebpf.plugin/ebpf_sync.c
+6 -2
@@ -74,7 +74,7 @@ static int ebpf_sync_initialize_syscall(ebpf_module_t *em)
74 ebpf_sync_syscalls_t *w = &local_syscalls[i];
75 if (!w->probe_links && w->enabled) {
76 em->thread_name = w->syscall;
77 - w->probe_links = ebpf_load_program(ebpf_plugin_dir, em, kernel_string, &w->objects);
77 + w->probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &w->objects);
78 if (!w->probe_links) {
79 em->thread_name = saved_name;
80 return -1;
@@ -387,7 +387,7 @@ void *ebpf_sync_thread(void *ptr)
387 goto endsync;
388
389 if (ebpf_sync_initialize_syscall(em)) {
390 - pthread_mutex_unlock(&lock);
390 + em->enabled = CONFIG_BOOLEAN_NO;
391 goto endsync;
392 }
393
@@ -400,11 +400,15 @@ void *ebpf_sync_thread(void *ptr)
400
401 pthread_mutex_lock(&lock);
402 ebpf_create_sync_charts(em->update_every);
403 + ebpf_update_stats(&plugin_statistics, em);
404 pthread_mutex_unlock(&lock);
405
406 sync_collector(em);
407
408 endsync:
409 + if (!em->enabled)
410 + ebpf_update_disabled_plugin_stats(em);
411 +
412 netdata_thread_cleanup_pop(1);
413 return NULL;
414 }
collectors/ebpf.plugin/ebpf_vfs.c
+6 -1
@@ -1576,8 +1576,9 @@ void *ebpf_vfs_thread(void *ptr)
1576 if (!em->enabled)
1577 goto endvfs;
1578
1579 - probe_links = ebpf_load_program(ebpf_plugin_dir, em, kernel_string, &objects);
1579 + probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &objects);
1580 if (!probe_links) {
1581 + em->enabled = CONFIG_BOOLEAN_NO;
1582 goto endvfs;
1583 }
1584
@@ -1591,11 +1592,15 @@ void *ebpf_vfs_thread(void *ptr)
1592
1593 pthread_mutex_lock(&lock);
1594 ebpf_create_global_charts(em);
1595 + ebpf_update_stats(&plugin_statistics, em);
1596 pthread_mutex_unlock(&lock);
1597
1598 vfs_collector(em);
1599
1600 endvfs:
1601 + if (!em->enabled)
1602 + ebpf_update_disabled_plugin_stats(em);
1603 +
1604 netdata_thread_cleanup_pop(1);
1605 return NULL;
1606 }
libnetdata/ebpf/ebpf.c
+201 -49
@@ -110,9 +110,23 @@ int ebpf_get_kernel_version()
110 *move++ = *version++;
111 *move = '\0';
112
113 - return ((int)(str2l(major) * 65536) + (int)(str2l(minor) * 256) + (int)str2l(patch));
113 + // This new rule is fixing kernel version according the formula:
114 + // KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + ((c) > 255 ? 255 : (c)))
115 + // that was extracted from /usr/include/linux/version.h
116 + int ipatch = (int)str2l(patch);
117 + if (ipatch > 255)
118 + ipatch = 255;
119 +
120 + return ((int)(str2l(major) * 65536) + (int)(str2l(minor) * 256) + ipatch);
121 }
122
123 +/**
124 + * Get RH release
125 + *
126 + * Read Red Hat release from /etc/redhat-release
127 + *
128 + * @return It returns RH release on success and -1 otherwise
129 + */
130 int get_redhat_release()
131 {
132 char buffer[VERSION_STRING_LEN + 1];
@@ -249,66 +263,189 @@ int has_condition_to_run(int version)
263
264 //----------------------------------------------------------------------------------------------------------------------
265
252 -char *ebpf_kernel_suffix(int version, int isrh)
266 +/**
267 + * Kernel Name
268 + *
269 + * Select kernel name used by eBPF programs
270 + *
271 + * Netdata delivers for users eBPF programs with specific suffixes that represent the kernels they were
272 + * compiled, when we load the eBPF program, the suffix must be the nereast possible of the kernel running.
273 + *
274 + * @param selector select the kernel version.
275 + *
276 + * @return It returns the string to load kernel.
277 + */
278 +static char *ebpf_select_kernel_name(uint32_t selector)
279 {
254 - if (isrh) {
255 - if (version >= NETDATA_EBPF_KERNEL_4_11)
256 - return "4.18";
257 - else
258 - return "3.10";
259 - } else {
260 - if (version >= NETDATA_EBPF_KERNEL_5_15)
261 - return "5.15";
262 - else if (version >= NETDATA_EBPF_KERNEL_5_11)
263 - return "5.11";
264 - else if (version >= NETDATA_EBPF_KERNEL_5_10)
265 - return "5.10";
266 - else if (version >= NETDATA_EBPF_KERNEL_4_17)
267 - return "5.4";
268 - else if (version >= NETDATA_EBPF_KERNEL_4_15)
269 - return "4.16";
270 - else if (version >= NETDATA_EBPF_KERNEL_4_11)
271 - return "4.14";
280 + static char *kernel_names[] = { NETDATA_IDX_STR_V3_10, NETDATA_IDX_STR_V4_14, NETDATA_IDX_STR_V4_16,
281 + NETDATA_IDX_STR_V4_18, NETDATA_IDX_STR_V5_4, NETDATA_IDX_STR_V5_10,
282 + NETDATA_IDX_STR_V5_11, NETDATA_IDX_STR_V5_15
283 + };
284 +
285 + return kernel_names[selector];
286 +}
287 +
288 +/**
289 + * Select Max Index
290 + *
291 + * Select last index that will be tested on host.
292 + *
293 + * @param is_rhf is Red Hat fammily?
294 + * @param kver the kernel version
295 + *
296 + * @return it returns the index to access kernel string.
297 + */
298 +static int ebpf_select_max_index(int is_rhf, uint32_t kver)
299 +{
300 + if (is_rhf > 0) { // Is Red Hat family
301 + if (kver >= NETDATA_EBPF_KERNEL_4_11)
302 + return NETDATA_IDX_V4_18;
303 + } else { // Kernels from kernel.org
304 + if (kver >= NETDATA_EBPF_KERNEL_5_15)
305 + return NETDATA_IDX_V5_15;
306 + else if (kver >= NETDATA_EBPF_KERNEL_5_11)
307 + return NETDATA_IDX_V5_11;
308 + else if (kver >= NETDATA_EBPF_KERNEL_5_10)
309 + return NETDATA_IDX_V5_10;
310 + else if (kver >= NETDATA_EBPF_KERNEL_4_17)
311 + return NETDATA_IDX_V5_4;
312 + else if (kver >= NETDATA_EBPF_KERNEL_4_15)
313 + return NETDATA_IDX_V4_16;
314 + else if (kver >= NETDATA_EBPF_KERNEL_4_11)
315 + return NETDATA_IDX_V4_14;
316 }
317
274 - return NULL;
318 + return NETDATA_IDX_V3_10;
319 +}
320 +
321 +/**
322 + * Select Index
323 + *
324 + * Select index to load data.
325 + *
326 + * @param kernels is the variable with kernel versions.
327 + * @param is_rhf is Red Hat fammily?
328 + * param kver the kernel version
329 + */
330 +static uint32_t ebpf_select_index(uint32_t kernels, int is_rhf, uint32_t kver)
331 +{
332 + uint32_t start = ebpf_select_max_index(is_rhf, kver);
333 + uint32_t idx;
334 +
335 + for (idx = start; idx; idx--) {
336 + if (kernels & 1 << idx)
337 + break;
338 + }
339 +
340 + return idx;
341 +}
342 +
343 +/**
344 + * Mount Name
345 + *
346 + * Mount name of eBPF program to be loaded.
347 + *
348 + * Netdata eBPF programs has the following format:
349 + *
350 + * Tnetdata_ebpf_N.V.o
351 + *
352 + * where:
353 + * T - Is the eBPF type. When starts with 'p', this means we are only adding probes,
354 + * and when they start with 'r' we are using retprobes.
355 + * N - The eBPF program name.
356 + * V - The kernel version in string format.
357 + *
358 + * @param out the vector where the name will be stored
359 + * @param path
360 + * @param len the size of the out vector.
361 + * @param kver the kernel version
362 + * @param name the eBPF program name.
363 + * @param is_return is return or entry ?
364 + */
365 +static void ebpf_mount_name(char *out, size_t len, char *path, uint32_t kver, const char *name, int is_return)
366 +{
367 + char *version = ebpf_select_kernel_name(kver);
368 + snprintfz(out, len, "%s/ebpf.d/%cnetdata_ebpf_%s.%s.o",
369 + path,
370 + (is_return) ? 'r' : 'p',
371 + name,
372 + version);
373 }
374
375 //----------------------------------------------------------------------------------------------------------------------
376
377 /**
280 - * Update Kernel
378 + * Statistics from targets
379 *
282 - * Update string used to load eBPF programs
380 + * Count the information from targets.
381 *
284 - * @param ks vector to store the value
285 - * @param length available length to store kernel
286 - * @param isrh Is a Red Hat distribution?
287 - * @param version the kernel version
382 + * @param report the output structure
383 + * @param targets vector with information about the eBPF plugin.
384 */
289 -void ebpf_update_kernel(char *ks, size_t length, int isrh, int version)
385 +static void ebpf_stats_targets(ebpf_plugin_stats_t *report, netdata_ebpf_targets_t *targets)
386 {
291 - char *kernel = ebpf_kernel_suffix(version, (isrh < 0) ? 0 : 1);
292 - size_t len = strlen(kernel);
293 - if (len > length)
294 - len = length - 1;
295 - strncpyz(ks, kernel, len);
296 - ks[len] = '\0';
387 + if (!targets) {
388 + report->probes = report->tracepoints = report->trampolines = 0;
389 + return;
390 + }
391 +
392 + int i = 0;
393 + while (targets[i].name) {
394 + switch (targets[i].mode) {
395 + case EBPF_LOAD_PROBE: {
396 + report->probes++;
397 + break;
398 + }
399 + case EBPF_LOAD_RETPROBE: {
400 + report->retprobes++;
401 + break;
402 + }
403 + case EBPF_LOAD_TRACEPOINT: {
404 + report->tracepoints++;
405 + break;
406 + }
407 + case EBPF_LOAD_TRAMPOLINE: {
408 + report->trampolines++;
409 + break;
410 + }
411 + }
412 +
413 + i++;
414 + }
415 }
416
299 -static int select_file(char *name, const char *program, size_t length, int mode, char *kernel_string)
417 +/**
418 + * Update General stats
419 + *
420 + * Update eBPF plugin statistics that has relationship with the thread.
421 + *
422 + * This function must be called with mutex associated to charts is locked.
423 + *
424 + * @param report the output structure
425 + * @param em the structure with information about how the module/thread is working.
426 + */
427 +void ebpf_update_stats(ebpf_plugin_stats_t *report, ebpf_module_t *em)
428 {
301 - int ret = -1;
302 - if (!mode)
303 - ret = snprintf(name, length, "rnetdata_ebpf_%s.%s.o", program, kernel_string);
304 - else if (mode == 1)
305 - ret = snprintf(name, length, "dnetdata_ebpf_%s.%s.o", program, kernel_string);
306 - else if (mode == 2)
307 - ret = snprintf(name, length, "pnetdata_ebpf_%s.%s.o", program, kernel_string);
429 + report->threads++;
430
309 - return ret;
431 + // It is not necessary to report more information.
432 + if (!em->enabled)
433 + return;
434 +
435 + report->running++;
436 +
437 + // In theory the `else if` is useless, because when this function is called, the module should not stay in
438 + // EBPF_LOAD_PLAY_DICE. We have this additional condition to detect errors from developers.
439 + if (em->load == EBPF_LOAD_LEGACY)
440 + report->legacy++;
441 + else if (em->load == EBPF_LOAD_CORE)
442 + report->core++;
443 +
444 + ebpf_stats_targets(report, em->targets);
445 }
446
447 +//----------------------------------------------------------------------------------------------------------------------
448 +
449 void ebpf_update_pid_table(ebpf_local_maps_t *pid, ebpf_module_t *em)
450 {
451 pid->user_input = em->pid_map_size;
@@ -454,17 +591,28 @@ static void ebpf_update_controller(ebpf_module_t *em, struct bpf_object *obj)
591 }
592 }
593
457 -struct bpf_link **ebpf_load_program(char *plugins_dir, ebpf_module_t *em, char *kernel_string,
594 +/**
595 + * Load Program
596 + *
597 + * Load eBPF program into kernel
598 + *
599 + * @param plugins_dir directory where binary are stored
600 + * @param em structure with information about eBPF program we will load.
601 + * @param kver the kernel version according /usr/include/linux/version.h
602 + * @param is_rhf is a kernel from Red Hat Family?
603 + * @param obj structure where we will store object loaded.
604 + *
605 + * @return it returns a link for each target we associated an eBPF program.
606 + */
607 +struct bpf_link **ebpf_load_program(char *plugins_dir, ebpf_module_t *em, int kver, int is_rhf,
608 struct bpf_object **obj)
609 {
610 char lpath[4096];
461 - char lname[128];
611
463 - int test = select_file(lname, em->thread_name, (size_t)127, em->mode, kernel_string);
464 - if (test < 0 || test > 127)
465 - return NULL;
612 + uint32_t idx = ebpf_select_index(em->kernels, is_rhf, kver);
613 +
614 + ebpf_mount_name(lpath, 4095, plugins_dir, idx, em->thread_name, em->mode);
615
467 - snprintf(lpath, 4096, "%s/ebpf.d/%s", plugins_dir, lname);
616 *obj = bpf_object__open_file(lpath, NULL);
617 if (libbpf_get_error(obj)) {
618 error("Cannot open BPF object %s", lpath);
@@ -485,6 +633,10 @@ struct bpf_link **ebpf_load_program(char *plugins_dir, ebpf_module_t *em, char *
633
634 size_t count_programs = ebpf_count_programs(*obj);
635
636 +#ifdef NETDATA_INTERNAL_CHECKS
637 + info("eBPF program %s loaded with success!", lpath);
638 +#endif
639 +
640 return ebpf_attach_programs(*obj, count_programs, em->names);
641 }
642
libnetdata/ebpf/ebpf.h
+86 -50
@@ -22,14 +22,6 @@
22 #define EBPF_CFG_APPLICATION "apps"
23 #define EBPF_CFG_CGROUP "cgroups"
24
25 -/**
26 - * The next magic number is got doing the following math:
27 - * 294960 = 4*65536 + 11*256 + 0
28 - *
29 - * For more details, please, read /usr/include/linux/version.h
30 - */
31 -#define NETDATA_MINIMUM_EBPF_KERNEL 264960
32 -
25 /**
26 * The RedHat magic number was got doing:
27 *
@@ -46,53 +38,63 @@
38 #define NETDATA_RH_8 2048
39
40 /**
49 - * Kernel 5.15
41 + * Kernel Version
42 *
51 - * 331520 = 5*65536 + 15*256
52 - */
53 -#define NETDATA_EBPF_KERNEL_5_15 331520
54 -
55 -/**
56 - * Kernel 5.11
43 + * Kernel versions are calculated using the following formula:
44 *
58 - * 330240 = 5*65536 + 11*256
59 - */
60 -#define NETDATA_EBPF_KERNEL_5_11 330496
61 -
62 -/**
63 - * Kernel 5.10
45 + * VERSION = LINUX_VERSION_MAJOR*65536 + LINUX_VERSION_PATCHLEVEL*256 + LINUX_VERSION_SUBLEVEL
46 *
65 - * 330240 = 5*65536 + 10*256
66 - */
67 -#define NETDATA_EBPF_KERNEL_5_10 330240
68 -
69 -/**
70 - * Kernel 5.0
47 + * Where LINUX_VERSION_MAJOR, LINUX_VERSION_PATCHLEVEL, and LINUX_VERSION_SUBLEVEL are extracted
48 + * from /usr/include/linux/version.h.
49 *
72 - * 327680 = 5*65536 +256*0
73 - */
74 -#define NETDATA_EBPF_KERNEL_5_0 327680
75 -
76 -/**
77 - * Kernel 4.17
50 + * LINUX_VERSION_SUBLEVEL has the maximum value 255, but linux can have more SUBLEVELS.
51 *
79 - * 266496 = 4*65536 + 17*256
52 */
81 -#define NETDATA_EBPF_KERNEL_4_17 266496
53 +enum netdata_ebpf_kernel_versions {
54 + NETDATA_EBPF_KERNEL_4_11 = 264960, // 264960 = 4 * 65536 + 15 * 256
55 + NETDATA_EBPF_KERNEL_4_15 = 265984, // 265984 = 4 * 65536 + 15 * 256
56 + NETDATA_EBPF_KERNEL_4_17 = 266496, // 266496 = 4 * 65536 + 17 * 256
57 + NETDATA_EBPF_KERNEL_5_0 = 327680, // 327680 = 5 * 65536 + 0 * 256
58 + NETDATA_EBPF_KERNEL_5_10 = 330240, // 330240 = 5 * 65536 + 10 * 256
59 + NETDATA_EBPF_KERNEL_5_11 = 330496, // 330240 = 5 * 65536 + 11 * 256
60 + NETDATA_EBPF_KERNEL_5_15 = 331520 // 331520 = 5 * 65536 + 15 * 256
61 +};
62
83 -/**
84 - * Kernel 4.15
85 - *
86 - * 265984 = 4*65536 + 15*256
87 - */
88 -#define NETDATA_EBPF_KERNEL_4_15 265984
63 +enum netdata_kernel_flag {
64 + NETDATA_V3_10 = 1 << 0,
65 + NETDATA_V4_14 = 1 << 1,
66 + NETDATA_V4_16 = 1 << 2,
67 + NETDATA_V4_18 = 1 << 3,
68 + NETDATA_V5_4 = 1 << 4,
69 + NETDATA_V5_10 = 1 << 5,
70 + NETDATA_V5_11 = 1 << 6,
71 + NETDATA_V5_15 = 1 << 7
72 +};
73 +
74 +enum netdata_kernel_idx {
75 + NETDATA_IDX_V3_10,
76 + NETDATA_IDX_V4_14,
77 + NETDATA_IDX_V4_16,
78 + NETDATA_IDX_V4_18,
79 + NETDATA_IDX_V5_4 ,
80 + NETDATA_IDX_V5_10,
81 + NETDATA_IDX_V5_11,
82 + NETDATA_IDX_V5_15
83 +};
84 +
85 +#define NETDATA_IDX_STR_V3_10 "3.10"
86 +#define NETDATA_IDX_STR_V4_14 "4.14"
87 +#define NETDATA_IDX_STR_V4_16 "4.16"
88 +#define NETDATA_IDX_STR_V4_18 "4.18"
89 +#define NETDATA_IDX_STR_V5_4 "5.4"
90 +#define NETDATA_IDX_STR_V5_10 "5.10"
91 +#define NETDATA_IDX_STR_V5_11 "5.11"
92 +#define NETDATA_IDX_STR_V5_15 "5.15"
93
94 /**
91 - * Kernel 4.11
92 - *
93 - * 264960 = 4*65536 + 15*256
95 + * Minimum value has relationship with libbpf support.
96 */
95 -#define NETDATA_EBPF_KERNEL_4_11 264960
97 +#define NETDATA_MINIMUM_EBPF_KERNEL NETDATA_EBPF_KERNEL_4_11
98
99 #define VERSION_STRING_LEN 256
100 #define EBPF_KERNEL_REJECT_LIST_FILE "ebpf_kernel_reject_list.txt"
@@ -155,6 +157,39 @@ typedef struct ebpf_specify_name {
157 bool retprobe;
158 } ebpf_specify_name_t;
159
160 +typedef enum netdata_ebpf_load_mode {
161 + EBPF_LOAD_LEGACY, // Select legacy mode, this means we will load binaries
162 + EBPF_LOAD_CORE, // When CO-RE is used, it is necessary to use the souce code
163 +
164 + EBPF_LOAD_PLAY_DICE // Take a look on environment and choose the best option
165 +} netdata_ebpf_load_mode_t;
166 +
167 +typedef enum netdata_ebpf_program_loaded {
168 + EBPF_LOAD_PROBE, // Attach probes on targets
169 + EBPF_LOAD_RETPROBE, // Attach retprobes on targets
170 + EBPF_LOAD_TRACEPOINT, // This stores log given description about the errors raised
171 + EBPF_LOAD_TRAMPOLINE, // This attaches kprobe when the function is called
172 +} netdata_ebpf_program_loaded_t;
173 +
174 +typedef struct netdata_ebpf_targets {
175 + char *name;
176 + netdata_ebpf_program_loaded_t mode;
177 +} netdata_ebpf_targets_t;
178 +
179 +typedef struct ebpf_plugin_stats {
180 + // Load options
181 + uint32_t legacy; // Legacy codes
182 + uint32_t core; // CO-RE codes, this means we are using source code compiled.
183 +
184 + uint32_t threads; // Total number of threads
185 + uint32_t running; // total number of threads running
186 +
187 + uint32_t probes; // Number of kprobes loaded
188 + uint32_t retprobes; // Number of kretprobes loaded
189 + uint32_t tracepoints; // Number of tracepoints used
190 + uint32_t trampolines; // Number of trampolines used
191 +} ebpf_plugin_stats_t;
192 +
193 typedef struct ebpf_module {
194 const char *thread_name;
195 const char *config_name;
@@ -173,17 +208,17 @@ typedef struct ebpf_module {
208 uint32_t pid_map_size;
209 struct config *cfg;
210 const char *config_file;
211 + uint64_t kernels;
212 + netdata_ebpf_load_mode_t load;
213 + netdata_ebpf_targets_t *targets;
214 } ebpf_module_t;
215
216 extern int ebpf_get_kernel_version();
217 extern int get_redhat_release();
218 extern int has_condition_to_run(int version);
219 extern char *ebpf_kernel_suffix(int version, int isrh);
182 -extern void ebpf_update_kernel(char *ks, size_t length, int isrh, int version);
183 -extern struct bpf_link **ebpf_load_program(char *plugins_dir,
184 - ebpf_module_t *em,
185 - char *kernel_string,
186 - struct bpf_object **obj);
220 +extern struct bpf_link **ebpf_load_program(char *plugins_dir, ebpf_module_t *em, int kver, int is_rhf,
221 + struct bpf_object **obj);
222
223 extern void ebpf_mount_config_name(char *filename, size_t length, char *path, const char *config);
224 extern int ebpf_load_config(struct config *config, char *filename);
@@ -193,6 +228,7 @@ extern char *ebpf_find_symbol(char *search);
228 extern void ebpf_load_addresses(ebpf_addresses_t *fa, int fd);
229 extern void ebpf_fill_algorithms(int *algorithms, size_t length, int algorithm);
230 extern char **ebpf_fill_histogram_dimension(size_t maximum);
231 +extern void ebpf_update_stats(ebpf_plugin_stats_t *report, ebpf_module_t *em);
232
233 // Histogram
234 #define NETDATA_EBPF_HIST_MAX_BINS 24UL
web/gui/dashboard_info.js
+8
@@ -3594,6 +3594,14 @@ netdataDashboard.context = {
3594 info: 'The netdata API response time measures the time netdata needed to serve requests. This time includes everything, from the reception of the first byte of a request, to the dispatch of the last byte of its reply, therefore it includes all network latencies involved (i.e. a client over a slow network will influence these metrics).'
3595 },
3596
3597 + 'netdata.ebpf_threads': {
3598 + info: 'Show total number of threads and number of active threads. For more details about the threads, see the <a href="https://learn.netdata.cloud/docs/agent/collectors/ebpf.plugin#ebpf-programs">official documentation</a>.'
3599 + },
3600 +
3601 + 'netdata.ebpf_load_methods': {
3602 + info: 'Show number of threads loaded using legacy code (independent binary) or <code>CO-RE (Compile Once Run Everywhere)</code>.'
3603 + },
3604 +
3605 // ------------------------------------------------------------------------
3606 // RETROSHARE
3607