From a1ff64efa6e2ba5ca94e035f3b3721740cbb3941 Mon Sep 17 00:00:00 2001 From: thiagoftsm Date: Wed, 4 Aug 2021 13:47:51 +0000 Subject: [PATCH] Split process and file descriptor (#246) --- includes/netdata_ebpf.h | 1 + includes/netdata_fd.h | 33 +++++++ includes/netdata_process.h | 10 --- kernel/Makefile | 1 + kernel/fd_kern.c | 180 +++++++++++++++++++++++++++++++++++++ kernel/process_kern.c | 138 +--------------------------- 6 files changed, 216 insertions(+), 147 deletions(-) create mode 100644 includes/netdata_fd.h create mode 100644 kernel/fd_kern.c diff --git a/includes/netdata_ebpf.h b/includes/netdata_ebpf.h index efd87a79..2077d5aa 100644 --- a/includes/netdata_ebpf.h +++ b/includes/netdata_ebpf.h @@ -15,6 +15,7 @@ This header has the common definitions for all `.c` files. #include "netdata_cache.h" #include "netdata_dc.h" #include "netdata_disk.h" +#include "netdata_fd.h" #include "netdata_fs.h" #include "netdata_mount.h" #include "netdata_network.h" diff --git a/includes/netdata_fd.h b/includes/netdata_fd.h new file mode 100644 index 00000000..4c40bbc8 --- /dev/null +++ b/includes/netdata_fd.h @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef _NETDATA_EBPF_FD_H_ +#define _NETDATA_EBPF_FD_H_ 1 + +#include + +struct netdata_fd_stat_t { + __u64 pid_tgid; //Unique identifier + __u32 pid; //process id + + //Counter + __u32 open_call; //open syscalls (open and openat) + __u32 close_call; //Close syscall (close) + + //Counter + __u32 open_err; + __u32 close_err; +}; + +enum fd_counters { + NETDATA_KEY_CALLS_DO_SYS_OPEN, + NETDATA_KEY_ERROR_DO_SYS_OPEN, + + NETDATA_KEY_CALLS_CLOSE_FD, + NETDATA_KEY_ERROR_CLOSE_FD, + + // Keep this as last and don't skip numbers as it is used as element counter + NETDATA_FD_COUNTER +}; + +#endif /* _NETDATA_EBPF_FD_H_ */ + diff --git a/includes/netdata_process.h b/includes/netdata_process.h index 22d13f1e..6dc39676 100644 --- a/includes/netdata_process.h +++ b/includes/netdata_process.h @@ -10,26 +10,19 @@ struct netdata_pid_stat_t { __u32 pid; //process id //Counter - __u32 open_call; //open syscalls (open and openat) __u32 exit_call; //Exit syscalls (exit for exit_group) __u32 release_call; //Exit syscalls (exit and exit_group) __u32 fork_call; //Start syscall (fork, clone, forkv) __u32 clone_call; //Start syscall (fork, clone, forkv) - __u32 close_call; //Close syscall (close) //Counter - __u32 open_err; __u32 fork_err; __u32 clone_err; - __u32 close_err; __u8 removeme; }; enum process_counters { - NETDATA_KEY_CALLS_DO_SYS_OPEN, - NETDATA_KEY_ERROR_DO_SYS_OPEN, - NETDATA_KEY_CALLS_DO_EXIT, NETDATA_KEY_CALLS_RELEASE_TASK, @@ -37,9 +30,6 @@ enum process_counters { NETDATA_KEY_CALLS_DO_FORK, NETDATA_KEY_ERROR_DO_FORK, - NETDATA_KEY_CALLS_CLOSE_FD, - NETDATA_KEY_ERROR_CLOSE_FD, - NETDATA_KEY_CALLS_SYS_CLONE, NETDATA_KEY_ERROR_SYS_CLONE, diff --git a/kernel/Makefile b/kernel/Makefile index a1af1493..f96a0e05 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -37,6 +37,7 @@ NETDATA_APPS= btrfs \ dc \ disk \ ext4 \ + fd \ fdatasync \ fsync \ mount \ diff --git a/kernel/fd_kern.c b/kernel/fd_kern.c new file mode 100644 index 00000000..c3d27ee3 --- /dev/null +++ b/kernel/fd_kern.c @@ -0,0 +1,180 @@ +#define KBUILD_MODNAME "fd_kern" +#include +#include +#include +#include +#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,10,17)) +# include +#endif + +#include +#include + +#include "bpf_helpers.h" +#include "netdata_ebpf.h" + +/************************************************************************************ + * + * MAPS Section + * + ***********************************************************************************/ + +struct bpf_map_def SEC("maps") tbl_fd_pid = { + .type = BPF_MAP_TYPE_HASH, + .key_size = sizeof(__u32), + .value_size = sizeof(struct netdata_fd_stat_t), + .max_entries = PID_MAX_DEFAULT +}; + +struct bpf_map_def SEC("maps") tbl_fd_global = { + .type = BPF_MAP_TYPE_PERCPU_ARRAY, + .key_size = sizeof(__u32), + .value_size = sizeof(__u64), + .max_entries = NETDATA_FD_COUNTER +}; + +struct bpf_map_def SEC("maps") fd_ctrl = { + .type = BPF_MAP_TYPE_ARRAY, + .key_size = sizeof(__u32), + .value_size = sizeof(__u32), + .max_entries = NETDATA_CONTROLLER_END +}; + +/************************************************************************************ + * + * Probe Section + * + ***********************************************************************************/ + +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(5,5,19)) +#if NETDATASEL < 2 +SEC("kretprobe/do_sys_open") +#else +SEC("kprobe/do_sys_open") +#endif +#else +#if NETDATASEL < 2 +SEC("kretprobe/do_sys_openat2") +#else +SEC("kprobe/do_sys_openat2") +#endif // Endif NETDATASEL +#endif //ENDIF KERNEL VERSION +int netdata_sys_open(struct pt_regs* ctx) +{ +#if NETDATASEL < 2 + int ret = (ssize_t)PT_REGS_RC(ctx); +#endif + struct netdata_fd_stat_t *fill; + struct netdata_fd_stat_t data = { }; + __u32 key = NETDATA_CONTROLLER_APPS_ENABLED; + + libnetdata_update_global(&tbl_fd_global, NETDATA_KEY_CALLS_DO_SYS_OPEN, 1); +#if NETDATASEL < 2 + if (ret < 0) { + libnetdata_update_global(&tbl_fd_global, NETDATA_KEY_ERROR_DO_SYS_OPEN, 1); + } +#endif + + __u32 *apps = bpf_map_lookup_elem(&fd_ctrl ,&key); + if (apps) + if (*apps == 0) + return 0; + + + __u64 pid_tgid = bpf_get_current_pid_tgid(); + key = (__u32)(pid_tgid >> 32); + __u32 tgid = (__u32)( 0x00000000FFFFFFFF & pid_tgid); + fill = bpf_map_lookup_elem(&tbl_fd_pid ,&key); + if (fill) { + libnetdata_update_u32(&fill->open_call, 1) ; + +#if NETDATASEL < 2 + if (ret < 0) { + libnetdata_update_u32(&fill->open_err, 1) ; + } +#endif + } else { + data.pid_tgid = pid_tgid; + data.pid = tgid; + +#if NETDATASEL < 2 + if (ret < 0) { + data.open_err = 1; + } else { +#endif + data.open_err = 0; +#if NETDATASEL < 2 + } +#endif + data.open_call = 1; + + bpf_map_update_elem(&tbl_fd_pid, &key, &data, BPF_ANY); + } + + return 0; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,11,0)) +#if NETDATASEL < 2 +SEC("kretprobe/close_fd") +#else +SEC("kprobe/close_fd") +#endif +#else +#if NETDATASEL < 2 +SEC("kretprobe/__close_fd") +#else +SEC("kprobe/__close_fd") +#endif +#endif +int netdata_close(struct pt_regs* ctx) +{ +#if NETDATASEL < 2 + int ret = (int)PT_REGS_RC(ctx); +#endif + __u32 key = NETDATA_CONTROLLER_APPS_ENABLED; + struct netdata_fd_stat_t data = { }; + struct netdata_fd_stat_t *fill; + + libnetdata_update_global(&tbl_fd_global, NETDATA_KEY_CALLS_CLOSE_FD, 1); +#if NETDATASEL < 2 + if (ret < 0) { + libnetdata_update_global(&tbl_fd_global, NETDATA_KEY_ERROR_CLOSE_FD, 1); + } +#endif + + __u32 *apps = bpf_map_lookup_elem(&fd_ctrl ,&key); + if (apps) + if (*apps == 0) + return 0; + + __u64 pid_tgid = bpf_get_current_pid_tgid(); + key = (__u32)(pid_tgid >> 32); + __u32 tgid = (__u32)( 0x00000000FFFFFFFF & pid_tgid); + fill = bpf_map_lookup_elem(&tbl_fd_pid ,&key); + if (fill) { + libnetdata_update_u32(&fill->close_call, 1) ; + +#if NETDATASEL < 2 + if (ret < 0) { + libnetdata_update_u32(&fill->close_err, 1) ; + } +#endif + } else { + data.pid_tgid = pid_tgid; + data.pid = tgid; + data.close_call = 1; +#if NETDATASEL < 2 + if (ret < 0) { + data.close_err = 1; + } +#endif + + bpf_map_update_elem(&tbl_fd_pid, &key, &data, BPF_ANY); + } + + return 0; +} + +char _license[] SEC("license") = "GPL"; + diff --git a/kernel/process_kern.c b/kernel/process_kern.c index 93542cd4..752be44b 100644 --- a/kernel/process_kern.c +++ b/kernel/process_kern.c @@ -69,87 +69,12 @@ static unsigned int log2l(unsigned long v) return log2(v); } -/************************************************************************************ - * - * FILE Section - * - ***********************************************************************************/ - -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(5,5,19)) -#if NETDATASEL < 2 -SEC("kretprobe/do_sys_open") -#else -SEC("kprobe/do_sys_open") -#endif -#else -#if NETDATASEL < 2 -SEC("kretprobe/do_sys_openat2") -#else -SEC("kprobe/do_sys_openat2") -#endif // Endif NETDATASEL -#endif //ENDIF KERNEL VERSION -int netdata_sys_open(struct pt_regs* ctx) -{ -#if NETDATASEL < 2 - int ret = (ssize_t)PT_REGS_RC(ctx); -#endif - struct netdata_pid_stat_t *fill; - struct netdata_pid_stat_t data = { }; - __u32 key = NETDATA_CONTROLLER_APPS_ENABLED; - - libnetdata_update_global(&tbl_total_stats, NETDATA_KEY_CALLS_DO_SYS_OPEN, 1); -#if NETDATASEL < 2 - if (ret < 0) { - libnetdata_update_global(&tbl_total_stats, NETDATA_KEY_ERROR_DO_SYS_OPEN, 1); - } -#endif - - __u32 *apps = bpf_map_lookup_elem(&process_ctrl ,&key); - if (apps) - if (*apps == 0) - return 0; - - - __u64 pid_tgid = bpf_get_current_pid_tgid(); - key = (__u32)(pid_tgid >> 32); - __u32 tgid = (__u32)( 0x00000000FFFFFFFF & pid_tgid); - fill = bpf_map_lookup_elem(&tbl_pid_stats ,&key); - if (fill) { - libnetdata_update_u32(&fill->open_call, 1) ; - -#if NETDATASEL < 2 - if (ret < 0) { - libnetdata_update_u32(&fill->open_err, 1) ; - } -#endif - } else { - data.pid_tgid = pid_tgid; - data.pid = tgid; - -#if NETDATASEL < 2 - if (ret < 0) { - data.open_err = 1; - } else { -#endif - data.open_err = 0; -#if NETDATASEL < 2 - } -#endif - data.open_call = 1; - - bpf_map_update_elem(&tbl_pid_stats, &key, &data, BPF_ANY); - } - - return 0; -} - /************************************************************************************ * * PROCESS Section * ***********************************************************************************/ - SEC("kprobe/do_exit") int netdata_sys_exit(struct pt_regs* ctx) { @@ -450,68 +375,6 @@ int netdata_sys_clone(struct pt_regs *ctx) #endif -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,11,0)) -#if NETDATASEL < 2 -SEC("kretprobe/close_fd") -#else -SEC("kprobe/close_fd") -#endif -#else -#if NETDATASEL < 2 -SEC("kretprobe/__close_fd") -#else -SEC("kprobe/__close_fd") -#endif -#endif -int netdata_close(struct pt_regs* ctx) -{ -#if NETDATASEL < 2 - int ret = (int)PT_REGS_RC(ctx); -#endif - __u32 key = NETDATA_CONTROLLER_APPS_ENABLED; - struct netdata_pid_stat_t data = { }; - struct netdata_pid_stat_t *fill; - - libnetdata_update_global(&tbl_total_stats, NETDATA_KEY_CALLS_CLOSE_FD, 1); -#if NETDATASEL < 2 - if (ret < 0) { - libnetdata_update_global(&tbl_total_stats, NETDATA_KEY_ERROR_CLOSE_FD, 1); - } -#endif - - __u32 *apps = bpf_map_lookup_elem(&process_ctrl ,&key); - if (apps) - if (*apps == 0) - return 0; - - __u64 pid_tgid = bpf_get_current_pid_tgid(); - key = (__u32)(pid_tgid >> 32); - __u32 tgid = (__u32)( 0x00000000FFFFFFFF & pid_tgid); - fill = bpf_map_lookup_elem(&tbl_pid_stats ,&key); - if (fill) { - libnetdata_update_u32(&fill->close_call, 1) ; - -#if NETDATASEL < 2 - if (ret < 0) { - libnetdata_update_u32(&fill->close_err, 1) ; - } -#endif - } else { - data.pid_tgid = pid_tgid; - data.pid = tgid; - data.close_call = 1; -#if NETDATASEL < 2 - if (ret < 0) { - data.close_err = 1; - } -#endif - - bpf_map_update_elem(&tbl_pid_stats, &key, &data, BPF_ANY); - } - - return 0; -} - SEC("kprobe/try_to_wake_up") int netdata_enter_try_to_wake_up(struct pt_regs* ctx) { @@ -534,3 +397,4 @@ int netdata_enter_try_to_wake_up(struct pt_regs* ctx) } char _license[] SEC("license") = "GPL"; +