summaryrefslogtreecommitdiffstats
path: root/src/collectors/ebpf.plugin/ebpf.c
diff options
context:
space:
mode:
authorvkalintiris <vasilis@netdata.cloud>2024-02-08 11:06:35 +0200
committerGitHub <noreply@github.com>2024-02-08 11:06:35 +0200
commite0ec10411bcfaeeaba331a93d5f3d96e23fa72e5 (patch)
treeb371cfb03d8f276e8c64cfd042648053abfbd0a2 /src/collectors/ebpf.plugin/ebpf.c
parente9760b43f53442d9dbd22f5353872ae5e83f7c4c (diff)
Move collectors/ under src/ (#16965)
Diffstat (limited to 'src/collectors/ebpf.plugin/ebpf.c')
-rw-r--r--src/collectors/ebpf.plugin/ebpf.c4110
1 files changed, 4110 insertions, 0 deletions
diff --git a/src/collectors/ebpf.plugin/ebpf.c b/src/collectors/ebpf.plugin/ebpf.c
new file mode 100644
index 0000000000..c46688895f
--- /dev/null
+++ b/src/collectors/ebpf.plugin/ebpf.c
@@ -0,0 +1,4110 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <ifaddrs.h>
+
+#include "ebpf.h"
+#include "ebpf_socket.h"
+#include "ebpf_unittest.h"
+#include "libnetdata/required_dummies.h"
+
+/*****************************************************************
+ *
+ * GLOBAL VARIABLES
+ *
+ *****************************************************************/
+
+char *ebpf_plugin_dir = PLUGINS_DIR;
+static char *ebpf_configured_log_dir = LOG_DIR;
+
+char *ebpf_algorithms[] = {"absolute", "incremental"};
+struct config collector_config = { .first_section = NULL,
+ .last_section = NULL,
+ .mutex = NETDATA_MUTEX_INITIALIZER,
+ .index = { .avl_tree = { .root = NULL, .compar = appconfig_section_compare },
+ .rwlock = AVL_LOCK_INITIALIZER } };
+
+int running_on_kernel = 0;
+int ebpf_nprocs;
+int isrh = 0;
+int main_thread_id = 0;
+int process_pid_fd = -1;
+static size_t global_iterations_counter = 1;
+bool publish_internal_metrics = true;
+
+pthread_mutex_t lock;
+pthread_mutex_t ebpf_exit_cleanup;
+pthread_mutex_t collect_data_mutex;
+
+struct netdata_static_thread cgroup_integration_thread = {
+ .name = "EBPF CGROUP INT",
+ .config_section = NULL,
+ .config_name = NULL,
+ .env_name = NULL,
+ .enabled = 1,
+ .thread = NULL,
+ .init_routine = NULL,
+ .start_routine = NULL
+};
+
+ebpf_module_t ebpf_modules[] = {
+ { .info = {.thread_name = "process",
+ .config_name = "process",
+ .thread_description = NETDATA_EBPF_MODULE_PROCESS_DESC},
+ .functions = {.start_routine = ebpf_process_thread,
+ .apps_routine = ebpf_process_create_apps_charts,
+ .fnct_routine = NULL},
+ .enabled = NETDATA_THREAD_EBPF_NOT_RUNNING,
+ .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO,
+ .apps_level = NETDATA_APPS_LEVEL_REAL_PARENT, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
+ .maps = NULL, .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &process_config,
+ .config_file = NETDATA_PROCESS_CONFIG_FILE,
+ .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4 | NETDATA_V5_10 |
+ NETDATA_V5_14,
+ .load = EBPF_LOAD_LEGACY, .targets = NULL, .probe_links = NULL, .objects = NULL,
+ .thread = NULL, .maps_per_core = CONFIG_BOOLEAN_YES, .lifetime = EBPF_DEFAULT_LIFETIME, .running_time = 0 },
+ { .info = {.thread_name = "socket",
+ .config_name = "socket",
+ .thread_description = NETDATA_EBPF_SOCKET_MODULE_DESC},
+ .functions = {.start_routine = ebpf_socket_thread,
+ .apps_routine = ebpf_socket_create_apps_charts,
+ .fnct_routine = ebpf_socket_read_open_connections,
+ .fcnt_name = EBPF_FUNCTION_SOCKET,
+ .fcnt_desc = EBPF_PLUGIN_SOCKET_FUNCTION_DESCRIPTION,
+ .fcnt_thread_chart_name = NULL,
+ .fcnt_thread_lifetime_name = NULL},
+ .enabled = NETDATA_THREAD_EBPF_NOT_RUNNING,
+ .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO,
+ .apps_level = NETDATA_APPS_LEVEL_REAL_PARENT, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
+ .maps = NULL,
+ .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &socket_config,
+ .config_file = NETDATA_NETWORK_CONFIG_FILE,
+ .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4 | NETDATA_V5_14,
+ .load = EBPF_LOAD_LEGACY, .targets = socket_targets, .probe_links = NULL, .objects = NULL,
+ .thread = NULL, .maps_per_core = CONFIG_BOOLEAN_YES, .lifetime = EBPF_DEFAULT_LIFETIME, .running_time = 0},
+ { .info = {.thread_name = "cachestat", .config_name = "cachestat", .thread_description = NETDATA_EBPF_CACHESTAT_MODULE_DESC},
+ .functions = {.start_routine = ebpf_cachestat_thread,
+ .apps_routine = ebpf_cachestat_create_apps_charts,
+ .fnct_routine = NULL},
+ .enabled = NETDATA_THREAD_EBPF_NOT_RUNNING,
+ .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO,
+ .apps_level = NETDATA_APPS_LEVEL_REAL_PARENT, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
+ .maps = cachestat_maps, .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &cachestat_config,
+ .config_file = NETDATA_CACHESTAT_CONFIG_FILE,
+ .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18|
+ NETDATA_V5_4 | NETDATA_V5_14 | NETDATA_V5_15 | NETDATA_V5_16,
+ .load = EBPF_LOAD_LEGACY, .targets = cachestat_targets, .probe_links = NULL, .objects = NULL,
+ .thread = NULL, .maps_per_core = CONFIG_BOOLEAN_YES, .lifetime = EBPF_DEFAULT_LIFETIME, .running_time = 0},
+ { .info = {.thread_name = "sync",
+ .config_name = "sync",
+ .thread_description = NETDATA_EBPF_SYNC_MODULE_DESC},
+ .functions = {.start_routine = ebpf_sync_thread,
+ .apps_routine = NULL,
+ .fnct_routine = NULL},
+ .enabled = NETDATA_THREAD_EBPF_NOT_RUNNING, .maps = NULL,
+ .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO,
+ .apps_level = NETDATA_APPS_NOT_SET, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
+ .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &sync_config,
+ .config_file = NETDATA_SYNC_CONFIG_FILE,
+ // All syscalls have the same kernels
+ .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4 | NETDATA_V5_14,
+ .load = EBPF_LOAD_LEGACY, .targets = sync_targets, .probe_links = NULL, .objects = NULL,
+ .thread = NULL, .maps_per_core = CONFIG_BOOLEAN_YES, .lifetime = EBPF_DEFAULT_LIFETIME, .running_time = 0},
+ { .info = {.thread_name = "dc",
+ .config_name = "dc",
+ .thread_description = NETDATA_EBPF_DC_MODULE_DESC},
+ .functions = {.start_routine = ebpf_dcstat_thread,
+ .apps_routine = ebpf_dcstat_create_apps_charts,
+ .fnct_routine = NULL},
+ .enabled = NETDATA_THREAD_EBPF_NOT_RUNNING,
+ .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO,
+ .apps_level = NETDATA_APPS_LEVEL_REAL_PARENT, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
+ .maps = dcstat_maps,
+ .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &dcstat_config,
+ .config_file = NETDATA_DIRECTORY_DCSTAT_CONFIG_FILE,
+ .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4 | NETDATA_V5_14,
+ .load = EBPF_LOAD_LEGACY, .targets = dc_targets, .probe_links = NULL, .objects = NULL,
+ .thread = NULL, .maps_per_core = CONFIG_BOOLEAN_YES, .lifetime = EBPF_DEFAULT_LIFETIME, .running_time = 0},
+ { .info = {.thread_name = "swap", .config_name = "swap", .thread_description = NETDATA_EBPF_SWAP_MODULE_DESC},
+ .functions = {.start_routine = ebpf_swap_thread,
+ .apps_routine = ebpf_swap_create_apps_charts,
+ .fnct_routine = NULL},
+ .enabled = NETDATA_THREAD_EBPF_NOT_RUNNING,
+ .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO,
+ .apps_level = NETDATA_APPS_LEVEL_REAL_PARENT, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
+ .maps = NULL,
+ .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &swap_config,
+ .config_file = NETDATA_DIRECTORY_SWAP_CONFIG_FILE,
+ .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4 | NETDATA_V5_14,
+ .load = EBPF_LOAD_LEGACY, .targets = swap_targets, .probe_links = NULL, .objects = NULL,
+ .thread = NULL, .maps_per_core = CONFIG_BOOLEAN_YES, .lifetime = EBPF_DEFAULT_LIFETIME, .running_time = 0},
+ { .info = {.thread_name = "vfs",
+ .config_name = "vfs",
+ .thread_description = NETDATA_EBPF_VFS_MODULE_DESC},
+ .functions = {.start_routine = ebpf_vfs_thread,
+ .apps_routine = ebpf_vfs_create_apps_charts,
+ .fnct_routine = NULL},
+ .enabled = NETDATA_THREAD_EBPF_NOT_RUNNING,
+ .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO,
+ .apps_level = NETDATA_APPS_LEVEL_REAL_PARENT, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
+ .maps = NULL,
+ .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &vfs_config,
+ .config_file = NETDATA_DIRECTORY_VFS_CONFIG_FILE,
+ .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4 | NETDATA_V5_14,
+ .load = EBPF_LOAD_LEGACY, .targets = vfs_targets, .probe_links = NULL, .objects = NULL,
+ .thread = NULL, .maps_per_core = CONFIG_BOOLEAN_YES, .lifetime = EBPF_DEFAULT_LIFETIME, .running_time = 0},
+ { .info = {.thread_name = "filesystem", .config_name = "filesystem", .thread_description = NETDATA_EBPF_FS_MODULE_DESC},
+ .functions = {.start_routine = ebpf_filesystem_thread,
+ .apps_routine = NULL,
+ .fnct_routine = NULL},
+ .enabled = NETDATA_THREAD_EBPF_NOT_RUNNING,
+ .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO,
+ .apps_level = NETDATA_APPS_NOT_SET, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
+ .maps = NULL, .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &fs_config,
+ .config_file = NETDATA_FILESYSTEM_CONFIG_FILE,
+ //We are setting kernels as zero, because we load eBPF programs according the kernel running.
+ .kernels = 0, .load = EBPF_LOAD_LEGACY, .targets = NULL, .probe_links = NULL, .objects = NULL,
+ .thread = NULL, .maps_per_core = CONFIG_BOOLEAN_YES, .lifetime = EBPF_DEFAULT_LIFETIME, .running_time = 0},
+ { .info = {.thread_name = "disk",
+ .config_name = "disk",
+ .thread_description = NETDATA_EBPF_DISK_MODULE_DESC},
+ .functions = {.start_routine = ebpf_disk_thread,
+ .apps_routine = NULL,
+ .fnct_routine = NULL},
+ .enabled = NETDATA_THREAD_EBPF_NOT_RUNNING,
+ .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO,
+ .apps_level = NETDATA_APPS_NOT_SET, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
+ .maps = NULL, .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &disk_config,
+ .config_file = NETDATA_DISK_CONFIG_FILE,
+ .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4 | NETDATA_V5_14,
+ .load = EBPF_LOAD_LEGACY, .targets = NULL, .probe_links = NULL, .objects = NULL,
+ .thread = NULL, .maps_per_core = CONFIG_BOOLEAN_YES, .lifetime = EBPF_DEFAULT_LIFETIME, .running_time = 0},
+ { .info = {.thread_name = "mount",
+ .config_name = "mount",
+ .thread_description = NETDATA_EBPF_MOUNT_MODULE_DESC},
+ .functions = {.start_routine = ebpf_mount_thread,
+ .apps_routine = NULL,
+ .fnct_routine = NULL},
+ .enabled = NETDATA_THREAD_EBPF_NOT_RUNNING,
+ .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO,
+ .apps_level = NETDATA_APPS_NOT_SET, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
+ .maps = NULL, .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &mount_config,
+ .config_file = NETDATA_MOUNT_CONFIG_FILE,
+ .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4 | NETDATA_V5_14,
+ .load = EBPF_LOAD_LEGACY, .targets = mount_targets, .probe_links = NULL, .objects = NULL,
+ .thread = NULL, .maps_per_core = CONFIG_BOOLEAN_YES, .lifetime = EBPF_DEFAULT_LIFETIME, .running_time = 0},
+ { .info = { .thread_name = "fd",
+ .config_name = "fd",
+ .thread_description = NETDATA_EBPF_FD_MODULE_DESC},
+ .functions = {.start_routine = ebpf_fd_thread,
+ .apps_routine = ebpf_fd_create_apps_charts,
+ .fnct_routine = NULL},
+ .enabled = NETDATA_THREAD_EBPF_NOT_RUNNING,
+ .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO,
+ .apps_level = NETDATA_APPS_LEVEL_REAL_PARENT, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
+ .maps = NULL,
+ .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &fd_config,
+ .config_file = NETDATA_FD_CONFIG_FILE,
+ .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4 | NETDATA_V5_11 |
+ NETDATA_V5_14,
+ .load = EBPF_LOAD_LEGACY, .targets = fd_targets, .probe_links = NULL, .objects = NULL,
+ .thread = NULL, .maps_per_core = CONFIG_BOOLEAN_YES, .lifetime = EBPF_DEFAULT_LIFETIME, .running_time = 0},
+ { .info = { .thread_name = "hardirq",
+ .config_name = "hardirq",
+ .thread_description = NETDATA_EBPF_HARDIRQ_MODULE_DESC},
+ .functions = {.start_routine = ebpf_hardirq_thread,
+ .apps_routine = NULL,
+ .fnct_routine = NULL},
+ .enabled = NETDATA_THREAD_EBPF_NOT_RUNNING,
+ .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO,
+ .apps_level = NETDATA_APPS_NOT_SET, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
+ .maps = NULL, .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &hardirq_config,
+ .config_file = NETDATA_HARDIRQ_CONFIG_FILE,
+ .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4 | NETDATA_V5_14,
+ .load = EBPF_LOAD_LEGACY, .targets = NULL, .probe_links = NULL, .objects = NULL,
+ .thread = NULL, .maps_per_core = CONFIG_BOOLEAN_YES, .lifetime = EBPF_DEFAULT_LIFETIME, .running_time = 0},
+ { .info = { .thread_name = "softirq",
+ .config_name = "softirq",
+ .thread_description = NETDATA_EBPF_SOFTIRQ_MODULE_DESC},
+ .functions = {.start_routine = ebpf_softirq_thread,
+ .apps_routine = NULL,
+ .fnct_routine = NULL },
+ .enabled = NETDATA_THREAD_EBPF_NOT_RUNNING,
+ .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO,
+ .apps_level = NETDATA_APPS_NOT_SET, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
+ .maps = NULL, .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &softirq_config,
+ .config_file = NETDATA_SOFTIRQ_CONFIG_FILE,
+ .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4 | NETDATA_V5_14,
+ .load = EBPF_LOAD_LEGACY, .targets = NULL, .probe_links = NULL, .objects = NULL,
+ .thread = NULL, .maps_per_core = CONFIG_BOOLEAN_YES, .lifetime = EBPF_DEFAULT_LIFETIME, .running_time = 0},
+ { .info = {.thread_name = "oomkill",
+ .config_name = "oomkill",
+ .thread_description = NETDATA_EBPF_OOMKILL_MODULE_DESC},
+ .functions = {.start_routine = ebpf_oomkill_thread,
+ .apps_routine = ebpf_oomkill_create_apps_charts,
+ .fnct_routine = NULL},.enabled = NETDATA_THREAD_EBPF_NOT_RUNNING,
+ .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO,
+ .apps_level = NETDATA_APPS_LEVEL_REAL_PARENT, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
+ .maps = NULL,
+ .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &oomkill_config,
+ .config_file = NETDATA_OOMKILL_CONFIG_FILE,
+ .kernels = NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4 | NETDATA_V5_14,
+ .load = EBPF_LOAD_LEGACY, .targets = NULL, .probe_links = NULL, .objects = NULL,
+ .thread = NULL, .maps_per_core = CONFIG_BOOLEAN_YES, .lifetime = EBPF_DEFAULT_LIFETIME, .running_time = 0},
+ { .info = {.thread_name = "shm",
+ .config_name = "shm",
+ .thread_description = NETDATA_EBPF_SHM_MODULE_DESC},
+ .functions = {.start_routine = ebpf_shm_thread,
+ .apps_routine = ebpf_shm_create_apps_charts,
+ .fnct_routine = NULL},
+ .enabled = NETDATA_THREAD_EBPF_NOT_RUNNING,
+ .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO,
+ .apps_level = NETDATA_APPS_LEVEL_REAL_PARENT, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
+ .maps = NULL,
+ .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &shm_config,
+ .config_file = NETDATA_DIRECTORY_SHM_CONFIG_FILE,
+ .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4 | NETDATA_V5_14,
+ .load = EBPF_LOAD_LEGACY, .targets = shm_targets, .probe_links = NULL, .objects = NULL,
+ .thread = NULL, .maps_per_core = CONFIG_BOOLEAN_YES, .lifetime = EBPF_DEFAULT_LIFETIME, .running_time = 0},
+ { .info = { .thread_name = "mdflush",
+ .config_name = "mdflush",
+ .thread_description = NETDATA_EBPF_MD_MODULE_DESC},
+ .functions = {.start_routine = ebpf_mdflush_thread,
+ .apps_routine = NULL,
+ .fnct_routine = NULL},
+ .enabled = NETDATA_THREAD_EBPF_NOT_RUNNING,
+ .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO,
+ .apps_level = NETDATA_APPS_NOT_SET, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
+ .maps = NULL, .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &mdflush_config,
+ .config_file = NETDATA_DIRECTORY_MDFLUSH_CONFIG_FILE,
+ .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4 | NETDATA_V5_14,
+ .load = EBPF_LOAD_LEGACY, .targets = mdflush_targets, .probe_links = NULL, .objects = NULL,
+ .thread = NULL, .maps_per_core = CONFIG_BOOLEAN_YES, .lifetime = EBPF_DEFAULT_LIFETIME, .running_time = 0},
+ { .info = { .thread_name = "functions",
+ .config_name = "functions",
+ .thread_description = NETDATA_EBPF_FUNCTIONS_MODULE_DESC},
+ .functions = {.start_routine = ebpf_function_thread,
+ .apps_routine = NULL,
+ .fnct_routine = NULL},
+ .enabled = NETDATA_THREAD_EBPF_RUNNING,
+ .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO,
+ .apps_level = NETDATA_APPS_NOT_SET, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
+ .maps = NULL, .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = NULL,
+ .config_file = NETDATA_DIRECTORY_FUNCTIONS_CONFIG_FILE,
+ .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4 | NETDATA_V5_14,
+ .load = EBPF_LOAD_LEGACY, .targets = NULL, .probe_links = NULL, .objects = NULL,
+ .thread = NULL, .maps_per_core = CONFIG_BOOLEAN_YES, .lifetime = EBPF_DEFAULT_LIFETIME, .running_time = 0},
+ { .info = {.thread_name = NULL, .config_name = NULL},
+ .functions = {.start_routine = NULL, .apps_routine = NULL, .fnct_routine = NULL},
+ .enabled = NETDATA_THREAD_EBPF_NOT_RUNNING, .update_every = EBPF_DEFAULT_UPDATE_EVERY,
+ .global_charts = 0, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO, .apps_level = NETDATA_APPS_NOT_SET,
+ .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0, .maps = NULL,
+ .pid_map_size = 0, .names = NULL, .cfg = NULL, .kernels = 0, .load = EBPF_LOAD_LEGACY,
+ .targets = NULL, .probe_links = NULL, .objects = NULL, .thread = NULL, .maps_per_core = CONFIG_BOOLEAN_YES},
+};
+
+struct netdata_static_thread ebpf_threads[] = {
+ {
+ .name = "EBPF PROCESS",
+ .config_section = NULL,
+ .config_name = NULL,
+ .env_name = NULL,
+ .enabled = 1,
+ .thread = NULL,
+ .init_routine = NULL,
+ .start_routine = NULL
+ },
+ {
+ .name = "EBPF SOCKET",
+ .config_section = NULL,
+ .config_name = NULL,
+ .env_name = NULL,
+ .enabled = 1,
+ .thread = NULL,
+ .init_routine = NULL,
+ .start_routine = NULL
+ },
+ {
+ .name = "EBPF CACHESTAT",
+ .config_section = NULL,
+ .config_name = NULL,
+ .env_name = NULL,
+ .enabled = 1,
+ .thread = NULL,
+ .init_routine = NULL,
+ .start_routine = NULL
+ },
+ {
+ .name = "EBPF SYNC",
+ .config_section = NULL,
+ .config_name = NULL,
+ .env_name = NULL,
+ .enabled = 1,
+ .thread = NULL,
+ .init_routine = NULL,
+ .start_routine = NULL
+ },
+ {
+ .name = "EBPF DCSTAT",
+ .config_section = NULL,
+ .config_name = NULL,
+ .env_name = NULL,
+ .enabled = 1,
+ .thread = NULL,
+ .init_routine = NULL,
+ .start_routine = NULL
+ },
+ {
+ .name = "EBPF SWAP",
+ .config_section = NULL,
+ .config_name = NULL,
+ .env_name = NULL,
+ .enabled = 1,
+ .thread = NULL,
+ .init_routine = NULL,
+ .start_routine = NULL
+ },
+ {
+ .name = "EBPF VFS",
+ .config_section = NULL,
+ .config_name = NULL,
+ .env_name = NULL,
+ .enabled = 1,
+ .thread = NULL,
+ .init_routine = NULL,
+ .start_routine = NULL
+ },
+ {
+ .name = "EBPF FILESYSTEM",
+ .config_section = NULL,
+ .config_name = NULL,
+ .env_name = NULL,
+ .enabled = 1,
+ .thread = NULL,
+ .init_routine = NULL,
+ .start_routine = NULL
+ },
+ {
+ .name = "EBPF DISK",
+ .config_section = NULL,
+ .config_name = NULL,
+ .env_name = NULL,
+ .enabled = 1,
+ .thread = NULL,
+ .init_routine = NULL,
+ .start_routine = NULL
+ },
+ {
+ .name = "EBPF MOUNT",
+ .config_section = NULL,
+ .config_name = NULL,
+ .env_name = NULL,
+ .enabled = 1,
+ .thread = NULL,
+ .init_routine = NULL,
+ .start_routine = NULL
+ },
+ {
+ .name = "EBPF FD",
+ .config_section = NULL,
+ .config_name = NULL,
+ .env_name = NULL,
+ .enabled = 1,
+ .thread = NULL,
+ .init_routine = NULL,
+ .start_routine = NULL
+ },
+ {
+ .name = "EBPF HARDIRQ",
+ .config_section = NULL,
+ .config_name = NULL,
+ .env_name = NULL,
+ .enabled = 1,
+ .thread = NULL,
+ .init_routine = NULL,
+ .start_routine = NULL
+ },
+ {
+ .name = "EBPF SOFTIRQ",
+ .config_section = NULL,
+ .config_name = NULL,
+ .env_name = NULL,
+ .enabled = 1,
+ .thread = NULL,
+ .init_routine = NULL,
+ .start_routine = NULL
+ },
+ {
+ .name = "EBPF OOMKILL",
+ .config_section = NULL,
+ .config_name = NULL,
+ .env_name = NULL,
+ .enabled = 1,
+ .thread = NULL,
+ .init_routine = NULL,
+ .start_routine = NULL
+ },
+ {
+ .name = "EBPF SHM",
+ .config_section = NULL,
+ .config_name = NULL,
+ .env_name = NULL,
+ .enabled = 1,
+ .thread = NULL,
+ .init_routine = NULL,
+ .start_routine = NULL
+ },
+ {
+ .name = "EBPF MDFLUSH",
+ .config_section = NULL,
+ .config_name = NULL,
+ .env_name = NULL,
+ .enabled = 1,
+ .thread = NULL,
+ .init_routine = NULL,
+ .start_routine = NULL
+ },
+ {
+ .name = "EBPF FUNCTIONS",
+ .config_section = NULL,
+ .config_name = NULL,
+ .env_name = NULL,
+#ifdef NETDATA_DEV_MODE
+ .enabled = 1,
+#else
+ .enabled = 0,
+#endif
+ .thread = NULL,
+ .init_routine = NULL,
+ .start_routine = NULL
+ },
+ {
+ .name = NULL,
+ .config_section = NULL,
+ .config_name = NULL,
+ .env_name = NULL,
+ .enabled = 0,
+ .thread = NULL,
+ .init_routine = NULL,
+ .start_routine = NULL
+ },
+};
+
+ebpf_filesystem_partitions_t localfs[] =
+ {{.filesystem = "ext4",
+ .optional_filesystem = NULL,
+ .family = "ext4",
+ .objects = NULL,
+ .probe_links = NULL,
+ .flags = NETDATA_FILESYSTEM_FLAG_NO_PARTITION,
+ .enabled = CONFIG_BOOLEAN_YES,
+ .addresses = {.function = NULL, .addr = 0},
+ .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4,
+ .fs_maps = NULL,
+ .fs_obj = NULL,
+ .functions = { "ext4_file_read_iter",
+ "ext4_file_write_iter",
+ "ext4_file_open",
+ "ext4_sync_file",
+ NULL }},
+ {.filesystem = "xfs",
+ .optional_filesystem = NULL,
+ .family = "xfs",
+ .objects = NULL,
+ .probe_links = NULL,
+ .flags = NETDATA_FILESYSTEM_FLAG_NO_PARTITION,
+ .enabled = CONFIG_BOOLEAN_YES,
+ .addresses = {.function = NULL, .addr = 0},
+ .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4,
+ .fs_maps = NULL,
+ .fs_obj = NULL,
+ .functions = { "xfs_file_read_iter",
+ "xfs_file_write_iter",
+ "xfs_file_open",
+ "xfs_file_fsync",
+ NULL }},
+ {.filesystem = "nfs",
+ .optional_filesystem = "nfs4",
+ .family = "nfs",
+ .objects = NULL,
+ .probe_links = NULL,
+ .flags = NETDATA_FILESYSTEM_ATTR_CHARTS,
+ .enabled = CONFIG_BOOLEAN_YES,
+ .addresses = {.function = NULL, .addr = 0},
+ .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4,
+ .fs_maps = NULL,
+ .fs_obj = NULL,
+ .functions = { "nfs_file_read",
+ "nfs_file_write",
+ "nfs_open",
+ "nfs_getattr",
+ NULL }}, // // "nfs4_file_open" - not present on all kernels
+ {.filesystem = "zfs",
+ .optional_filesystem = NULL,
+ .family = "zfs",
+ .objects = NULL,
+ .probe_links = NULL,
+ .flags = NETDATA_FILESYSTEM_FLAG_NO_PARTITION,
+ .enabled = CONFIG_BOOLEAN_YES,
+ .addresses = {.function = NULL, .addr = 0},
+ .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4,
+ .fs_maps = NULL,
+ .fs_obj = NULL,
+ .functions = { "zpl_iter_read",
+ "zpl_iter_write",
+ "zpl_open",
+ "zpl_fsync",
+ NULL }},
+ {.filesystem = "btrfs",
+ .optional_filesystem = NULL,
+ .family = "btrfs",
+ .objects = NULL,
+ .probe_links = NULL,
+ .flags = NETDATA_FILESYSTEM_FILL_ADDRESS_TABLE,
+ .enabled = CONFIG_BOOLEAN_YES,
+ .addresses = {.function = "btrfs_file_operations", .addr = 0},
+ .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4 | NETDATA_V5_10,
+ .fs_maps = NULL,
+ .fs_obj = NULL,
+ .functions = { "btrfs_file_read_iter",
+ "btrfs_file_write_iter",
+ "btrfs_file_open",
+ "btrfs_sync_file",
+ NULL }},
+ {.filesystem = NULL,
+ .optional_filesystem = NULL,
+ .family = NULL,
+ .objects = NULL,
+ .probe_links = NULL,
+ .flags = NETDATA_FILESYSTEM_FLAG_NO_PARTITION,
+ .enabled = CONFIG_BOOLEAN_YES,
+ .addresses = {.function = NULL, .addr = 0},
+ .kernels = 0, .fs_maps = NULL, .fs_obj = NULL}};
+
+ebpf_sync_syscalls_t local_syscalls[] = {
+ {.syscall = NETDATA_SYSCALLS_SYNC, .enabled = CONFIG_BOOLEAN_YES, .objects = NULL, .probe_links = NULL,
+#ifdef LIBBPF_MAJOR_VERSION
+ .sync_obj = NULL,
+#endif
+ .sync_maps = NULL
+ },
+ {.syscall = NETDATA_SYSCALLS_SYNCFS, .enabled = CONFIG_BOOLEAN_YES, .objects = NULL, .probe_links = NULL,
+#ifdef LIBBPF_MAJOR_VERSION
+ .sync_obj = NULL,
+#endif
+ .sync_maps = NULL
+ },
+ {.syscall = NETDATA_SYSCALLS_MSYNC, .enabled = CONFIG_BOOLEAN_YES, .objects = NULL, .probe_links = NULL,
+#ifdef LIBBPF_MAJOR_VERSION
+ .sync_obj = NULL,
+#endif
+ .sync_maps = NULL
+ },
+ {.syscall = NETDATA_SYSCALLS_FSYNC, .enabled = CONFIG_BOOLEAN_YES, .objects = NULL, .probe_links = NULL,
+#ifdef LIBBPF_MAJOR_VERSION
+ .sync_obj = NULL,
+#endif
+ .sync_maps = NULL
+ },
+ {.syscall = NETDATA_SYSCALLS_FDATASYNC, .enabled = CONFIG_BOOLEAN_YES, .objects = NULL, .probe_links = NULL,
+#ifdef LIBBPF_MAJOR_VERSION
+ .sync_obj = NULL,
+#endif
+ .sync_maps = NULL
+ },
+ {.syscall = NETDATA_SYSCALLS_SYNC_FILE_RANGE, .enabled = CONFIG_BOOLEAN_YES, .objects = NULL, .probe_links = NULL,
+#ifdef LIBBPF_MAJOR_VERSION
+ .sync_obj = NULL,
+#endif
+ .sync_maps = NULL
+ },
+ {.syscall = NULL, .enabled = CONFIG_BOOLEAN_NO, .objects = NULL, .probe_links = NULL,
+#ifdef LIBBPF_MAJOR_VERSION
+ .sync_obj = NULL,
+#endif
+ .sync_maps = NULL
+ }
+};
+
+
+// Link with cgroup.plugin
+netdata_ebpf_cgroup_shm_t shm_ebpf_cgroup = {NULL, NULL};
+int shm_fd_ebpf_cgroup = -1;
+sem_t *shm_sem_ebpf_cgroup = SEM_FAILED;
+pthread_mutex_t mutex_cgroup_shm;
+
+//Network viewer
+ebpf_network_viewer_options_t network_viewer_opt;
+
+// Statistic
+ebpf_plugin_stats_t plugin_statistics = {.core = 0, .legacy = 0, .running = 0, .threads = 0, .tracepoints = 0,
+ .probes = 0, .retprobes = 0, .trampolines = 0, .memlock_kern = 0,
+ .hash_tables = 0};
+netdata_ebpf_judy_pid_t ebpf_judy_pid = {.pid_table = NULL, .index = {.JudyLArray = NULL}};
+bool ebpf_plugin_exit = false;
+
+#ifdef LIBBPF_MAJOR_VERSION
+struct btf *default_btf = NULL;
+struct cachestat_bpf *cachestat_bpf_obj = NULL;
+struct dc_bpf *dc_bpf_obj = NULL;
+struct disk_bpf *disk_bpf_obj = NULL;
+struct fd_bpf *fd_bpf_obj = NULL;
+struct hardirq_bpf *hardirq_bpf_obj = NULL;
+struct mdflush_bpf *mdflush_bpf_obj = NULL;
+struct mount_bpf *mount_bpf_obj = NULL;
+struct shm_bpf *shm_bpf_obj = NULL;
+struct socket_bpf *socket_bpf_obj = NULL;
+struct swap_bpf *bpf_obj = NULL;
+struct vfs_bpf *vfs_bpf_obj = NULL;
+#else
+void *default_btf = NULL;
+#endif
+char *btf_path = NULL;
+
+/*****************************************************************
+ *
+ * FUNCTIONS USED TO MANIPULATE JUDY ARRAY
+ *
+ *****************************************************************/
+
+/**
+ * Hashtable insert unsafe
+ *
+ * Find or create a value associated to the index
+ *
+ * @return The lsocket = 0 when new item added to the array otherwise the existing item value is returned in *lsocket
+ * we return a pointer to a pointer, so that the caller can put anything needed at the value of the index.
+ * The pointer to pointer we return has to be used before any other operation that may change the index (insert/delete).
+ *
+ */
+void **ebpf_judy_insert_unsafe(PPvoid_t arr, Word_t key)
+{
+ JError_t J_Error;
+ Pvoid_t *idx = JudyLIns(arr, key, &J_Error);
+ if (unlikely(idx == PJERR)) {
+ netdata_log_error("Cannot add PID to JudyL, JU_ERRNO_* == %u, ID == %d",
+ JU_ERRNO(&J_Error), JU_ERRID(&J_Error));
+ }
+
+ return idx;
+}
+
+/**
+ * Get PID from judy
+ *
+ * Get a pointer for the `pid` from judy_array;
+ *
+ * @param judy_array a judy array where PID is the primary key
+ * @param pid pid stored.
+ */
+netdata_ebpf_judy_pid_stats_t *ebpf_get_pid_from_judy_unsafe(PPvoid_t judy_array, uint32_t pid)
+{
+ netdata_ebpf_judy_pid_stats_t **pid_pptr =
+ (netdata_ebpf_judy_pid_stats_t **)ebpf_judy_insert_unsafe(judy_array, pid);
+ netdata_ebpf_judy_pid_stats_t *pid_ptr = *pid_pptr;
+ if (likely(*pid_pptr == NULL)) {
+ // a new PID added to the index
+ *pid_pptr = aral_mallocz(ebpf_judy_pid.pid_table);
+
+ pid_ptr = *pid_pptr;
+
+ pid_ptr->cmdline = NULL;
+ pid_ptr->socket_stats.JudyLArray = NULL;
+ rw_spinlock_init(&pid_ptr->socket_stats.rw_spinlock);
+ }
+
+ return pid_ptr;
+}
+
+/*****************************************************************
+ *
+ * FUNCTIONS USED TO ALLOCATE APPS/CGROUP MEMORIES (ARAL)
+ *
+ *****************************************************************/
+
+/**
+ * Allocate PID ARAL
+ *
+ * Allocate memory using ARAL functions to speed up processing.
+ *
+ * @param name the internal name used for allocated region.
+ * @param size size of each element inside allocated space
+ *
+ * @return It returns the address on success and NULL otherwise.
+ */
+ARAL *ebpf_allocate_pid_aral(char *name, size_t size)
+{
+ static size_t max_elements = NETDATA_EBPF_ALLOC_MAX_PID;
+ if (max_elements < NETDATA_EBPF_ALLOC_MIN_ELEMENTS) {
+ netdata_log_error("Number of elements given is too small, adjusting it for %d", NETDATA_EBPF_ALLOC_MIN_ELEMENTS);
+ max_elements = NETDATA_EBPF_ALLOC_MIN_ELEMENTS;
+ }
+
+ return aral_create(name, size,
+ 0, max_elements,
+ NULL, NULL, NULL, false, false);
+}
+
+/*****************************************************************
+ *
+ * FUNCTIONS USED TO CLEAN MEMORY AND OPERATE SYSTEM FILES
+ *
+ *****************************************************************/
+
+/**
+ * Wait to avoid possible coredumps while process is closing.
+ */
+static inline void ebpf_check_before2go()
+{
+ int i = EBPF_OPTION_ALL_CHARTS;
+ usec_t max = USEC_PER_SEC, step = 200000;
+ while (i && max) {
+ max -= step;
+ sleep_usec(step);
+ i = 0;
+ int j;
+ pthread_mutex_lock(&ebpf_exit_cleanup);
+ for (j = 0; ebpf_modules[j].info.thread_name != NULL; j++) {
+ if (ebpf_modules[j].enabled < NETDATA_THREAD_EBPF_STOPPING)
+ i++;
+ }
+ pthread_mutex_unlock(&ebpf_exit_cleanup);
+ }
+
+ if (i) {
+ netdata_log_error("eBPF cannot unload all threads on time, but it will go away");
+ }
+}
+
+/**
+ * Close the collector gracefully
+ */
+static void ebpf_exit()
+{
+#ifdef LIBBPF_MAJOR_VERSION
+ pthread_mutex_lock(&ebpf_exit_cleanup);
+ if (default_btf) {
+ btf__free(default_btf);
+ default_btf = NULL;
+ }
+ pthread_mutex_unlock(&ebpf_exit_cleanup);
+#endif
+
+ char filename[FILENAME_MAX + 1];
+ ebpf_pid_file(filename, FILENAME_MAX);
+ if (unlink(filename))
+ netdata_log_error("Cannot remove PID file %s", filename);
+
+#ifdef NETDATA_INTERNAL_CHECKS
+ netdata_log_error("Good bye world! I was PID %d", main_thread_id);
+#endif
+ fprintf(stdout, "EXIT\n");
+ fflush(stdout);
+
+ ebpf_check_before2go();
+ pthread_mutex_lock(&mutex_cgroup_shm);
+ if (shm_ebpf_cgroup.header) {
+ ebpf_unmap_cgroup_shared_memory();
+ shm_unlink(NETDATA_SHARED_MEMORY_EBPF_CGROUP_NAME);
+ }
+ pthread_mutex_unlock(&mutex_cgroup_shm);
+
+ exit(0);
+}
+
+/**
+ * Unload loegacy code
+ *
+ * @param objects objects loaded from eBPF programs
+ * @param probe_links links from loader
+ */
+void ebpf_unload_legacy_code(struct bpf_object *objects, struct bpf_link **probe_links)
+{
+ if (!probe_links || !objects)
+ return;
+
+ struct bpf_program *prog;
+ size_t j = 0 ;
+ bpf_object__for_each_program(prog, objects) {
+ bpf_link