From bb50acdcb8073654ea667b8c0272e335bd43f844 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 14 Apr 2022 20:12:14 +0200 Subject: Merging upstream version 1.34.0. Signed-off-by: Daniel Baumann --- collectors/ebpf.plugin/ebpf_shm.c | 243 +++++++++++++++++++++++++++++++++++++- 1 file changed, 240 insertions(+), 3 deletions(-) (limited to 'collectors/ebpf.plugin/ebpf_shm.c') diff --git a/collectors/ebpf.plugin/ebpf_shm.c b/collectors/ebpf.plugin/ebpf_shm.c index 0cfb3abdc..939741e75 100644 --- a/collectors/ebpf.plugin/ebpf_shm.c +++ b/collectors/ebpf.plugin/ebpf_shm.c @@ -41,6 +41,203 @@ static struct bpf_object *objects = NULL; struct netdata_static_thread shm_threads = {"SHM KERNEL", NULL, NULL, 1, NULL, NULL, NULL}; +netdata_ebpf_targets_t shm_targets[] = { {.name = "shmget", .mode = EBPF_LOAD_TRAMPOLINE}, + {.name = "shmat", .mode = EBPF_LOAD_TRAMPOLINE}, + {.name = "shmdt", .mode = EBPF_LOAD_TRAMPOLINE}, + {.name = "shmctl", .mode = EBPF_LOAD_TRAMPOLINE}, + {.name = NULL, .mode = EBPF_LOAD_TRAMPOLINE}}; + +#ifdef LIBBPF_MAJOR_VERSION +#include "includes/shm.skel.h" + +static struct shm_bpf *bpf_obj = NULL; + +/***************************************************************** + * + * BTF FUNCTIONS + * + *****************************************************************/ + +/* + * Disable tracepoint + * + * Disable all tracepoints to use exclusively another method. + * + * @param obj is the main structure for bpf objects. + */ +static void ebpf_shm_disable_tracepoint(struct shm_bpf *obj) +{ + bpf_program__set_autoload(obj->progs.netdata_syscall_shmget, false); + bpf_program__set_autoload(obj->progs.netdata_syscall_shmat, false); + bpf_program__set_autoload(obj->progs.netdata_syscall_shmdt, false); + bpf_program__set_autoload(obj->progs.netdata_syscall_shmctl, false); +} + +/* + * Disable probe + * + * Disable all probes to use exclusively another method. + * + * @param obj is the main structure for bpf objects. + */ +static void ebpf_disable_probe(struct shm_bpf *obj) +{ + bpf_program__set_autoload(obj->progs.netdata_shmget_probe, false); + bpf_program__set_autoload(obj->progs.netdata_shmat_probe, false); + bpf_program__set_autoload(obj->progs.netdata_shmdt_probe, false); + bpf_program__set_autoload(obj->progs.netdata_shmctl_probe, false); +} + +/* + * Disable trampoline + * + * Disable all trampoline to use exclusively another method. + * + * @param obj is the main structure for bpf objects. + */ +static void ebpf_disable_trampoline(struct shm_bpf *obj) +{ + bpf_program__set_autoload(obj->progs.netdata_shmget_fentry, false); + bpf_program__set_autoload(obj->progs.netdata_shmat_fentry, false); + bpf_program__set_autoload(obj->progs.netdata_shmdt_fentry, false); + bpf_program__set_autoload(obj->progs.netdata_shmctl_fentry, false); +} + +/** + * Set trampoline target + * + * Set the targets we will monitor. + * + * @param obj is the main structure for bpf objects. + */ +static void ebpf_set_trampoline_target(struct shm_bpf *obj) +{ + char syscall[NETDATA_EBPF_MAX_SYSCALL_LENGTH + 1]; + ebpf_select_host_prefix(syscall, NETDATA_EBPF_MAX_SYSCALL_LENGTH, + shm_targets[NETDATA_KEY_SHMGET_CALL].name, running_on_kernel); + + bpf_program__set_attach_target(obj->progs.netdata_shmget_fentry, 0, + syscall); + + ebpf_select_host_prefix(syscall, NETDATA_EBPF_MAX_SYSCALL_LENGTH, + shm_targets[NETDATA_KEY_SHMAT_CALL].name, running_on_kernel); + bpf_program__set_attach_target(obj->progs.netdata_shmat_fentry, 0, + syscall); + + ebpf_select_host_prefix(syscall, NETDATA_EBPF_MAX_SYSCALL_LENGTH, + shm_targets[NETDATA_KEY_SHMDT_CALL].name, running_on_kernel); + bpf_program__set_attach_target(obj->progs.netdata_shmdt_fentry, 0, + syscall); + + ebpf_select_host_prefix(syscall, NETDATA_EBPF_MAX_SYSCALL_LENGTH, + shm_targets[NETDATA_KEY_SHMCTL_CALL].name, running_on_kernel); + bpf_program__set_attach_target(obj->progs.netdata_shmctl_fentry, 0, + syscall); +} + +/** + * SHM Attach Probe + * + * Attach probes to target + * + * @param obj is the main structure for bpf objects. + * + * @return It returns 0 on success and -1 otherwise. + */ +static int ebpf_shm_attach_probe(struct shm_bpf *obj) +{ + char syscall[NETDATA_EBPF_MAX_SYSCALL_LENGTH + 1]; + ebpf_select_host_prefix(syscall, NETDATA_EBPF_MAX_SYSCALL_LENGTH, + shm_targets[NETDATA_KEY_SHMGET_CALL].name, running_on_kernel); + + obj->links.netdata_shmget_probe = bpf_program__attach_kprobe(obj->progs.netdata_shmget_probe, + false, syscall); + int ret = (int)libbpf_get_error(obj->links.netdata_shmget_probe); + if (ret) + return -1; + + ebpf_select_host_prefix(syscall, NETDATA_EBPF_MAX_SYSCALL_LENGTH, + shm_targets[NETDATA_KEY_SHMAT_CALL].name, running_on_kernel); + obj->links.netdata_shmat_probe = bpf_program__attach_kprobe(obj->progs.netdata_shmat_probe, + false, syscall); + ret = (int)libbpf_get_error(obj->links.netdata_shmat_probe); + if (ret) + return -1; + + ebpf_select_host_prefix(syscall, NETDATA_EBPF_MAX_SYSCALL_LENGTH, + shm_targets[NETDATA_KEY_SHMDT_CALL].name, running_on_kernel); + obj->links.netdata_shmdt_probe = bpf_program__attach_kprobe(obj->progs.netdata_shmdt_probe, + false, syscall); + ret = (int)libbpf_get_error(obj->links.netdata_shmdt_probe); + if (ret) + return -1; + + ebpf_select_host_prefix(syscall, NETDATA_EBPF_MAX_SYSCALL_LENGTH, + shm_targets[NETDATA_KEY_SHMCTL_CALL].name, running_on_kernel); + obj->links.netdata_shmctl_probe = bpf_program__attach_kprobe(obj->progs.netdata_shmctl_probe, + false, syscall); + ret = (int)libbpf_get_error(obj->links.netdata_shmctl_probe); + if (ret) + return -1; + + return 0; +} + +/** + * Set hash tables + * + * Set the values for maps according the value given by kernel. + */ +static void ebpf_shm_set_hash_tables(struct shm_bpf *obj) +{ + shm_maps[NETDATA_PID_SHM_TABLE].map_fd = bpf_map__fd(obj->maps.tbl_pid_shm); + shm_maps[NETDATA_SHM_CONTROLLER].map_fd = bpf_map__fd(obj->maps.shm_ctrl); + shm_maps[NETDATA_SHM_GLOBAL_TABLE].map_fd = bpf_map__fd(obj->maps.tbl_shm); +} + +/** + * Load and attach + * + * Load and attach the eBPF code in kernel. + * + * @param obj is the main structure for bpf objects. + * @param em structure with configuration + * + * @return it returns 0 on succes and -1 otherwise + */ +static inline int ebpf_shm_load_and_attach(struct shm_bpf *obj, ebpf_module_t *em) +{ + netdata_ebpf_targets_t *shmt = em->targets; + netdata_ebpf_program_loaded_t test = shmt[NETDATA_KEY_SHMGET_CALL].mode; + + // We are testing only one, because all will have the same behavior + if (test == EBPF_LOAD_TRAMPOLINE ) { + ebpf_shm_disable_tracepoint(obj); + ebpf_disable_probe(obj); + + ebpf_set_trampoline_target(obj); + } else if (test == EBPF_LOAD_PROBE || test == EBPF_LOAD_RETPROBE ) { + ebpf_shm_disable_tracepoint(obj); + ebpf_disable_trampoline(obj); + } else { + ebpf_disable_probe(obj); + ebpf_disable_trampoline(obj); + } + + int ret = shm_bpf__load(obj); + if (!ret) { + if (test != EBPF_LOAD_PROBE && test != EBPF_LOAD_RETPROBE) + shm_bpf__attach(obj); + else + ret = ebpf_shm_attach_probe(obj); + + if (!ret) + ebpf_shm_set_hash_tables(obj); + } + + return ret; +} +#endif /***************************************************************** * FUNCTIONS TO CLOSE THE THREAD *****************************************************************/ @@ -91,6 +288,10 @@ static void ebpf_shm_cleanup(void *ptr) } bpf_object__close(objects); } +#ifdef LIBBPF_MAJOR_VERSION + else if (bpf_obj) + shm_bpf__destroy(bpf_obj); +#endif } /***************************************************************** @@ -787,7 +988,7 @@ static void ebpf_create_shm_charts(int update_every) ebpf_create_chart( NETDATA_EBPF_SYSTEM_GROUP, NETDATA_SHM_GLOBAL_CHART, - "Calls to shared memory system calls.", + "Calls to shared memory system calls", EBPF_COMMON_DIMENSION_CALL, NETDATA_SYSTEM_IPC_SHM_SUBMENU, NULL, @@ -802,6 +1003,40 @@ static void ebpf_create_shm_charts(int update_every) fflush(stdout); } +/* + * Load BPF + * + * Load BPF files. + * + * @param em the structure with configuration + */ +static int ebpf_shm_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->enabled = CONFIG_BOOLEAN_NO; + ret = -1; + } + } +#ifdef LIBBPF_MAJOR_VERSION + else { + bpf_obj = shm_bpf__open(); + if (!bpf_obj) + ret = -1; + else + ret = ebpf_shm_load_and_attach(bpf_obj, em); + } +#endif + + + if (ret) + error("%s %s", EBPF_DEFAULT_ERROR_MSG, em->thread_name); + + return ret; +} + /** * Shared memory thread. * @@ -821,8 +1056,10 @@ void *ebpf_shm_thread(void *ptr) goto endshm; } - probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &objects); - if (!probe_links) { +#ifdef LIBBPF_MAJOR_VERSION + ebpf_adjust_thread_load(em, default_btf); +#endif + if (ebpf_shm_load_bpf(em)) { em->enabled = CONFIG_BOOLEAN_NO; goto endshm; } -- cgit v1.2.3