diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2021-03-31 12:58:11 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2021-03-31 12:58:11 +0000 |
commit | f99c4526d94d3e04124c5c48ab4a3da6ca53a458 (patch) | |
tree | a2ed8860030cc49f492b09b3222d593c65619800 /libnetdata/ebpf/ebpf.c | |
parent | Adding upstream version 1.29.3. (diff) | |
download | netdata-f99c4526d94d3e04124c5c48ab4a3da6ca53a458.tar.xz netdata-f99c4526d94d3e04124c5c48ab4a3da6ca53a458.zip |
Adding upstream version 1.30.0.upstream/1.30.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'libnetdata/ebpf/ebpf.c')
-rw-r--r-- | libnetdata/ebpf/ebpf.c | 99 |
1 files changed, 87 insertions, 12 deletions
diff --git a/libnetdata/ebpf/ebpf.c b/libnetdata/ebpf/ebpf.c index a9ff21f6..8619ae26 100644 --- a/libnetdata/ebpf/ebpf.c +++ b/libnetdata/ebpf/ebpf.c @@ -8,6 +8,9 @@ #include "../libnetdata.h" +char *ebpf_user_config_dir = CONFIG_DIR; +char *ebpf_stock_config_dir = LIBCONFIG_DIR; + /* static int clean_kprobe_event(FILE *out, char *filename, char *father_pid, netdata_ebpf_events_t *ptr) { @@ -97,7 +100,7 @@ int get_kernel_version(char *out, int size) return -1; move = patch; - while (*version && *version != '\n') + while (*version && *version != '\n' && *version != '-') *move++ = *version++; *move = '\0'; @@ -182,20 +185,26 @@ static int kernel_is_rejected() } char filename[FILENAME_MAX + 1]; - snprintfz(filename, FILENAME_MAX, "%s/%s", config_dir, EBPF_KERNEL_REJECT_LIST_FILE); + snprintfz(filename, FILENAME_MAX, "%s/ebpf.d/%s", config_dir, EBPF_KERNEL_REJECT_LIST_FILE); FILE *kernel_reject_list = fopen(filename, "r"); if (!kernel_reject_list) { - config_dir = getenv("NETDATA_STOCK_CONFIG_DIR"); - if (config_dir == NULL) { - config_dir = LIBCONFIG_DIR; - } - + // Keep this to have compatibility with old versions snprintfz(filename, FILENAME_MAX, "%s/%s", config_dir, EBPF_KERNEL_REJECT_LIST_FILE); kernel_reject_list = fopen(filename, "r"); - if (!kernel_reject_list) - return 0; + if (!kernel_reject_list) { + config_dir = getenv("NETDATA_STOCK_CONFIG_DIR"); + if (config_dir == NULL) { + config_dir = LIBCONFIG_DIR; + } + + snprintfz(filename, FILENAME_MAX, "%s/ebpf.d/%s", config_dir, EBPF_KERNEL_REJECT_LIST_FILE); + kernel_reject_list = fopen(filename, "r"); + + if (!kernel_reject_list) + return 0; + } } // Find if the kernel is in the reject list @@ -246,7 +255,9 @@ char *ebpf_kernel_suffix(int version, int isrh) else return "3.10"; } else { - if (version >= NETDATA_EBPF_KERNEL_5_10) + if (version >= NETDATA_EBPF_KERNEL_5_11) + return "5.11"; + else if (version >= NETDATA_EBPF_KERNEL_5_10) return "5.10"; else if (version >= NETDATA_EBPF_KERNEL_4_17) return "5.4"; @@ -294,8 +305,10 @@ struct bpf_link **ebpf_load_program(char *plugins_dir, ebpf_module_t *em, char * if (test < 0 || test > 127) return NULL; - snprintf(lpath, 4096, "%s/%s", plugins_dir, lname); - if (bpf_prog_load(lpath, BPF_PROG_TYPE_KPROBE, obj, &prog_fd)) { + snprintf(lpath, 4096, "%s/ebpf.d/%s", plugins_dir, lname); + // We are using BPF_PROG_TYPE_UNSPEC instead a specific type for bpf_prog_load to define the type + // according the eBPF program loaded + if (bpf_prog_load(lpath, BPF_PROG_TYPE_UNSPEC, obj, &prog_fd)) { em->enabled = CONFIG_BOOLEAN_NO; info("Cannot load program: %s", lpath); return NULL; @@ -322,3 +335,65 @@ struct bpf_link **ebpf_load_program(char *plugins_dir, ebpf_module_t *em, char * return links; } + +//---------------------------------------------------------------------------------------------------------------------- + +void ebpf_mount_config_name(char *filename, size_t length, char *path, char *config) +{ + snprintf(filename, length, "%s/ebpf.d/%s", path, config); +} + +int ebpf_load_config(struct config *config, char *filename) +{ + return appconfig_load(config, filename, 0, NULL); +} + + +static netdata_run_mode_t ebpf_select_mode(char *mode) +{ + if (!strcasecmp(mode, "return")) + return MODE_RETURN; + else if (!strcasecmp(mode, "dev")) + return MODE_DEVMODE; + + return MODE_ENTRY; +} + +void ebpf_update_module_using_config(ebpf_module_t *modules, struct config *cfg) +{ + char *mode = appconfig_get(cfg, EBPF_GLOBAL_SECTION, EBPF_CFG_LOAD_MODE, EBPF_CFG_LOAD_MODE_DEFAULT); + modules->mode = ebpf_select_mode(mode); + + modules->update_time = (int)appconfig_get_number(cfg, EBPF_GLOBAL_SECTION, EBPF_CFG_UPDATE_EVERY, 1); + + modules->apps_charts = appconfig_get_boolean(cfg, EBPF_GLOBAL_SECTION, EBPF_CFG_APPLICATION, + CONFIG_BOOLEAN_YES); +} + + +/** + * Update module + * + * When this function is called, it will load the configuration file and after this + * it updates the global information of ebpf_module. + * If the module has specific configuration, this function will load it, but it will not + * update the variables. + * + * @param em the module structure + * @param cfg the configuration structure + * @param cfg_file the filename to load + */ +void ebpf_update_module(ebpf_module_t *em, struct config *cfg, char *cfg_file) +{ + char filename[FILENAME_MAX+1]; + ebpf_mount_config_name(filename, FILENAME_MAX, ebpf_user_config_dir, cfg_file); + if (!ebpf_load_config(cfg, filename)) { + ebpf_mount_config_name(filename, FILENAME_MAX, ebpf_stock_config_dir, cfg_file); + if (!ebpf_load_config(cfg, filename)) { + error("Cannot load the ebpf configuration file %s", cfg_file); + return; + } + } + + ebpf_update_module_using_config(em, cfg); +} |