diff options
Diffstat (limited to 'libnetdata/ebpf')
-rw-r--r-- | libnetdata/ebpf/ebpf.c | 99 | ||||
-rw-r--r-- | libnetdata/ebpf/ebpf.h | 25 |
2 files changed, 112 insertions, 12 deletions
diff --git a/libnetdata/ebpf/ebpf.c b/libnetdata/ebpf/ebpf.c index a9ff21f69..8619ae26f 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); +} diff --git a/libnetdata/ebpf/ebpf.h b/libnetdata/ebpf/ebpf.h index d4faccffd..ac3a1a2fc 100644 --- a/libnetdata/ebpf/ebpf.h +++ b/libnetdata/ebpf/ebpf.h @@ -8,6 +8,15 @@ #define NETDATA_DEBUGFS "/sys/kernel/debug/tracing/" +// Config files +#define EBPF_GLOBAL_SECTION "global" +#define EBPF_CFG_LOAD_MODE "ebpf load mode" +#define EBPF_CFG_LOAD_MODE_DEFAULT "entry" +#define EBPF_CFG_LOAD_MODE_RETURN "return" + +#define EBPF_CFG_UPDATE_EVERY "update every" +#define EBPF_CFG_APPLICATION "apps" + /** * The next magic number is got doing the following math: * 294960 = 4*65536 + 11*256 + 0 @@ -32,6 +41,13 @@ #define NETDATA_RH_8 2048 /** + * Kernel 5.11 + * + * 330240 = 5*65536 + 11*256 + */ +#define NETDATA_EBPF_KERNEL_5_11 330496 + +/** * Kernel 5.10 * * 330240 = 5*65536 + 10*256 @@ -62,6 +78,9 @@ #define VERSION_STRING_LEN 256 #define EBPF_KERNEL_REJECT_LIST_FILE "ebpf_kernel_reject_list.txt" +extern char *ebpf_user_config_dir; +extern char *ebpf_stock_config_dir; + typedef struct ebpf_data { int *map_fd; @@ -87,6 +106,7 @@ typedef struct ebpf_module { netdata_run_mode_t mode; uint32_t thread_id; int optional; + void (*apps_routine)(struct ebpf_module *em, void *ptr); } ebpf_module_t; #define NETDATA_MAX_PROBES 64 @@ -102,4 +122,9 @@ extern struct bpf_link **ebpf_load_program(char *plugins_dir, struct bpf_object **obj, int *map_fd); +extern void ebpf_mount_config_name(char *filename, size_t length, char *path, char *config); +extern int ebpf_load_config(struct config *config, char *filename); +extern void ebpf_update_module_using_config(ebpf_module_t *modules, struct config *cfg); +extern void ebpf_update_module(ebpf_module_t *em, struct config *cfg, char *cfg_file); + #endif /* NETDATA_EBPF_H */ |