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