From b8eaf108538615e45346ba8edec6a2fcce16298e Mon Sep 17 00:00:00 2001 From: thiagoftsm Date: Fri, 5 Aug 2022 15:07:46 +0000 Subject: Remove SIGSEGV and SIGABRT (ebpf.plugin) (#13407) --- collectors/ebpf.plugin/ebpf.c | 419 ++++++++++++++++---------- collectors/ebpf.plugin/ebpf.h | 11 +- collectors/ebpf.plugin/ebpf_apps.c | 4 +- collectors/ebpf.plugin/ebpf_cachestat.c | 85 +++--- collectors/ebpf.plugin/ebpf_dcstat.c | 79 ++--- collectors/ebpf.plugin/ebpf_disk.c | 74 ++--- collectors/ebpf.plugin/ebpf_fd.c | 74 ++--- collectors/ebpf.plugin/ebpf_filesystem.c | 112 +++---- collectors/ebpf.plugin/ebpf_filesystem.h | 20 -- collectors/ebpf.plugin/ebpf_hardirq.c | 80 ++--- collectors/ebpf.plugin/ebpf_mdflush.c | 70 ++--- collectors/ebpf.plugin/ebpf_mount.c | 67 +++-- collectors/ebpf.plugin/ebpf_oomkill.c | 35 +-- collectors/ebpf.plugin/ebpf_process.c | 189 ++++++------ collectors/ebpf.plugin/ebpf_process.h | 2 + collectors/ebpf.plugin/ebpf_shm.c | 78 ++--- collectors/ebpf.plugin/ebpf_socket.c | 490 +++++++++++++++---------------- collectors/ebpf.plugin/ebpf_socket.h | 4 +- collectors/ebpf.plugin/ebpf_softirq.c | 76 ++--- collectors/ebpf.plugin/ebpf_swap.c | 80 ++--- collectors/ebpf.plugin/ebpf_sync.c | 185 ++++++------ collectors/ebpf.plugin/ebpf_sync.h | 17 -- collectors/ebpf.plugin/ebpf_vfs.c | 75 ++--- 23 files changed, 1218 insertions(+), 1108 deletions(-) (limited to 'collectors/ebpf.plugin') diff --git a/collectors/ebpf.plugin/ebpf.c b/collectors/ebpf.plugin/ebpf.c index 5c3c716065..65c96f6727 100644 --- a/collectors/ebpf.plugin/ebpf.c +++ b/collectors/ebpf.plugin/ebpf.c @@ -18,8 +18,6 @@ char *ebpf_plugin_dir = PLUGINS_DIR; static char *ebpf_configured_log_dir = LOG_DIR; char *ebpf_algorithms[] = {"absolute", "incremental"}; -static int thread_finished = 0; -int close_ebpf_plugin = 0; struct config collector_config = { .first_section = NULL, .last_section = NULL, .mutex = NETDATA_MUTEX_INITIALIZER, @@ -29,7 +27,6 @@ struct config collector_config = { .first_section = NULL, int running_on_kernel = 0; int ebpf_nprocs; int isrh = 0; -uint32_t finalized_threads = 1; pthread_mutex_t lock; pthread_mutex_t collect_data_mutex; @@ -37,132 +34,264 @@ pthread_cond_t collect_data_cond_var; ebpf_module_t ebpf_modules[] = { { .thread_name = "process", .config_name = "process", .enabled = 0, .start_routine = ebpf_process_thread, - .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO, + .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0, .apps_routine = ebpf_process_create_apps_charts, .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, - .load = EBPF_LOAD_LEGACY, .targets = NULL}, + .load = EBPF_LOAD_LEGACY, .targets = NULL, .probe_links = NULL, .objects = NULL}, { .thread_name = "socket", .config_name = "socket", .enabled = 0, .start_routine = ebpf_socket_thread, - .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO, + .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0, .apps_routine = ebpf_socket_create_apps_charts, .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, - .load = EBPF_LOAD_LEGACY, .targets = socket_targets}, + .load = EBPF_LOAD_LEGACY, .targets = socket_targets, .probe_links = NULL, .objects = NULL}, { .thread_name = "cachestat", .config_name = "cachestat", .enabled = 0, .start_routine = ebpf_cachestat_thread, - .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO, + .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0, .apps_routine = ebpf_cachestat_create_apps_charts, .maps = NULL, .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_15 | NETDATA_V5_16, - .load = EBPF_LOAD_LEGACY, .targets = cachestat_targets}, + .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18| NETDATA_V5_4 | NETDATA_V5_15 | + NETDATA_V5_16, + .load = EBPF_LOAD_LEGACY, .targets = cachestat_targets, .probe_links = NULL, .objects = NULL}, { .thread_name = "sync", .config_name = "sync", .enabled = 0, .start_routine = ebpf_sync_thread, - .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO, + .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0, .apps_routine = NULL, .maps = NULL, .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, - .load = EBPF_LOAD_LEGACY, .targets = sync_targets}, + .load = EBPF_LOAD_LEGACY, .targets = sync_targets, .probe_links = NULL, .objects = NULL}, { .thread_name = "dc", .config_name = "dc", .enabled = 0, .start_routine = ebpf_dcstat_thread, - .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO, + .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0, .apps_routine = ebpf_dcstat_create_apps_charts, .maps = NULL, .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, - .load = EBPF_LOAD_LEGACY, .targets = dc_targets}, + .load = EBPF_LOAD_LEGACY, .targets = dc_targets, .probe_links = NULL, .objects = NULL}, { .thread_name = "swap", .config_name = "swap", .enabled = 0, .start_routine = ebpf_swap_thread, - .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO, + .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0, .apps_routine = ebpf_swap_create_apps_charts, .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, - .load = EBPF_LOAD_LEGACY, .targets = swap_targets}, + .load = EBPF_LOAD_LEGACY, .targets = swap_targets, .probe_links = NULL, .objects = NULL}, { .thread_name = "vfs", .config_name = "vfs", .enabled = 0, .start_routine = ebpf_vfs_thread, - .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO, + .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0, .apps_routine = ebpf_vfs_create_apps_charts, .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, - .load = EBPF_LOAD_LEGACY, .targets = NULL}, + .load = EBPF_LOAD_LEGACY, .targets = NULL, .probe_links = NULL, .objects = NULL}, { .thread_name = "filesystem", .config_name = "filesystem", .enabled = 0, .start_routine = ebpf_filesystem_thread, - .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO, + .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0, .apps_routine = NULL, .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 }, + .kernels = 0, .load = EBPF_LOAD_LEGACY, .targets = NULL, .probe_links = NULL, .objects = NULL }, { .thread_name = "disk", .config_name = "disk", .enabled = 0, .start_routine = ebpf_disk_thread, - .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO, + .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0, .apps_routine = NULL, .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, - .load = EBPF_LOAD_LEGACY, .targets = NULL}, + .load = EBPF_LOAD_LEGACY, .targets = NULL, .probe_links = NULL, .objects = NULL}, { .thread_name = "mount", .config_name = "mount", .enabled = 0, .start_routine = ebpf_mount_thread, - .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO, + .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0, .apps_routine = NULL, .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, - .load = EBPF_LOAD_LEGACY, .targets = mount_targets}, + .load = EBPF_LOAD_LEGACY, .targets = mount_targets, .probe_links = NULL, .objects = NULL}, { .thread_name = "fd", .config_name = "fd", .enabled = 0, .start_routine = ebpf_fd_thread, - .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO, + .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0, .apps_routine = ebpf_fd_create_apps_charts, .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, - .load = EBPF_LOAD_LEGACY, .targets = NULL}, + .load = EBPF_LOAD_LEGACY, .targets = NULL, .probe_links = NULL, .objects = NULL}, { .thread_name = "hardirq", .config_name = "hardirq", .enabled = 0, .start_routine = ebpf_hardirq_thread, - .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO, + .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0, .apps_routine = NULL, .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, - .load = EBPF_LOAD_LEGACY, .targets = NULL}, + .load = EBPF_LOAD_LEGACY, .targets = NULL, .probe_links = NULL, .objects = NULL}, { .thread_name = "softirq", .config_name = "softirq", .enabled = 0, .start_routine = ebpf_softirq_thread, - .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO, + .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0, .apps_routine = NULL, .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, - .load = EBPF_LOAD_LEGACY, .targets = NULL}, + .load = EBPF_LOAD_LEGACY, .targets = NULL, .probe_links = NULL, .objects = NULL}, { .thread_name = "oomkill", .config_name = "oomkill", .enabled = 0, .start_routine = ebpf_oomkill_thread, - .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO, + .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0, .apps_routine = ebpf_oomkill_create_apps_charts, .maps = NULL, .pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &oomkill_config, .config_file = NETDATA_OOMKILL_CONFIG_FILE, .kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4, - .load = EBPF_LOAD_LEGACY, .targets = NULL}, + .load = EBPF_LOAD_LEGACY, .targets = NULL, .probe_links = NULL, .objects = NULL}, { .thread_name = "shm", .config_name = "shm", .enabled = 0, .start_routine = ebpf_shm_thread, - .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO, + .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0, .apps_routine = ebpf_shm_create_apps_charts, .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, - .load = EBPF_LOAD_LEGACY, .targets = shm_targets}, + .load = EBPF_LOAD_LEGACY, .targets = shm_targets, .probe_links = NULL, .objects = NULL}, { .thread_name = "mdflush", .config_name = "mdflush", .enabled = 0, .start_routine = ebpf_mdflush_thread, - .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = CONFIG_BOOLEAN_NO, + .update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0, .apps_routine = NULL, .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, - .load = EBPF_LOAD_LEGACY, .targets = NULL}, + .load = EBPF_LOAD_LEGACY, .targets = NULL, .probe_links = NULL, .objects = NULL}, { .thread_name = NULL, .enabled = 0, .start_routine = NULL, .update_every = EBPF_DEFAULT_UPDATE_EVERY, - .global_charts = 0, .apps_charts = CONFIG_BOOLEAN_NO, .cgroup_charts = CONFIG_BOOLEAN_NO, + .global_charts = 0, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0, .apps_routine = NULL, .maps = NULL, .pid_map_size = 0, .names = NULL, - .cfg = NULL, .config_name = NULL, .kernels = 0, .load = EBPF_LOAD_LEGACY, .targets = NULL}, + .cfg = NULL, .config_name = NULL, .kernels = 0, .load = EBPF_LOAD_LEGACY, .targets = NULL, .probe_links = NULL, + .objects = NULL}, +}; + +struct netdata_static_thread ebpf_threads[] = { + {"EBPF PROCESS", NULL, NULL, 1, + NULL, NULL, NULL}, + {"EBPF SOCKET" , NULL, NULL, 1, + NULL, NULL, NULL}, + {"EBPF CACHESTAT" , NULL, NULL, 1, + NULL, NULL, NULL}, + {"EBPF SYNC" , NULL, NULL, 1, + NULL, NULL, NULL}, + {"EBPF DCSTAT" , NULL, NULL, 1, + NULL, NULL, NULL}, + {"EBPF SWAP" , NULL, NULL, 1, + NULL, NULL, NULL}, + {"EBPF VFS" , NULL, NULL, 1, + NULL, NULL, NULL}, + {"EBPF FILESYSTEM" , NULL, NULL, 1, + NULL, NULL, NULL}, + {"EBPF DISK" , NULL, NULL, 1, + NULL, NULL, NULL}, + {"EBPF MOUNT" , NULL, NULL, 1, + NULL, NULL, NULL}, + {"EBPF FD" , NULL, NULL, 1, + NULL, NULL, NULL}, + {"EBPF HARDIRQ" , NULL, NULL, 1, + NULL, NULL, NULL}, + {"EBPF SOFTIRQ" , NULL, NULL, 1, + NULL, NULL, NULL}, + {"EBPF OOMKILL" , NULL, NULL, 1, + NULL, NULL, NULL}, + {"EBPF SHM" , NULL, NULL, 1, + NULL, NULL, NULL}, + {"EBPF MDFLUSH" , NULL, NULL, 1, + NULL, NULL, NULL}, + {NULL , NULL, NULL, 0, + NULL, NULL, 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}, + {.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}, + {.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}, + {.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}, + {.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}, + {.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}}; + +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 + }, + {.syscall = NETDATA_SYSCALLS_SYNCFS, .enabled = CONFIG_BOOLEAN_YES, .objects = NULL, .probe_links = NULL, +#ifdef LIBBPF_MAJOR_VERSION + .sync_obj = NULL +#endif + }, + {.syscall = NETDATA_SYSCALLS_MSYNC, .enabled = CONFIG_BOOLEAN_YES, .objects = NULL, .probe_links = NULL, +#ifdef LIBBPF_MAJOR_VERSION + .sync_obj = NULL +#endif + }, + {.syscall = NETDATA_SYSCALLS_FSYNC, .enabled = CONFIG_BOOLEAN_YES, .objects = NULL, .probe_links = NULL, +#ifdef LIBBPF_MAJOR_VERSION + .sync_obj = NULL +#endif + }, + {.syscall = NETDATA_SYSCALLS_FDATASYNC, .enabled = CONFIG_BOOLEAN_YES, .objects = NULL, .probe_links = NULL, +#ifdef LIBBPF_MAJOR_VERSION + .sync_obj = NULL +#endif + }, + {.syscall = NETDATA_SYSCALLS_SYNC_FILE_RANGE, .enabled = CONFIG_BOOLEAN_YES, .objects = NULL, .probe_links = NULL, +#ifdef LIBBPF_MAJOR_VERSION + .sync_obj = NULL +#endif + }, + {.syscall = NULL, .enabled = CONFIG_BOOLEAN_NO, .objects = NULL, .probe_links = NULL, +#ifdef LIBBPF_MAJOR_VERSION + .sync_obj = NULL +#endif + } }; // Link with apps.plugin @@ -192,18 +321,6 @@ char *btf_path = NULL; * *****************************************************************/ -/** - * Clean Loaded Events - * - * This function cleans the events previous loaded on Linux. -void clean_loaded_events() -{ - int event_pid; - for (event_pid = 0; ebpf_modules[event_pid].probes; event_pid++) - clean_kprobe_events(NULL, (int)ebpf_modules[event_pid].thread_id, ebpf_modules[event_pid].probes); -} - */ - /** * Close the collector gracefully * @@ -211,64 +328,89 @@ void clean_loaded_events() */ static void ebpf_exit(int sig) { - close_ebpf_plugin = 1; - static int remove_pid = 0; - - // When both threads were not finished case I try to go in front this address, the collector will crash - if (!thread_finished) { - return; +#ifdef LIBBPF_MAJOR_VERSION + if (default_btf) { + btf__free(default_btf); + default_btf = NULL; } +#endif - ebpf_close_cgroup_shm(); + char filename[FILENAME_MAX + 1]; + ebpf_pid_file(filename, FILENAME_MAX); + if (unlink(filename)) + error("Cannot remove PID file %s", filename); - /* - int ret = fork(); - if (ret < 0) // error - error("Cannot fork(), so I won't be able to clean %skprobe_events", NETDATA_DEBUGFS); - else if (!ret) { // child - int i; - for (i = getdtablesize(); i >= 0; --i) - close(i); + exit(sig); +} - int fd = open("/dev/null", O_RDWR, 0); - if (fd != -1) { - dup2(fd, STDIN_FILENO); - dup2(fd, STDOUT_FILENO); - dup2(fd, STDERR_FILENO); - } +/** + * Unload loegacy code + * + * @param objects objects loaded from eBPF programs + * @param probe_links links from loader + */ +static void ebpf_unload_legacy_code(struct bpf_object *objects, struct bpf_link **probe_links) +{ + if (!probe_links || !objects) + return; - if (fd > 2) - close(fd); + struct bpf_program *prog; + size_t j = 0 ; + bpf_object__for_each_program(prog, objects) { + bpf_link__destroy(probe_links[j]); + j++; + } + freez(probe_links); + if (objects) + bpf_object__close(objects); +} - int sid = setsid(); - if (sid >= 0) { - debug(D_EXIT, "Wait for father %d die", getpid()); - sleep_usec(200000); // Sleep 200 milliseconds to father dies. - clean_loaded_events(); - } else { - error("Cannot become session id leader, so I won't try to clean kprobe_events.\n"); +int ebpf_exit_plugin = 0; +/** + * Close the collector gracefully + * + * @param sig is the signal number used to close the collector + */ +static void ebpf_stop_threads(int sig) +{ + ebpf_exit_plugin = 1; + int i; + for (i = 0; ebpf_threads[i].name != NULL; i++); + + usec_t max = 2 * USEC_PER_SEC, step = 100000; + while (i && max) { + max -= step; + sleep_usec(step); + i = 0; + int j; + for (j = 0; ebpf_threads[j].name != NULL; j++) { + if (ebpf_threads[j].enabled != NETDATA_MAIN_THREAD_EXITED) + i++; } - } else { // parent - exit(0); } - */ -#ifdef LIBBPF_MAJOR_VERSION - if (default_btf) { - btf__free(default_btf); - default_btf = NULL; + //Unload threads(except sync and filesystem) + for (i = 0; ebpf_threads[i].name != NULL; i++) { + if (ebpf_threads[i].enabled == NETDATA_MAIN_THREAD_EXITED && i != EBPF_MODULE_FILESYSTEM_IDX && + i != EBPF_MODULE_SYNC_IDX) + ebpf_unload_legacy_code(ebpf_modules[i].objects, ebpf_modules[i].probe_links); } -#endif - if (!remove_pid) { - remove_pid = 1; - char filename[FILENAME_MAX + 1]; - ebpf_pid_file(filename, FILENAME_MAX); - if (unlink(filename)) - error("Cannot remove PID file %s", filename); + //Unload filesystem + if (ebpf_threads[EBPF_MODULE_FILESYSTEM_IDX].enabled == NETDATA_MAIN_THREAD_EXITED) { + for (i = 0; localfs[i].filesystem != NULL; i++) { + ebpf_unload_legacy_code(localfs[i].objects, localfs[i].probe_links); + } } - exit(sig); + //Unload Sync + if (ebpf_threads[EBPF_MODULE_SYNC_IDX].enabled == NETDATA_MAIN_THREAD_EXITED) { + for (i = 0; local_syscalls[i].syscall != NULL; i++) { + ebpf_unload_legacy_code(local_syscalls[i].objects, local_syscalls[i].probe_links); + } + } + + ebpf_exit(sig); } /***************************************************************** @@ -659,7 +801,7 @@ static inline void ebpf_enable_specific_chart(struct ebpf_module *em, int disabl // oomkill stores data inside apps submenu, so it always need to have apps_enabled for plugin to create // its chart, without this comparison eBPF.plugin will try to store invalid data when apps is disabled. if (!disable_apps || !strcmp(em->thread_name, "oomkill")) { - em->apps_charts = CONFIG_BOOLEAN_YES; + em->apps_charts = NETDATA_EBPF_APPS_FLAG_YES; } if (!disable_cgroup) { @@ -724,7 +866,7 @@ static inline void ebpf_disable_apps() { int i; for (i = 0; ebpf_modules[i].thread_name; i++) { - ebpf_modules[i].apps_charts = 0; + ebpf_modules[i].apps_charts = NETDATA_EBPF_APPS_FLAG_NO; } } @@ -1031,7 +1173,6 @@ int ebpf_start_pthread_variables() pthread_mutex_init(&collect_data_mutex, NULL); if (pthread_cond_init(&collect_data_cond_var, NULL)) { - thread_finished++; error("Cannot start conditional variable to control Apps charts."); return -1; } @@ -1051,7 +1192,7 @@ static inline uint32_t ebpf_am_i_collect_pids() uint32_t ret = 0; int i; for (i = 0; ebpf_modules[i].thread_name; i++) { - ret |= ebpf_modules[i].cgroup_charts | ebpf_modules[i].apps_charts; + ret |= ebpf_modules[i].cgroup_charts | (ebpf_modules[i].apps_charts & NETDATA_EBPF_APPS_FLAG_YES); } return ret; @@ -1675,7 +1816,6 @@ static void ebpf_parse_args(int argc, char **argv) &apps_groups_default_target, &apps_groups_root_target, ebpf_stock_config_dir, "groups")) { error("Cannot read process groups '%s/apps_groups.conf'. There are no internal defaults. Failing.", ebpf_stock_config_dir); - thread_finished++; ebpf_exit(1); } } else @@ -1831,6 +1971,19 @@ static void ebpf_manage_pid(pid_t pid) ebpf_update_pid_file(filename, pid); } +/** + * Set start routine + * + * Set static routine before threads to be created. + */ + static void ebpf_set_static_routine() + { + int i; + for (i = 0; ebpf_modules[i].thread_name; i++) { + ebpf_threads[i].start_routine = ebpf_modules[i].start_routine; + } + } + /** * Entry point * @@ -1875,16 +2028,19 @@ int main(int argc, char **argv) return 4; } - signal(SIGINT, ebpf_exit); - signal(SIGTERM, ebpf_exit); - signal(SIGPIPE, ebpf_exit); + signal(SIGINT, ebpf_stop_threads); + signal(SIGQUIT, ebpf_stop_threads); + signal(SIGTERM, ebpf_stop_threads); + signal(SIGPIPE, ebpf_stop_threads); if (ebpf_start_pthread_variables()) { - thread_finished++; error("Cannot start mutex to control overall charts."); ebpf_exit(5); } + netdata_configured_host_prefix = getenv("NETDATA_HOST_PREFIX"); + if(verify_netdata_host_prefix() == -1) ebpf_exit(6); + ebpf_allocate_common_vectors(); #ifdef LIBBPF_MAJOR_VERSION @@ -1897,44 +2053,7 @@ int main(int argc, char **argv) read_local_ports("/proc/net/udp", IPPROTO_UDP); read_local_ports("/proc/net/udp6", IPPROTO_UDP); - struct netdata_static_thread ebpf_threads[] = { - {"EBPF PROCESS", NULL, NULL, 1, - NULL, NULL, ebpf_modules[EBPF_MODULE_PROCESS_IDX].start_routine}, - {"EBPF SOCKET" , NULL, NULL, 1, - NULL, NULL, ebpf_modules[EBPF_MODULE_SOCKET_IDX].start_routine}, - {"EBPF CACHESTAT" , NULL, NULL, 1, - NULL, NULL, ebpf_modules[EBPF_MODULE_CACHESTAT_IDX].start_routine}, - {"EBPF SYNC" , NULL, NULL, 1, - NULL, NULL, ebpf_modules[EBPF_MODULE_SYNC_IDX].start_routine}, - {"EBPF DCSTAT" , NULL, NULL, 1, - NULL, NULL, ebpf_modules[EBPF_MODULE_DCSTAT_IDX].start_routine}, - {"EBPF SWAP" , NULL, NULL, 1, - NULL, NULL, ebpf_modules[EBPF_MODULE_SWAP_IDX].start_routine}, - {"EBPF VFS" , NULL, NULL, 1, - NULL, NULL, ebpf_modules[EBPF_MODULE_VFS_IDX].start_routine}, - {"EBPF FILESYSTEM" , NULL, NULL, 1, - NULL, NULL, ebpf_modules[EBPF_MODULE_FILESYSTEM_IDX].start_routine}, - {"EBPF DISK" , NULL, NULL, 1, - NULL, NULL, ebpf_modules[EBPF_MODULE_DISK_IDX].start_routine}, - {"EBPF MOUNT" , NULL, NULL, 1, - NULL, NULL, ebpf_modules[EBPF_MODULE_MOUNT_IDX].start_routine}, - {"EBPF FD" , NULL, NULL, 1, - NULL, NULL, ebpf_modules[EBPF_MODULE_FD_IDX].start_routine}, - {"EBPF HARDIRQ" , NULL, NULL, 1, - NULL, NULL, ebpf_modules[EBPF_MODULE_HARDIRQ_IDX].start_routine}, - {"EBPF SOFTIRQ" , NULL, NULL, 1, - NULL, NULL, ebpf_modules[EBPF_MODULE_SOFTIRQ_IDX].start_routine}, - {"EBPF OOMKILL" , NULL, NULL, 1, - NULL, NULL, ebpf_modules[EBPF_MODULE_OOMKILL_IDX].start_routine}, - {"EBPF SHM" , NULL, NULL, 1, - NULL, NULL, ebpf_modules[EBPF_MODULE_SHM_IDX].start_routine}, - {"EBPF MDFLUSH" , NULL, NULL, 1, - NULL, NULL, ebpf_modules[EBPF_MODULE_MDFLUSH_IDX].start_routine}, - {NULL , NULL, NULL, 0, - NULL, NULL, NULL} - }; - - //clean_loaded_events(); + ebpf_set_static_routine(); int i; for (i = 0; ebpf_threads[i].name != NULL; i++) { @@ -1943,16 +2062,16 @@ int main(int argc, char **argv) ebpf_module_t *em = &ebpf_modules[i]; em->thread_id = i; - netdata_thread_create(st->thread, st->name, NETDATA_THREAD_OPTION_JOINABLE, st->start_routine, em); + netdata_thread_create(st->thread, st->name, NETDATA_THREAD_OPTION_DEFAULT, st->start_routine, em); } - for (i = 0; ebpf_threads[i].name != NULL; i++) { - struct netdata_static_thread *st = &ebpf_threads[i]; - netdata_thread_join(*st->thread, NULL); + usec_t step = 60 * USEC_PER_SEC; + heartbeat_t hb; + heartbeat_init(&hb); + //Plugin will be killed when it receives a signal + for (;;) { + (void)heartbeat_next(&hb, step); } - thread_finished++; - ebpf_exit(0); - return 0; } diff --git a/collectors/ebpf.plugin/ebpf.h b/collectors/ebpf.plugin/ebpf.h index 337e4f4710..c23ca332d9 100644 --- a/collectors/ebpf.plugin/ebpf.h +++ b/collectors/ebpf.plugin/ebpf.h @@ -108,6 +108,12 @@ typedef struct ebpf_tracepoint { char *event; } ebpf_tracepoint_t; +enum ebpf_threads_status { + NETDATA_THREAD_EBPF_RUNNING, + NETDATA_THREAD_EBPF_STOPPING, + NETDATA_THREAD_EBPF_STOPPED +}; + // Copied from musl header #ifndef offsetof #if __GNUC__ > 3 @@ -162,7 +168,6 @@ extern void *ebpf_socket_thread(void *ptr); // Common variables extern pthread_mutex_t lock; -extern int close_ebpf_plugin; extern int ebpf_nprocs; extern int running_on_kernel; extern int isrh; @@ -265,7 +270,6 @@ extern int shm_fd_ebpf_cgroup; extern sem_t *shm_sem_ebpf_cgroup; extern pthread_mutex_t mutex_cgroup_shm; extern size_t all_pids_count; -extern uint32_t finalized_threads; extern ebpf_plugin_stats_t plugin_statistics; extern struct btf *default_btf; @@ -281,6 +285,9 @@ extern void ebpf_write_chart_obsolete(char *type, char *id, char *title, char *u char *charttype, char *context, int order, int update_every); extern void write_histogram_chart(char *family, char *name, const netdata_idx_t *hist, char **dimensions, uint32_t end); void ebpf_update_disabled_plugin_stats(ebpf_module_t *em); +extern ebpf_filesystem_partitions_t localfs[]; +extern ebpf_sync_syscalls_t local_syscalls[]; +extern int ebpf_exit_plugin; #define EBPF_MAX_SYNCHRONIZATION_TIME 300 diff --git a/collectors/ebpf.plugin/ebpf_apps.c b/collectors/ebpf.plugin/ebpf_apps.c index 2c65db8d11..7519e06402 100644 --- a/collectors/ebpf.plugin/ebpf_apps.c +++ b/collectors/ebpf.plugin/ebpf_apps.c @@ -134,7 +134,7 @@ size_t zero_all_targets(struct target *root) while (pid_on_target) { struct pid_on_target *pid_on_target_to_free = pid_on_target; pid_on_target = pid_on_target->next; - free(pid_on_target_to_free); + freez(pid_on_target_to_free); } w->root_pid = NULL; @@ -1119,7 +1119,7 @@ void collect_data_for_all_processes(int tbl_pid_stats_fd) key = pids->pid; ebpf_process_stat_t *w = global_process_stats[key]; if (!w) { - w = mallocz(sizeof(ebpf_process_stat_t)); + w = callocz(1, sizeof(ebpf_process_stat_t)); global_process_stats[key] = w; } diff --git a/collectors/ebpf.plugin/ebpf_cachestat.c b/collectors/ebpf.plugin/ebpf_cachestat.c index 728a863afc..14669bf680 100644 --- a/collectors/ebpf.plugin/ebpf_cachestat.c +++ b/collectors/ebpf.plugin/ebpf_cachestat.c @@ -5,9 +5,6 @@ netdata_publish_cachestat_t **cachestat_pid; -static struct bpf_link **probe_links = NULL; -static struct bpf_object *objects = NULL; - static char *cachestat_counter_dimension_name[NETDATA_CACHESTAT_END] = { "ratio", "dirty", "hit", "miss" }; static netdata_syscall_stat_t cachestat_counter_aggregated_data[NETDATA_CACHESTAT_END]; @@ -18,8 +15,6 @@ netdata_cachestat_pid_t *cachestat_vector = NULL; static netdata_idx_t cachestat_hash_values[NETDATA_CACHESTAT_END]; static netdata_idx_t *cachestat_values = NULL; -static int read_thread_closed = 1; - struct netdata_static_thread cachestat_threads = {"CACHESTAT KERNEL", NULL, NULL, 1, NULL, NULL, NULL}; @@ -44,6 +39,7 @@ struct config cachestat_config = { .first_section = NULL, .mutex = NETDATA_MUTEX_INITIALIZER, .index = { .avl_tree = { .root = NULL, .compar = appconfig_section_compare }, .rwlock = AVL_LOCK_INITIALIZER } }; +static enum ebpf_threads_status ebpf_cachestat_exited = NETDATA_THREAD_EBPF_RUNNING; netdata_ebpf_targets_t cachestat_targets[] = { {.name = "add_to_page_cache_lru", .mode = EBPF_LOAD_TRAMPOLINE}, {.name = "mark_page_accessed", .mode = EBPF_LOAD_TRAMPOLINE}, @@ -294,43 +290,48 @@ static inline int ebpf_cachestat_load_and_attach(struct cachestat_bpf *obj, ebpf *****************************************************************/ /** - * Clean up the main thread. + * Cachestat exit. + * + * Cancel child and exit. * * @param ptr thread data. */ -static void ebpf_cachestat_cleanup(void *ptr) +static void ebpf_cachestat_exit(void *ptr) { ebpf_module_t *em = (ebpf_module_t *)ptr; - if (!em->enabled) + if (!em->enabled) { + em->enabled = NETDATA_MAIN_THREAD_EXITED; return; - - heartbeat_t hb; - heartbeat_init(&hb); - uint32_t tick = 2*USEC_PER_MS; - while (!read_thread_closed) { - usec_t dt = heartbeat_next(&hb, tick); - UNUSED(dt); } + ebpf_cachestat_exited = NETDATA_THREAD_EBPF_STOPPING; +} + +/** + * Cachestat cleanup + * + * Clean up allocated addresses. + * + * @param ptr thread data. + */ +static void ebpf_cachestat_cleanup(void *ptr) +{ + ebpf_module_t *em = (ebpf_module_t *)ptr; + if (ebpf_cachestat_exited != NETDATA_THREAD_EBPF_STOPPED) + return; + ebpf_cleanup_publish_syscall(cachestat_counter_publish_aggregated); freez(cachestat_vector); freez(cachestat_values); + freez(cachestat_threads.thread); - if (probe_links) { - struct bpf_program *prog; - size_t i = 0 ; - bpf_object__for_each_program(prog, objects) { - bpf_link__destroy(probe_links[i]); - i++; - } - if (objects) - bpf_object__close(objects); - } #ifdef LIBBPF_MAJOR_VERSION - else if (bpf_obj) + if (bpf_obj) cachestat_bpf__destroy(bpf_obj); #endif + cachestat_threads.enabled = NETDATA_MAIN_THREAD_EXITED; + em->enabled = NETDATA_MAIN_THREAD_EXITED; } /***************************************************************** @@ -594,6 +595,8 @@ void ebpf_cachestat_create_apps_charts(struct ebpf_module *em, void *ptr) 20093, ebpf_algorithms[NETDATA_EBPF_ABSOLUTE_IDX], root, em->update_every, NETDATA_EBPF_MODULE_NAME_CACHESTAT); + + em->apps_charts |= NETDATA_EBPF_APPS_FLAG_CHART_CREATED; } /***************************************************************** @@ -639,22 +642,25 @@ static void read_global_table() */ void *ebpf_cachestat_read_hash(void *ptr) { - read_thread_closed = 0; - + netdata_thread_cleanup_push(ebpf_cachestat_cleanup, ptr); heartbeat_t hb; heartbeat_init(&hb); ebpf_module_t *em = (ebpf_module_t *)ptr; usec_t step = NETDATA_LATENCY_CACHESTAT_SLEEP_MS * em->update_every; - while (!close_ebpf_plugin) { + while (ebpf_cachestat_exited == NETDATA_THREAD_EBPF_RUNNING) { usec_t dt = heartbeat_next(&hb, step); (void)dt; + if (ebpf_cachestat_exited == NETDATA_THREAD_EBPF_STOPPING) + break; read_global_table(); } - read_thread_closed = 1; + ebpf_cachestat_exited = NETDATA_THREAD_EBPF_STOPPED; + + netdata_thread_cleanup_pop(1); return NULL; } @@ -1068,23 +1074,26 @@ void ebpf_cachestat_send_cgroup_data(int update_every) */ static void cachestat_collector(ebpf_module_t *em) { - cachestat_threads.thread = mallocz(sizeof(netdata_thread_t)); + cachestat_threads.thread = callocz(1, sizeof(netdata_thread_t)); cachestat_threads.start_routine = ebpf_cachestat_read_hash; - netdata_thread_create(cachestat_threads.thread, cachestat_threads.name, NETDATA_THREAD_OPTION_JOINABLE, + netdata_thread_create(cachestat_threads.thread, cachestat_threads.name, NETDATA_THREAD_OPTION_DEFAULT, ebpf_cachestat_read_hash, em); netdata_publish_cachestat_t publish; memset(&publish, 0, sizeof(publish)); - int apps = em->apps_charts; int cgroups = em->cgroup_charts; int update_every = em->update_every; heartbeat_t hb; heartbeat_init(&hb); usec_t step = update_every * USEC_PER_SEC; - while (!close_ebpf_plugin) { + //This will be cancelled by its parent + while (!ebpf_exit_plugin) { (void)heartbeat_next(&hb, step); + if (ebpf_exit_plugin) + break; + netdata_apps_integration_flags_t apps = em->apps_charts; pthread_mutex_lock(&collect_data_mutex); if (apps) read_apps_table(); @@ -1096,7 +1105,7 @@ static void cachestat_collector(ebpf_module_t *em) cachestat_send_global(&publish); - if (apps) + if (apps & NETDATA_EBPF_APPS_FLAG_CHART_CREATED) ebpf_cache_send_apps_data(apps_groups_root_target); if (cgroups) @@ -1219,8 +1228,8 @@ static int ebpf_cachestat_load_bpf(ebpf_module_t *em) { int ret = 0; if (em->load == EBPF_LOAD_LEGACY) { - probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &objects); - if (!probe_links) { + em->probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &em->objects); + if (!em->probe_links) { ret = -1; } } @@ -1251,7 +1260,7 @@ static int ebpf_cachestat_load_bpf(ebpf_module_t *em) */ void *ebpf_cachestat_thread(void *ptr) { - netdata_thread_cleanup_push(ebpf_cachestat_cleanup, ptr); + netdata_thread_cleanup_push(ebpf_cachestat_exit, ptr); ebpf_module_t *em = (ebpf_module_t *)ptr; em->maps = cachestat_maps; diff --git a/collectors/ebpf.plugin/ebpf_dcstat.c b/collectors/ebpf.plugin/ebpf_dcstat.c index 1f4dc4a2e9..8cf063ca15 100644 --- a/collectors/ebpf.plugin/ebpf_dcstat.c +++ b/collectors/ebpf.plugin/ebpf_dcstat.c @@ -10,14 +10,9 @@ static netdata_publish_syscall_t dcstat_counter_publish_aggregated[NETDATA_DCSTA netdata_dcstat_pid_t *dcstat_vector = NULL; netdata_publish_dcstat_t **dcstat_pid = NULL; -static struct bpf_link **probe_links = NULL; -static struct bpf_object *objects = NULL; - static netdata_idx_t dcstat_hash_values[NETDATA_DCSTAT_IDX_END]; static netdata_idx_t *dcstat_values = NULL; -static int read_thread_closed = 1; - struct config dcstat_config = { .first_section = NULL, .last_section = NULL, .mutex = NETDATA_MUTEX_INITIALIZER, @@ -27,6 +22,7 @@ struct config dcstat_config = { .first_section = NULL, struct netdata_static_thread dcstat_threads = {"DCSTAT KERNEL", NULL, NULL, 1, NULL, NULL, NULL}; +static enum ebpf_threads_status ebpf_dcstat_exited = NETDATA_THREAD_EBPF_RUNNING; static ebpf_local_maps_t dcstat_maps[] = {{.name = "dcstat_global", .internal_input = NETDATA_DIRECTORY_CACHE_END, .user_input = 0, .type = NETDATA_EBPF_MAP_STATIC, @@ -265,6 +261,24 @@ void ebpf_dcstat_clean_names() } } +/** + * DCstat exit + * + * Cancel child and exit. + * + * @param ptr thread data. + */ +static void ebpf_dcstat_exit(void *ptr) +{ + ebpf_module_t *em = (ebpf_module_t *)ptr; + if (!em->enabled) { + em->enabled = NETDATA_MAIN_THREAD_EXITED; + return; + } + + ebpf_dcstat_exited = NETDATA_THREAD_EBPF_STOPPING; +} + /** * Clean up the main thread. * @@ -273,38 +287,24 @@ void ebpf_dcstat_clean_names() static void ebpf_dcstat_cleanup(void *ptr) { ebpf_module_t *em = (ebpf_module_t *)ptr; - if (!em->enabled) + if (ebpf_dcstat_exited != NETDATA_THREAD_EBPF_STOPPED) return; - heartbeat_t hb; - heartbeat_init(&hb); - uint32_t tick = 2 * USEC_PER_MS; - while (!read_thread_closed) { - usec_t dt = heartbeat_next(&hb, tick); - UNUSED(dt); - } - freez(dcstat_vector); freez(dcstat_values); + freez(dcstat_threads.thread); ebpf_cleanup_publish_syscall(dcstat_counter_publish_aggregated); ebpf_dcstat_clean_names(); - if (probe_links) { - struct bpf_program *prog; - size_t i = 0 ; - bpf_object__for_each_program(prog, objects) { - bpf_link__destroy(probe_links[i]); - i++; - } - if (objects) - bpf_object__close(objects); - } #ifdef LIBBPF_MAJOR_VERSION - else if (bpf_obj) + if (bpf_obj) dc_bpf__destroy(bpf_obj); #endif + + dcstat_threads.enabled = NETDATA_MAIN_THREAD_EXITED; + em->enabled = NETDATA_MAIN_THREAD_EXITED; } /***************************************************************** @@ -358,6 +358,8 @@ void ebpf_dcstat_create_apps_charts(struct ebpf_module *em, void *ptr) 20103, ebpf_algorithms[NETDATA_EBPF_ABSOLUTE_IDX], root, em->update_every, NETDATA_EBPF_MODULE_NAME_DCSTAT); + + em->apps_charts |= NETDATA_EBPF_APPS_FLAG_CHART_CREATED; } /***************************************************************** @@ -522,22 +524,25 @@ static void read_global_table() */ void *ebpf_dcstat_read_hash(void *ptr) { - read_thread_closed = 0; - + netdata_thread_cleanup_push(ebpf_dcstat_cleanup, ptr); heartbeat_t hb; heartbeat_init(&hb); ebpf_module_t *em = (ebpf_module_t *)ptr; usec_t step = NETDATA_LATENCY_DCSTAT_SLEEP_MS * em->update_every; - while (!close_ebpf_plugin) { + while (ebpf_dcstat_exited == NETDATA_THREAD_EBPF_RUNNING) { usec_t dt = heartbeat_next(&hb, step); (void)dt; + if (ebpf_dcstat_exited == NETDATA_THREAD_EBPF_STOPPING) + break; read_global_table(); } - read_thread_closed = 1; + ebpf_dcstat_exited = NETDATA_THREAD_EBPF_STOPPED; + + netdata_thread_cleanup_pop(1); return NULL; } @@ -1000,20 +1005,22 @@ static void dcstat_collector(ebpf_module_t *em) dcstat_threads.thread = mallocz(sizeof(netdata_thread_t)); dcstat_threads.start_routine = ebpf_dcstat_read_hash; - netdata_thread_create(dcstat_threads.thread, dcstat_threads.name, NETDATA_THREAD_OPTION_JOINABLE, + netdata_thread_create(dcstat_threads.thread, dcstat_threads.name, NETDATA_THREAD_OPTION_DEFAULT, ebpf_dcstat_read_hash, em); netdata_publish_dcstat_t publish; memset(&publish, 0, sizeof(publish)); - int apps = em->apps_charts; int cgroups = em->cgroup_charts; int update_every = em->update_every; heartbeat_t hb; heartbeat_init(&hb); usec_t step = update_every * USEC_PER_SEC; - while (!close_ebpf_plugin) { + while (!ebpf_exit_plugin) { (void)heartbeat_next(&hb, step); + if (ebpf_exit_plugin) + break; + netdata_apps_integration_flags_t apps = em->apps_charts; pthread_mutex_lock(&collect_data_mutex); if (apps) read_apps_table(); @@ -1025,7 +1032,7 @@ static void dcstat_collector(ebpf_module_t *em) dcstat_send_global(&publish); - if (apps) + if (apps & NETDATA_EBPF_APPS_FLAG_CHART_CREATED) ebpf_dcache_send_apps_data(apps_groups_root_target); if (cgroups) @@ -1110,8 +1117,8 @@ static int ebpf_dcstat_load_bpf(ebpf_module_t *em) { int ret = 0; if (em->load == EBPF_LOAD_LEGACY) { - probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &objects); - if (!probe_links) { + em->probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &em->objects); + if (!em->probe_links) { ret = -1; } } @@ -1142,7 +1149,7 @@ static int ebpf_dcstat_load_bpf(ebpf_module_t *em) */ void *ebpf_dcstat_thread(void *ptr) { - netdata_thread_cleanup_push(ebpf_dcstat_cleanup, ptr); + netdata_thread_cleanup_push(ebpf_dcstat_exit, ptr); ebpf_module_t *em = (ebpf_module_t *)ptr; em->maps = dcstat_maps; diff --git a/collectors/ebpf.plugin/ebpf_disk.c b/collectors/ebpf.plugin/ebpf_disk.c index 09e7e6880e..96b1705cea 100644 --- a/collectors/ebpf.plugin/ebpf_disk.c +++ b/collectors/ebpf.plugin/ebpf_disk.c @@ -25,9 +25,6 @@ char *tracepoint_block_type = { "block"} ; char *tracepoint_block_issue = { "block_rq_issue" }; char *tracepoint_block_rq_complete = { "block_rq_complete" }; -static struct bpf_link **probe_links = NULL; -static struct bpf_object *objects = NULL; - static int was_block_issue_enabled = 0; static int was_block_rq_complete_enabled = 0; @@ -35,12 +32,11 @@ static char **dimensions = NULL; static netdata_syscall_stat_t disk_aggregated_data[NETDATA_EBPF_HIST_MAX_BINS]; static netdata_publish_syscall_t disk_publish_aggregated[NETDATA_EBPF_HIST_MAX_BINS]; -static int read_thread_closed = 1; - static netdata_idx_t *disk_hash_values = NULL; static struct netdata_static_thread disk_threads = {"DISK KERNEL", NULL, NULL, 1, NULL, NULL, NULL }; +static enum ebpf_threads_status ebpf_disk_exited = NETDATA_THREAD_EBPF_RUNNING; ebpf_publish_disk_t *plot_disks = NULL; pthread_mutex_t plot_mutex; @@ -428,25 +424,37 @@ static void ebpf_cleanup_disk_list() } /** - * Clean up the main thread. + * Disk exit. + * + * Cancel child and exit. * * @param ptr thread data. */ -static void ebpf_disk_cleanup(void *ptr) +static void ebpf_disk_exit(void *ptr) { - ebpf_disk_disable_tracepoints(); + ebpf_module_t *em = (ebpf_module_t *)ptr; + if (!em->enabled) { + em->enabled = NETDATA_MAIN_THREAD_EXITED; + return; + } + + ebpf_disk_exited = NETDATA_THREAD_EBPF_STOPPING; +} +/** + * Disk Cleanup + * + * Clean up allocated memory. + * + * @param ptr thread data. + */ +static void ebpf_disk_cleanup(void *ptr) +{ ebpf_module_t *em = (ebpf_module_t *)ptr; - if (!em->enabled) + if (ebpf_disk_exited != NETDATA_THREAD_EBPF_STOPPED) return; - heartbeat_t hb; - heartbeat_init(&hb); - uint32_t tick = 2 * USEC_PER_MS; - while (!read_thread_closed) { - usec_t dt = heartbeat_next(&hb, tick); - UNUSED(dt); - } + ebpf_disk_disable_tracepoints(); if (dimensions) ebpf_histogram_dimension_cleanup(dimensions, NETDATA_EBPF_HIST_MAX_BINS); @@ -458,16 +466,8 @@ static void ebpf_disk_cleanup(void *ptr) ebpf_cleanup_plot_disks(); ebpf_cleanup_disk_list(); - if (probe_links) { - struct bpf_program *prog; - size_t i = 0 ; - bpf_object__for_each_program(prog, objects) { - bpf_link__destroy(probe_links[i]); - i++; - } - if (objects) - bpf_object__close(objects); - } + disk_threads.enabled = NETDATA_MAIN_THREAD_EXITED; + em->enabled = NETDATA_MAIN_THREAD_EXITED; } /***************************************************************** @@ -583,19 +583,25 @@ static void read_hard_disk_tables(int table) */ void *ebpf_disk_read_hash(void *ptr) { + netdata_thread_cleanup_push(ebpf_disk_cleanup, ptr); heartbeat_t hb; heartbeat_init(&hb); ebpf_module_t *em = (ebpf_module_t *)ptr; usec_t step = NETDATA_LATENCY_DISK_SLEEP_MS * em->update_every; - while (!close_ebpf_plugin) { + while (ebpf_disk_exited == NETDATA_THREAD_EBPF_RUNNING) { usec_t dt = heartbeat_next(&hb, step); (void)dt; + if (ebpf_disk_exited == NETDATA_THREAD_EBPF_STOPPING) + break; read_hard_disk_tables(disk_maps[NETDATA_DISK_READ].map_fd); } + ebpf_disk_exited = NETDATA_THREAD_EBPF_STOPPED; + + netdata_thread_cleanup_pop(1); return NULL; } @@ -725,16 +731,17 @@ static void disk_collector(ebpf_module_t *em) disk_threads.thread = mallocz(sizeof(netdata_thread_t)); disk_threads.start_routine = ebpf_disk_read_hash; - netdata_thread_create(disk_threads.thread, disk_threads.name, NETDATA_THREAD_OPTION_JOINABLE, + netdata_thread_create(disk_threads.thread, disk_threads.name, NETDATA_THREAD_OPTION_DEFAULT, ebpf_disk_read_hash, em); int update_every = em->update_every; - read_thread_closed = 0; heartbeat_t hb; heartbeat_init(&hb); usec_t step = update_every * USEC_PER_SEC; - while (!close_ebpf_plugin) { + while (!ebpf_exit_plugin) { (void)heartbeat_next(&hb, step); + if (ebpf_exit_plugin) + break; pthread_mutex_lock(&lock); ebpf_remove_pointer_from_plot_disk(em); @@ -744,7 +751,6 @@ static void disk_collector(ebpf_module_t *em) ebpf_update_disks(em); } - read_thread_closed = 1; } /***************************************************************** @@ -794,7 +800,7 @@ static int ebpf_disk_enable_tracepoints() */ void *ebpf_disk_thread(void *ptr) { - netdata_thread_cleanup_push(ebpf_disk_cleanup, ptr); + netdata_thread_cleanup_push(ebpf_disk_exit, ptr); ebpf_module_t *em = (ebpf_module_t *)ptr; em->maps = disk_maps; @@ -819,8 +825,8 @@ void *ebpf_disk_thread(void *ptr) goto enddisk; } - probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &objects); - if (!probe_links) { + em->probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &em->objects); + if (!em->probe_links) { em->enabled = 0; goto enddisk; } diff --git a/collectors/ebpf.plugin/ebpf_fd.c b/collectors/ebpf.plugin/ebpf_fd.c index f466ed783e..b4e577dad0 100644 --- a/collectors/ebpf.plugin/ebpf_fd.c +++ b/collectors/ebpf.plugin/ebpf_fd.c @@ -29,12 +29,9 @@ struct config fd_config = { .first_section = NULL, .last_section = NULL, .mutex .index = {.avl_tree = { .root = NULL, .compar = appconfig_section_compare }, .rwlock = AVL_LOCK_INITIALIZER } }; -static struct bpf_link **probe_links = NULL; -static struct bpf_object *objects = NULL; - struct netdata_static_thread fd_thread = {"FD KERNEL", NULL, NULL, 1, NULL, NULL, NULL}; -static int read_thread_closed = 1; +static enum ebpf_threads_status ebpf_fd_exited = NETDATA_THREAD_EBPF_RUNNING; static netdata_idx_t fd_hash_values[NETDATA_FD_COUNTER]; static netdata_idx_t *fd_values = NULL; @@ -47,6 +44,24 @@ netdata_fd_stat_t **fd_pid = NULL; * *****************************************************************/ +/** + * FD Exit + * + * Cancel child thread and exit. + * + * @param ptr thread data. + */ +static void ebpf_fd_exit(void *ptr) +{ + ebpf_module_t *em = (ebpf_module_t *)ptr; + if (!em->enabled) { + em->enabled = NETDATA_MAIN_THREAD_EXITED; + return; + } + + ebpf_fd_exited = NETDATA_THREAD_EBPF_STOPPING; +} + /** * Clean up the main thread. * @@ -55,32 +70,16 @@ netdata_fd_stat_t **fd_pid = NULL; static void ebpf_fd_cleanup(void *ptr) { ebpf_module_t *em = (ebpf_module_t *)ptr; - if (!em->enabled) + if (ebpf_fd_exited != NETDATA_THREAD_EBPF_STOPPED) return; - heartbeat_t hb; - heartbeat_init(&hb); - uint32_t tick = 2 * USEC_PER_MS; - while (!read_thread_closed) { - usec_t dt = heartbeat_next(&hb, tick); - UNUSED(dt); - } - ebpf_cleanup_publish_syscall(fd_publish_aggregated); freez(fd_thread.thread); freez(fd_values); freez(fd_vector); - if (probe_links) { - struct bpf_program *prog; - size_t i = 0 ; - bpf_object__for_each_program(prog, objects) { - bpf_link__destroy(probe_links[i]); - i++; - } - if (objects) - bpf_object__close(objects); - } + fd_thread.enabled = NETDATA_MAIN_THREAD_EXITED; + em->enabled = NETDATA_MAIN_THREAD_EXITED; } /***************************************************************** @@ -148,21 +147,24 @@ static void read_global_table() */ void *ebpf_fd_read_hash(void *ptr) { - read_thread_closed = 0; - + netdata_thread_cleanup_push(ebpf_fd_cleanup, ptr); heartbeat_t hb; heartbeat_init(&hb); ebpf_module_t *em = (ebpf_module_t *)ptr; usec_t step = NETDATA_FD_SLEEP_MS * em->update_every; - while (!close_ebpf_plugin) { + while (ebpf_fd_exited == NETDATA_THREAD_EBPF_RUNNING) { usec_t dt = heartbeat_next(&hb, step); (void)dt; + if (ebpf_fd_exited == NETDATA_THREAD_EBPF_STOPPING) + break; read_global_table(); } - read_thread_closed = 1; + ebpf_fd_exited = NETDATA_THREAD_EBPF_STOPPED; + + netdata_thread_cleanup_pop(1); return NULL; } @@ -652,17 +654,19 @@ static void fd_collector(ebpf_module_t *em) fd_thread.thread = mallocz(sizeof(netdata_thread_t)); fd_thread.start_routine = ebpf_fd_read_hash; - netdata_thread_create(fd_thread.thread, fd_thread.name, NETDATA_THREAD_OPTION_JOINABLE, + netdata_thread_create(fd_thread.thread, fd_thread.name, NETDATA_THREAD_OPTION_DEFAULT, ebpf_fd_read_hash, em); - int apps = em->apps_charts; int cgroups = em->cgroup_charts; heartbeat_t hb; heartbeat_init(&hb); usec_t step = em->update_every * USEC_PER_SEC; - while (!close_ebpf_plugin) { + while (!ebpf_exit_plugin) { (void)heartbeat_next(&hb, step); + if (ebpf_exit_plugin) + break; + netdata_apps_integration_flags_t apps = em->apps_charts; pthread_mutex_lock(&collect_data_mutex); if (apps) read_apps_table(); @@ -674,7 +678,7 @@ static void fd_collector(ebpf_module_t *em) ebpf_fd_send_data(em); - if (apps) + if (apps & NETDATA_EBPF_APPS_FLAG_CHART_CREATED) ebpf_fd_send_apps_data(em, apps_groups_root_target); if (cgroups) @@ -740,6 +744,8 @@ void ebpf_fd_create_apps_charts(struct ebpf_module *em, void *ptr) ebpf_algorithms[NETDATA_EBPF_INCREMENTAL_IDX], root, em->update_every, NETDATA_EBPF_MODULE_NAME_PROCESS); } + + em->apps_charts |= NETDATA_EBPF_APPS_FLAG_CHART_CREATED; } /** @@ -815,7 +821,7 @@ static void ebpf_fd_allocate_global_vectors(int apps) */ void *ebpf_fd_thread(void *ptr) { - netdata_thread_cleanup_push(ebpf_fd_cleanup, ptr); + netdata_thread_cleanup_push(ebpf_fd_exit, ptr); ebpf_module_t *em = (ebpf_module_t *)ptr; em->maps = fd_maps; @@ -825,8 +831,8 @@ void *ebpf_fd_thread(void *ptr) ebpf_fd_allocate_global_vectors(em->apps_charts); - probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &objects); - if (!probe_links) { + em->probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &em->objects); + if (!em->probe_links) { em->enabled = CONFIG_BOOLEAN_NO; goto endfd; } diff --git a/collectors/ebpf.plugin/ebpf_filesystem.c b/collectors/ebpf.plugin/ebpf_filesystem.c index 483690a804..bc767fbc93 100644 --- a/collectors/ebpf.plugin/ebpf_filesystem.c +++ b/collectors/ebpf.plugin/ebpf_filesystem.c @@ -30,67 +30,11 @@ static ebpf_local_maps_t fs_maps[] = {{.name = "tbl_ext4", .internal_input = NET .type = NETDATA_EBPF_MAP_CONTROLLER, .map_fd = ND_EBPF_MAP_FD_NOT_INITIALIZED}}; -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}, - {.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}, - {.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}, - {.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}, - {.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}, - {.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}}; - struct netdata_static_thread filesystem_threads = {"EBPF FS READ", NULL, NULL, 1, NULL, NULL, NULL }; +static enum ebpf_threads_status ebpf_fs_exited = NETDATA_THREAD_EBPF_RUNNING; -static int read_thread_closed = 1; static netdata_syscall_stat_t filesystem_aggregated_data[NETDATA_EBPF_HIST_MAX_BINS]; static netdata_publish_syscall_t filesystem_publish_aggregated[NETDATA_EBPF_HIST_MAX_BINS]; @@ -381,6 +325,7 @@ void ebpf_filesystem_cleanup_ebpf_data() bpf_link__destroy(probe_links[j]); j++; } + freez(probe_links); if (efp->objects) bpf_object__close(efp->objects); } @@ -388,24 +333,36 @@ void ebpf_filesystem_cleanup_ebpf_data() } /** - * Clean up the main thread. + * Filesystem exit + * + * Cancel child thread. * * @param ptr thread data. */ -static void ebpf_filesystem_cleanup(void *ptr) +static void ebpf_filesystem_exit(void *ptr) { ebpf_module_t *em = (ebpf_module_t *)ptr; - if (!em->enabled) + if (!em->enabled) { + em->enabled = NETDATA_MAIN_THREAD_EXITED; return; - - heartbeat_t hb; - heartbeat_init(&hb); - uint32_t tick = 2*USEC_PER_MS; - while (!read_thread_closed) { - usec_t dt = heartbeat_next(&hb, tick); - UNUSED(dt); } + ebpf_fs_exited = NETDATA_THREAD_EBPF_STOPPING; +} + +/** + * File system cleanup + * + * Clean up allocated thread. + * + * @param ptr thread data. + */ +static void ebpf_filesystem_cleanup(void *ptr) +{ + ebpf_module_t *em = (ebpf_module_t *)ptr; + if (ebpf_fs_exited != NETDATA_THREAD_EBPF_STOPPED) + return; + freez(filesystem_threads.thread); ebpf_cleanup_publish_syscall(filesystem_publish_aggregated); @@ -413,6 +370,9 @@ static void ebpf_filesystem_cleanup(void *ptr) if (dimensions) ebpf_histogram_dimension_cleanup(dimensions, NETDATA_EBPF_HIST_MAX_BINS); freez(filesystem_hash_values); + + filesystem_threads.enabled = NETDATA_MAIN_THREAD_EXITED; + em->enabled = NETDATA_MAIN_THREAD_EXITED; } /***************************************************************** @@ -516,16 +476,18 @@ static void read_filesystem_tables() */ void *ebpf_filesystem_read_hash(void *ptr) { + netdata_thread_cleanup_push(ebpf_filesystem_cleanup, ptr); ebpf_module_t *em = (ebpf_module_t *)ptr; - read_thread_closed = 0; heartbeat_t hb; heartbeat_init(&hb); usec_t step = NETDATA_FILESYSTEM_READ_SLEEP_MS * em->update_every; int update_every = em->update_every; - while (!close_ebpf_plugin) { + while (ebpf_fs_exited == NETDATA_THREAD_EBPF_RUNNING) { usec_t dt = heartbeat_next(&hb, step); (void)dt; + if (ebpf_fs_exited == NETDATA_THREAD_EBPF_STOPPING) + break; (void) ebpf_update_partitions(em); ebpf_obsolete_fs_charts(update_every); @@ -537,7 +499,9 @@ void *ebpf_filesystem_read_hash(void *ptr) read_filesystem_tables(); } - read_thread_closed = 1; + eb