From 7f002c126d41c434df422804941bb254f13a913f Mon Sep 17 00:00:00 2001 From: thiagoftsm Date: Wed, 13 Jan 2021 15:02:20 +0000 Subject: [PATCH] New eBPF kernel (#10434) Bring support for kernel 5.10. --- collectors/ebpf.plugin/ebpf.c | 44 ++----------------- collectors/ebpf.plugin/ebpf.h | 6 --- .../ebpf.plugin/ebpf_kernel_reject_list.txt | 1 - collectors/ebpf.plugin/ebpf_process.c | 12 ----- collectors/ebpf.plugin/ebpf_socket.c | 16 +------ libnetdata/ebpf/ebpf.c | 15 ++++--- libnetdata/ebpf/ebpf.h | 14 +++--- netdata-installer.sh | 8 ++++ packaging/ebpf.checksums | 6 +-- packaging/ebpf.version | 2 +- web/gui/dashboard_info.js | 14 +++--- 11 files changed, 40 insertions(+), 98 deletions(-) diff --git a/collectors/ebpf.plugin/ebpf.c b/collectors/ebpf.plugin/ebpf.c index 6cd8b96aa4..56e084e973 100644 --- a/collectors/ebpf.plugin/ebpf.c +++ b/collectors/ebpf.plugin/ebpf.c @@ -75,43 +75,15 @@ pthread_mutex_t lock; pthread_mutex_t collect_data_mutex; pthread_cond_t collect_data_cond_var; -netdata_ebpf_events_t process_probes[] = { - { .type = 'r', .name = "vfs_write" }, - { .type = 'r', .name = "vfs_writev" }, - { .type = 'r', .name = "vfs_read" }, - { .type = 'r', .name = "vfs_readv" }, - { .type = 'r', .name = "do_sys_open" }, - { .type = 'r', .name = "vfs_unlink" }, - { .type = 'p', .name = "do_exit" }, - { .type = 'p', .name = "release_task" }, - { .type = 'r', .name = "_do_fork" }, - { .type = 'r', .name = "__close_fd" }, - { .type = 'p', .name = "try_to_wake_up" }, - { .type = 'r', .name = "__x64_sys_clone" }, - { .type = 0, .name = NULL } -}; - -netdata_ebpf_events_t socket_probes[] = { - { .type = 'p', .name = "tcp_cleanup_rbuf" }, - { .type = 'p', .name = "tcp_close" }, - { .type = 'p', .name = "udp_recvmsg" }, - { .type = 'r', .name = "udp_recvmsg" }, - { .type = 'r', .name = "udp_sendmsg" }, - { .type = 'p', .name = "do_exit" }, - { .type = 'p', .name = "tcp_sendmsg" }, - { .type = 'r', .name = "tcp_sendmsg" }, - { .type = 0, .name = NULL } -}; - ebpf_module_t ebpf_modules[] = { { .thread_name = "process", .config_name = "process", .enabled = 0, .start_routine = ebpf_process_thread, - .update_time = 1, .global_charts = 1, .apps_charts = 1, .mode = MODE_ENTRY, .probes = process_probes, + .update_time = 1, .global_charts = 1, .apps_charts = 1, .mode = MODE_ENTRY, .optional = 0 }, { .thread_name = "socket", .config_name = "socket", .enabled = 0, .start_routine = ebpf_socket_thread, - .update_time = 1, .global_charts = 1, .apps_charts = 1, .mode = MODE_ENTRY, .probes = socket_probes, + .update_time = 1, .global_charts = 1, .apps_charts = 1, .mode = MODE_ENTRY, .optional = 0 }, { .thread_name = NULL, .enabled = 0, .start_routine = NULL, .update_time = 1, - .global_charts = 0, .apps_charts = 1, .mode = MODE_ENTRY, .probes = NULL, + .global_charts = 0, .apps_charts = 1, .mode = MODE_ENTRY, .optional = 0 }, }; @@ -166,15 +138,6 @@ static void clean_ip_structure(ebpf_network_viewer_ip_list_t **clean) *clean = NULL; } -static void change_events() -{ - if (ebpf_modules[0].mode == MODE_ENTRY) - change_process_event(); - - if (ebpf_modules[1].mode == MODE_ENTRY) - change_socket_event(); -} - /** * Clean Loaded Events * @@ -1966,7 +1929,6 @@ int main(int argc, char **argv) {NULL , NULL, NULL, 0, NULL, NULL, NULL} }; - change_events(); //clean_loaded_events(); int i; diff --git a/collectors/ebpf.plugin/ebpf.h b/collectors/ebpf.plugin/ebpf.h index 51b88fe228..1f58229515 100644 --- a/collectors/ebpf.plugin/ebpf.h +++ b/collectors/ebpf.plugin/ebpf.h @@ -109,8 +109,6 @@ extern int ebpf_nprocs; extern int running_on_kernel; extern char *ebpf_plugin_dir; extern char kernel_string[64]; -extern netdata_ebpf_events_t process_probes[]; -extern netdata_ebpf_events_t socket_probes[]; extern pthread_mutex_t collect_data_mutex; extern pthread_cond_t collect_data_cond_var; @@ -193,8 +191,4 @@ extern uint32_t finalized_threads; #define EBPF_MAX_SYNCHRONIZATION_TIME 300 -// External functions -extern void change_socket_event(); -extern void change_process_event(); - #endif /* NETDATA_COLLECTOR_EBPF_H */ diff --git a/collectors/ebpf.plugin/ebpf_kernel_reject_list.txt b/collectors/ebpf.plugin/ebpf_kernel_reject_list.txt index 832be363b8..d56b216a9c 100644 --- a/collectors/ebpf.plugin/ebpf_kernel_reject_list.txt +++ b/collectors/ebpf.plugin/ebpf_kernel_reject_list.txt @@ -1,2 +1 @@ Ubuntu 4.18.0-13. -Ubuntu 4.18.0-25. diff --git a/collectors/ebpf.plugin/ebpf_process.c b/collectors/ebpf.plugin/ebpf_process.c index a6a4d38a0b..9a1d69c066 100644 --- a/collectors/ebpf.plugin/ebpf_process.c +++ b/collectors/ebpf.plugin/ebpf_process.c @@ -968,22 +968,10 @@ static void ebpf_process_allocate_global_vectors(size_t length) prev_apps_data = callocz((size_t)pid_max, sizeof(ebpf_process_publish_apps_t *)); } -void change_process_event() -{ - int i; - if (running_on_kernel < NETDATA_KERNEL_V5_3) - process_probes[EBPF_SYS_CLONE_IDX].name = NULL; - - for (i = 0; process_probes[i].name; i++) { - process_probes[i].type = 'p'; - } -} - static void change_syscalls() { static char *lfork = { "do_fork" }; process_id_names[7] = lfork; - process_probes[8].name = lfork; } /** diff --git a/collectors/ebpf.plugin/ebpf_socket.c b/collectors/ebpf.plugin/ebpf_socket.c index 2a3c01c61e..2f73cf4dd4 100644 --- a/collectors/ebpf.plugin/ebpf_socket.c +++ b/collectors/ebpf.plugin/ebpf_socket.c @@ -1851,24 +1851,12 @@ static void ebpf_socket_allocate_global_vectors(size_t length) outbound_vectors.plot = callocz(network_viewer_opt.max_dim, sizeof(netdata_socket_plot_t)); } -void change_socket_event() -{ - socket_probes[0].type = 'p'; - socket_probes[4].type = 'p'; - socket_probes[5].type = 'p'; - socket_probes[7].name = NULL; -} - /** * Set local function pointers, this function will never be compiled with static libraries */ -static void set_local_pointers(ebpf_module_t *em) +static void set_local_pointers() { map_fd = socket_data.map_fd; - - if (em->mode == MODE_ENTRY) { - change_socket_event(); - } } /** @@ -1926,7 +1914,7 @@ void *ebpf_socket_thread(void *ptr) goto endsocket; } - set_local_pointers(em); + set_local_pointers(); probe_links = ebpf_load_program(ebpf_plugin_dir, em, kernel_string, &objects, socket_data.map_fd); if (!probe_links) { pthread_mutex_unlock(&lock); diff --git a/libnetdata/ebpf/ebpf.c b/libnetdata/ebpf/ebpf.c index dfcbd7fcf5..a9ff21f693 100644 --- a/libnetdata/ebpf/ebpf.c +++ b/libnetdata/ebpf/ebpf.c @@ -242,16 +242,18 @@ char *ebpf_kernel_suffix(int version, int isrh) { if (isrh) { if (version >= NETDATA_EBPF_KERNEL_4_11) - return "4.18.0"; + return "4.18"; else - return "3.10.0"; + return "3.10"; } else { - if (version >= NETDATA_EBPF_KERNEL_4_17) - return "5.4.20"; + if (version >= NETDATA_EBPF_KERNEL_5_10) + return "5.10"; + else if (version >= NETDATA_EBPF_KERNEL_4_17) + return "5.4"; else if (version >= NETDATA_EBPF_KERNEL_4_15) - return "4.16.18"; + return "4.16"; else if (version >= NETDATA_EBPF_KERNEL_4_11) - return "4.14.171"; + return "4.14"; } return NULL; @@ -294,6 +296,7 @@ struct bpf_link **ebpf_load_program(char *plugins_dir, ebpf_module_t *em, char * snprintf(lpath, 4096, "%s/%s", plugins_dir, lname); if (bpf_prog_load(lpath, BPF_PROG_TYPE_KPROBE, obj, &prog_fd)) { + em->enabled = CONFIG_BOOLEAN_NO; info("Cannot load program: %s", lpath); return NULL; } else { diff --git a/libnetdata/ebpf/ebpf.h b/libnetdata/ebpf/ebpf.h index 379f2be45e..d4faccffd2 100644 --- a/libnetdata/ebpf/ebpf.h +++ b/libnetdata/ebpf/ebpf.h @@ -31,6 +31,13 @@ */ #define NETDATA_RH_8 2048 +/** + * Kernel 5.10 + * + * 330240 = 5*65536 + 10*256 + */ +#define NETDATA_EBPF_KERNEL_5_10 330240 + /** * Kernel 4.17 * @@ -55,11 +62,6 @@ #define VERSION_STRING_LEN 256 #define EBPF_KERNEL_REJECT_LIST_FILE "ebpf_kernel_reject_list.txt" -typedef struct netdata_ebpf_events { - char type; - char *name; -} netdata_ebpf_events_t; - typedef struct ebpf_data { int *map_fd; @@ -83,14 +85,12 @@ typedef struct ebpf_module { int global_charts; int apps_charts; netdata_run_mode_t mode; - netdata_ebpf_events_t *probes; uint32_t thread_id; int optional; } ebpf_module_t; #define NETDATA_MAX_PROBES 64 -extern int clean_kprobe_events(FILE *out, int pid, netdata_ebpf_events_t *ptr); extern int get_kernel_version(char *out, int size); extern int get_redhat_release(); extern int has_condition_to_run(int version); diff --git a/netdata-installer.sh b/netdata-installer.sh index 0474100acd..c11e1a7ec7 100755 --- a/netdata-installer.sh +++ b/netdata-installer.sh @@ -1608,6 +1608,14 @@ remove_old_ebpf() { echo >&2 "Renaming eBPF configuration file." mv "${NETDATA_PREFIX}/etc/netdata/ebpf_process.conf" "${NETDATA_PREFIX}/etc/netdata/ebpf.conf" fi + + # Added to remove eBPF programs with name pattern: NAME_VERSION.SUBVERSION.PATCH + if [ -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/pnetdata_ebpf_process.3.10.0.o" ]; then + echo >&2 "Removing old eBPF programs" + rm -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/rnetdata_ebpf"*.?.*.*.o + rm -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/pnetdata_ebpf"*.?.*.*.o + fi + } install_ebpf() { diff --git a/packaging/ebpf.checksums b/packaging/ebpf.checksums index 760e107d9b..9db8e7e4b5 100644 --- a/packaging/ebpf.checksums +++ b/packaging/ebpf.checksums @@ -1,3 +1,3 @@ -723fecc3a74065f724d4af2780674f5aeb7f0b968899abc9e171fca1623ecd2a netdata-kernel-collector-glibc-v0.5.2.tar.xz -f2110b1c149017c4a4f486e30d701731a5d12050345f9038c63c6dcc81d8e4d4 netdata-kernel-collector-musl-v0.5.2.tar.xz -6587a4aedf4e0f17d725c4b8cee1f9b9fdbca41f9cd4fe85e4abbfdc03f27465 netdata-kernel-collector-static-v0.5.2.tar.xz +bcc2e38754f277e84aefdb2760d7de2b32611576718234e1cecdb70a87e93497 netdata-kernel-collector-glibc-v0.5.4.tar.xz +912675155f438c9fdccc1e91c1423fa4bb914a9c7e2d7b843f551e053f4374eb netdata-kernel-collector-musl-v0.5.4.tar.xz +dd0f63895305c38669b512f9e95a75057340f04ea999c3ea3540cb18a893dc52 netdata-kernel-collector-static-v0.5.4.tar.xz diff --git a/packaging/ebpf.version b/packaging/ebpf.version index b0c2058e6b..8ea9cc1eb1 100644 --- a/packaging/ebpf.version +++ b/packaging/ebpf.version @@ -1 +1 @@ -v0.5.2 +v0.5.4 diff --git a/web/gui/dashboard_info.js b/web/gui/dashboard_info.js index 872a43a773..1f289ba0c2 100644 --- a/web/gui/dashboard_info.js +++ b/web/gui/dashboard_info.js @@ -1105,13 +1105,13 @@ netdataDashboard.context = { }, 'apps.file_open': { - info: 'Calls to the internal function do_sys_open, which is the common function called from' + + info: 'Calls to the internal function do_sys_open ( For kernels newer than 5.5.19 we add a kprobe to do_sys_openat2. ), which is the common function called from' + ' open(2) ' + ' and openat(2). ' }, 'apps.file_open_error': { - info: 'Failed calls to the internal function do_sys_open.' + info: 'Failed calls to the internal function do_sys_open ( For kernels newer than 5.5.19 we add a kprobe to do_sys_openat2. ).' }, 'apps.file_closed': { @@ -1152,11 +1152,11 @@ netdataDashboard.context = { }, 'apps.process_create': { - info: 'Calls to the function do_fork to create a new task, which is the common name used to define process and tasks inside the kernel. Netdata identifies the process by counting the number of calls to sys_clone that do not have the flag CLONE_THREAD set.' + info: 'Calls to either do_fork, or kernel_clone if you are running kernel newer than 5.9.16, to create a new task, which is the common name used to define process and tasks inside the kernel. Netdata identifies the process by counting the number of calls to sys_clone that do not have the flag CLONE_THREAD set.' }, 'apps.thread_create': { - info: 'Calls to the function do_fork to create a new task, which is the common name used to define process and tasks inside the kernel. Netdata identifies the threads by counting the number of calls to sys_clone that have the flag CLONE_THREAD set.' + info: 'Calls to either do_fork, or kernel_clone if you are running kernel newer than 5.9.16, to create a new task, which is the common name used to define process and tasks inside the kernel. Netdata identifies the threads by counting the number of calls to sys_clone that have the flag CLONE_THREAD set.' }, 'apps.task_close': { @@ -3297,7 +3297,7 @@ netdataDashboard.context = { 'ebpf.file_descriptor': { title : 'File access', - info: 'Calls for internal functions on Linux kernel. The open dimension is attached to the kernel internal function do_sys_open, which is the common function called from'+ + info: 'Calls for internal functions on Linux kernel. The open dimension is attached to the kernel internal function do_sys_open ( For kernels newer than 5.5.19 we add a kprobe to do_sys_openat2. ), which is the common function called from'+ ' open(2) ' + ' and openat(2). ' + ' The close dimension is attached to the function __close_fd, which is called from system call' + @@ -3306,7 +3306,7 @@ netdataDashboard.context = { 'ebpf.file_error': { title : 'File access error', - info: 'Failed calls to the kernel internal function do_sys_open, which is the common function called from'+ + info: 'Failed calls to the kernel internal function do_sys_open ( For kernels newer than 5.5.19 we add a kprobe to do_sys_openat2. ), which is the common function called from'+ ' open(2) ' + ' and openat(2). ' + ' The close dimension is attached to the function __close_fd, which is called from system call' + @@ -3335,7 +3335,7 @@ netdataDashboard.context = { 'ebpf.process_thread': { title : 'Task creation', - info: 'Number of times that the function do_fork is called to create a new task, which is the common name used to define process and tasks inside the kernel. Netdata identifies the threads by couting the number of calls for sys_clone that has the flag CLONE_THREAD set.' + info: 'Number of times that either do_fork, or kernel_clone if you are running kernel newer than 5.9.16, is called to create a new task, which is the common name used to define process and tasks inside the kernel. Netdata identifies the threads by couting the number of calls for sys_clone that has the flag CLONE_THREAD set.' }, 'ebpf.exit': {