summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--collectors/ebpf.plugin/README.md19
-rw-r--r--collectors/ebpf.plugin/ebpf.c58
-rw-r--r--collectors/ebpf.plugin/ebpf.d.conf11
-rw-r--r--collectors/ebpf.plugin/ebpf.d/fd.conf4
-rw-r--r--collectors/ebpf.plugin/ebpf.d/vfs.conf4
-rw-r--r--collectors/ebpf.plugin/ebpf.h4
-rw-r--r--collectors/ebpf.plugin/ebpf_cachestat.c31
-rw-r--r--collectors/ebpf.plugin/ebpf_dcstat.c31
-rw-r--r--collectors/ebpf.plugin/ebpf_fd.c331
-rw-r--r--collectors/ebpf.plugin/ebpf_fd.h1
-rw-r--r--collectors/ebpf.plugin/ebpf_mount.c2
-rw-r--r--collectors/ebpf.plugin/ebpf_shm.c47
-rw-r--r--collectors/ebpf.plugin/ebpf_socket.c2
-rw-r--r--collectors/ebpf.plugin/ebpf_swap.c34
-rw-r--r--collectors/ebpf.plugin/ebpf_sync.c2
-rw-r--r--collectors/ebpf.plugin/ebpf_vfs.c389
-rw-r--r--collectors/ebpf.plugin/ebpf_vfs.h17
-rw-r--r--libnetdata/ebpf/ebpf.c81
-rw-r--r--libnetdata/ebpf/ebpf.h15
-rw-r--r--packaging/ebpf-co-re.checksums2
-rw-r--r--packaging/ebpf-co-re.version2
-rw-r--r--packaging/ebpf.checksums6
-rw-r--r--packaging/ebpf.version2
23 files changed, 1018 insertions, 77 deletions
diff --git a/collectors/ebpf.plugin/README.md b/collectors/ebpf.plugin/README.md
index 550982ad29..7762ed34f7 100644
--- a/collectors/ebpf.plugin/README.md
+++ b/collectors/ebpf.plugin/README.md
@@ -137,6 +137,25 @@ If you do not need to monitor specific metrics for your `cgroups`, you can enabl
`ebpf.d.conf`, and then disable the plugin for a specific `thread` by following the steps in the
[Configuration](#configuring-ebpfplugin) section.
+#### Collect PID
+
+When one of the previous integrations is enabled, `ebpf.plugin` will use Process Identifier (`PID`) to identify the
+process group for which it needs to plot data.
+
+There are different ways to collect PID, and you can select the way `ebpf.plugin` collects data with the following
+values:
+
+- `real parent`: This is the default mode. Collection will aggregate data for the real parent, the thread that creates
+ child threads.
+- `parent`: Parent and real parent are the same when a process starts, but this value can be changed during run time.
+- `all`: This option will store all PIDs that run on the host. Note, this method can be expensive for the host,
+ because more memory needs to be allocated and parsed.
+
+The threads that have integration with other collectors have an internal clean up wherein they attach either a
+`trampoline` or a `kprobe` to `release_task` internal function. To avoid `overload` on this function, `ebpf.plugin`
+will only enable these threads integrated with other collectors when the kernel is compiled with
+`CONFIG_DEBUG_INFO_BTF`, unless you enable them manually.
+
#### Integration Dashboard Elements
When an integration is enabled, your dashboard will also show the following cgroups and apps charts using low-level
diff --git a/collectors/ebpf.plugin/ebpf.c b/collectors/ebpf.plugin/ebpf.c
index 0d69e5ca64..0e05e24da2 100644
--- a/collectors/ebpf.plugin/ebpf.c
+++ b/collectors/ebpf.plugin/ebpf.c
@@ -77,7 +77,7 @@ ebpf_module_t ebpf_modules[] = {
.load = EBPF_LOAD_LEGACY, .targets = dc_targets, .probe_links = NULL, .objects = NULL},
{ .thread_name = "swap", .config_name = "swap", .enabled = 0, .start_routine = ebpf_swap_thread,
.update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO,
- .apps_level = NETDATA_APPS_NOT_SET, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
+ .apps_level = NETDATA_APPS_LEVEL_REAL_PARENT, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
.apps_routine = ebpf_swap_create_apps_charts, .maps = NULL,
.pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &swap_config,
.config_file = NETDATA_DIRECTORY_SWAP_CONFIG_FILE,
@@ -85,12 +85,12 @@ ebpf_module_t ebpf_modules[] = {
.load = EBPF_LOAD_LEGACY, .targets = swap_targets, .probe_links = NULL, .objects = NULL},
{ .thread_name = "vfs", .config_name = "vfs", .enabled = 0, .start_routine = ebpf_vfs_thread,
.update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO,
- .apps_level = NETDATA_APPS_NOT_SET, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
+ .apps_level = NETDATA_APPS_LEVEL_REAL_PARENT, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
.apps_routine = ebpf_vfs_create_apps_charts, .maps = NULL,
.pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &vfs_config,
.config_file = NETDATA_DIRECTORY_VFS_CONFIG_FILE,
.kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4 | NETDATA_V5_14,
- .load = EBPF_LOAD_LEGACY, .targets = NULL, .probe_links = NULL, .objects = NULL},
+ .load = EBPF_LOAD_LEGACY, .targets = vfs_targets, .probe_links = NULL, .objects = NULL},
{ .thread_name = "filesystem", .config_name = "filesystem", .enabled = 0, .start_routine = ebpf_filesystem_thread,
.update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO,
.apps_level = NETDATA_APPS_NOT_SET, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
@@ -114,13 +114,13 @@ ebpf_module_t ebpf_modules[] = {
.load = EBPF_LOAD_LEGACY, .targets = mount_targets, .probe_links = NULL, .objects = NULL},
{ .thread_name = "fd", .config_name = "fd", .enabled = 0, .start_routine = ebpf_fd_thread,
.update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO,
- .apps_level = NETDATA_APPS_NOT_SET, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
+ .apps_level = NETDATA_APPS_LEVEL_REAL_PARENT, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
.apps_routine = ebpf_fd_create_apps_charts, .maps = NULL,
.pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &fd_config,
.config_file = NETDATA_FD_CONFIG_FILE,
.kernels = NETDATA_V3_10 | NETDATA_V4_14 | NETDATA_V4_16 | NETDATA_V4_18 | NETDATA_V5_4 | NETDATA_V5_11 |
NETDATA_V5_14,
- .load = EBPF_LOAD_LEGACY, .targets = NULL, .probe_links = NULL, .objects = NULL},
+ .load = EBPF_LOAD_LEGACY, .targets = fd_targets, .probe_links = NULL, .objects = NULL},
{ .thread_name = "hardirq", .config_name = "hardirq", .enabled = 0, .start_routine = ebpf_hardirq_thread,
.update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO,
.apps_level = NETDATA_APPS_NOT_SET, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
@@ -145,7 +145,7 @@ ebpf_module_t ebpf_modules[] = {
.load = EBPF_LOAD_LEGACY, .targets = NULL, .probe_links = NULL, .objects = NULL},
{ .thread_name = "shm", .config_name = "shm", .enabled = 0, .start_routine = ebpf_shm_thread,
.update_every = EBPF_DEFAULT_UPDATE_EVERY, .global_charts = 1, .apps_charts = NETDATA_EBPF_APPS_FLAG_NO,
- .apps_level = NETDATA_APPS_NOT_SET, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
+ .apps_level = NETDATA_APPS_LEVEL_ALL, .cgroup_charts = CONFIG_BOOLEAN_NO, .mode = MODE_ENTRY, .optional = 0,
.apps_routine = ebpf_shm_create_apps_charts, .maps = NULL,
.pid_map_size = ND_EBPF_DEFAULT_PID_SIZE, .names = NULL, .cfg = &shm_config,
.config_file = NETDATA_DIRECTORY_SHM_CONFIG_FILE,
@@ -314,6 +314,8 @@ ebpf_plugin_stats_t plugin_statistics = {.core = 0, .legacy = 0, .running = 0, .
#ifdef LIBBPF_MAJOR_VERSION
struct btf *default_btf = NULL;
+#else
+void *default_btf = NULL;
#endif
char *btf_path = NULL;
@@ -1263,35 +1265,28 @@ static void ebpf_update_table_size()
/**
* Set Load mode
*
- * @param load default load mode.
+ * @param origin specify the configuration file loaded
*/
-static inline void ebpf_set_load_mode(netdata_ebpf_load_mode_t load)
+static inline void ebpf_set_load_mode(netdata_ebpf_load_mode_t load, netdata_ebpf_load_mode_t origin)
{
-#ifdef LIBBPF_MAJOR_VERSION
- if (load == EBPF_LOAD_CORE || load == EBPF_LOAD_PLAY_DICE) {
- load = (!default_btf) ? EBPF_LOAD_LEGACY : EBPF_LOAD_CORE;
- }
-#else
- load = EBPF_LOAD_LEGACY;
-#endif
-
int i;
for (i = 0; ebpf_modules[i].thread_name; i++) {
- // TO DO: Use `load` variable after we change all threads.
- ebpf_modules[i].load = EBPF_LOAD_LEGACY; // load ;
+ ebpf_modules[i].load &= ~NETDATA_EBPF_LOAD_METHODS;
+ ebpf_modules[i].load |= load | origin ;
}
}
/**
* Update mode
*
- * @param str value read from configuration file.
+ * @param str value read from configuration file.
+ * @param origin specify the configuration file loaded
*/
-static inline void epbf_update_load_mode(char *str)
+static inline void epbf_update_load_mode(char *str, netdata_ebpf_load_mode_t origin)
{
netdata_ebpf_load_mode_t load = epbf_convert_string_to_load_mode(str);
- ebpf_set_load_mode(load);
+ ebpf_set_load_mode(load, origin);
}
/**
@@ -1299,9 +1294,11 @@ static inline void epbf_update_load_mode(char *str)
*
* @param disable_apps variable to store information related to apps.
* @param disable_cgroups variable to store information related to cgroups.
- * @param update_every value to overwrite the update frequency set by the server.
+ * @param update_every value to overwrite the update frequency set by the server.
+ * @param origin specify the configuration file loaded
*/
-static void read_collector_values(int *disable_apps, int *disable_cgroups, int update_every)
+static void read_collector_values(int *disable_apps, int *disable_cgroups,
+ int update_every, netdata_ebpf_load_mode_t origin)
{
// Read global section
char *value;
@@ -1323,7 +1320,7 @@ static void read_collector_values(int *disable_apps, int *disable_cgroups, int u
value = appconfig_get(&collector_config, EBPF_GLOBAL_SECTION, EBPF_CFG_TYPE_FORMAT, EBPF_CFG_DEFAULT_PROGRAM);
- epbf_update_load_mode(value);
+ epbf_update_load_mode(value, origin);
ebpf_update_interval(update_every);
@@ -1501,6 +1498,7 @@ static void read_collector_values(int *disable_apps, int *disable_cgroups, int u
static int load_collector_config(char *path, int *disable_apps, int *disable_cgroups, int update_every)
{
char lpath[4096];
+ netdata_ebpf_load_mode_t origin;
snprintf(lpath, 4095, "%s/%s", path, NETDATA_EBPF_CONFIG_FILE);
if (!appconfig_load(&collector_config, lpath, 0, NULL)) {
@@ -1508,9 +1506,11 @@ static int load_collector_config(char *path, int *disable_apps, int *disable_cgr
if (!appconfig_load(&collector_config, lpath, 0, NULL)) {
return -1;
}
- }
+ origin = EBPF_LOADED_FROM_STOCK;
+ } else
+ origin = EBPF_LOADED_FROM_USER;
- read_collector_values(disable_apps, disable_cgroups, update_every);
+ read_collector_values(disable_apps, disable_cgroups, update_every, origin);
return 0;
}
@@ -1554,7 +1554,7 @@ static inline void ebpf_load_thread_config()
{
int i;
for (i = 0; ebpf_modules[i].thread_name; i++) {
- ebpf_update_module(&ebpf_modules[i]);
+ ebpf_update_module(&ebpf_modules[i], default_btf);
}
}
@@ -1773,14 +1773,14 @@ static void ebpf_parse_args(int argc, char **argv)
break;
}
case EBPF_OPTION_LEGACY: {
- ebpf_set_load_mode(EBPF_LOAD_LEGACY);
+ ebpf_set_load_mode(EBPF_LOAD_LEGACY, EBPF_LOADED_FROM_USER);
#ifdef NETDATA_INTERNAL_CHECKS
info("EBPF running with \"LEGACY\" code, because it was started with the option \"[-]-legacy\".");
#endif
break;
}
case EBPF_OPTION_CORE: {
- ebpf_set_load_mode(EBPF_LOAD_CORE);
+ ebpf_set_load_mode(EBPF_LOAD_CORE, EBPF_LOADED_FROM_USER);
#ifdef NETDATA_INTERNAL_CHECKS
info("EBPF running with \"CO-RE\" code, because it was started with the option \"[-]-core\".");
#endif
diff --git a/collectors/ebpf.plugin/ebpf.d.conf b/collectors/ebpf.plugin/ebpf.d.conf
index aeba473edf..cf5c740fc1 100644
--- a/collectors/ebpf.plugin/ebpf.d.conf
+++ b/collectors/ebpf.plugin/ebpf.d.conf
@@ -26,16 +26,16 @@
#
# eBPF Programs
#
-# The eBPF collector enables and runs the following eBPF programs by default:
+# The eBPF collector has the following eBPF programs:
#
# `cachestat` : Make charts for kernel functions related to page cache.
# `dcstat` : Make charts for kernel functions related to directory cache.
# `disk` : Monitor I/O latencies for disks
# `fd` : This eBPF program creates charts that show information about file manipulation.
-# `mdflush` : Monitors flush counts for multi-devices.
-# `mount` : Monitor calls for syscalls mount and umount
# `filesystem`: Monitor calls for functions used to manipulate specific filesystems
# `hardirq` : Monitor latency of serving hardware interrupt requests (hard IRQs).
+# `mdflush` : Monitors flush counts for multi-devices.
+# `mount` : Monitor calls for syscalls mount and umount
# `oomkill` : This eBPF program creates a chart that shows which process got OOM killed and when.
# `process` : This eBPF program creates charts that show information about process life.
# `shm` : Monitor calls for syscalls shmget, shmat, shmdt and shmctl.
@@ -46,6 +46,9 @@
# `swap` : Monitor calls for internal swap functions.
# `vfs` : This eBPF program creates charts that show information about process VFS IO, VFS file manipulation and
# files removed.
+#
+# When plugin detects that system has support to BTF, it enables integration with apps.plugin.
+#
[ebpf programs]
cachestat = no
dcstat = no
@@ -57,7 +60,7 @@
mount = yes
oomkill = yes
process = yes
- shm = yes
+ shm = no
socket = yes
softirq = yes
sync = yes
diff --git a/collectors/ebpf.plugin/ebpf.d/fd.conf b/collectors/ebpf.plugin/ebpf.d/fd.conf
index f6edd3d938..8333520fcf 100644
--- a/collectors/ebpf.plugin/ebpf.d/fd.conf
+++ b/collectors/ebpf.plugin/ebpf.d/fd.conf
@@ -11,9 +11,11 @@
# The `pid table size` defines the maximum number of PIDs stored inside the hash table.
#
# Uncomment lines to define specific options for thread.
-#[global]
+[global]
# ebpf load mode = entry
# apps = yes
# cgroups = no
# update every = 10
# pid table size = 32768
+ ebpf type format = auto
+ ebpf co-re tracing = trampoline
diff --git a/collectors/ebpf.plugin/ebpf.d/vfs.conf b/collectors/ebpf.plugin/ebpf.d/vfs.conf
index a65e0acbc0..fa5d5b4e95 100644
--- a/collectors/ebpf.plugin/ebpf.d/vfs.conf
+++ b/collectors/ebpf.plugin/ebpf.d/vfs.conf
@@ -9,9 +9,11 @@
# the setting `apps` and `cgroups` to 'no'.
#
# Uncomment lines to define specific options for thread.
-#[global]
+[global]
# ebpf load mode = entry
# apps = yes
# cgroups = no
# update every = 10
# pid table size = 32768
+ ebpf type format = auto
+ ebpf co-re tracing = trampoline
diff --git a/collectors/ebpf.plugin/ebpf.h b/collectors/ebpf.plugin/ebpf.h
index c23ca332d9..899d3b7b7e 100644
--- a/collectors/ebpf.plugin/ebpf.h
+++ b/collectors/ebpf.plugin/ebpf.h
@@ -271,7 +271,11 @@ extern sem_t *shm_sem_ebpf_cgroup;
extern pthread_mutex_t mutex_cgroup_shm;
extern size_t all_pids_count;
extern ebpf_plugin_stats_t plugin_statistics;
+#ifdef LIBBPF_MAJOR_VERSION
extern struct btf *default_btf;
+#else
+extern void *default_btf;
+#endif
// Socket functions and variables
// Common functions
diff --git a/collectors/ebpf.plugin/ebpf_cachestat.c b/collectors/ebpf.plugin/ebpf_cachestat.c
index 57c424e53c..76b0385a50 100644
--- a/collectors/ebpf.plugin/ebpf_cachestat.c
+++ b/collectors/ebpf.plugin/ebpf_cachestat.c
@@ -67,6 +67,7 @@ static void ebpf_cachestat_disable_probe(struct cachestat_bpf *obj)
bpf_program__set_autoload(obj->progs.netdata_set_page_dirty_kprobe, false);
bpf_program__set_autoload(obj->progs.netdata_account_page_dirtied_kprobe, false);
bpf_program__set_autoload(obj->progs.netdata_mark_buffer_dirty_kprobe, false);
+ bpf_program__set_autoload(obj->progs.netdata_release_task_kprobe, false);
}
/*
@@ -105,6 +106,7 @@ static void ebpf_cachestat_disable_trampoline(struct cachestat_bpf *obj)
bpf_program__set_autoload(obj->progs.netdata_set_page_dirty_fentry, false);
bpf_program__set_autoload(obj->progs.netdata_account_page_dirtied_fentry, false);
bpf_program__set_autoload(obj->progs.netdata_mark_buffer_dirty_fentry, false);
+ bpf_program__set_autoload(obj->progs.netdata_release_task_fentry, false);
}
/*
@@ -156,6 +158,9 @@ static inline void netdata_set_trampoline_target(struct cachestat_bpf *obj)
bpf_program__set_attach_target(obj->progs.netdata_mark_buffer_dirty_fentry, 0,
cachestat_targets[NETDATA_KEY_CALLS_MARK_BUFFER_DIRTY].name);
+
+ bpf_program__set_attach_target(obj->progs.netdata_release_task_fentry, 0,
+ EBPF_COMMON_FNCT_CLEAN_UP);
}
/**
@@ -210,6 +215,13 @@ static int ebpf_cachestat_attach_probe(struct cachestat_bpf *obj)
if (ret)
return -1;
+ obj->links.netdata_release_task_kprobe = bpf_program__attach_kprobe(obj->progs.netdata_release_task_kprobe,
+ false,
+ EBPF_COMMON_FNCT_CLEAN_UP);
+ ret = libbpf_get_error(obj->links.netdata_release_task_kprobe);
+ if (ret)
+ return -1;
+
return 0;
}
@@ -242,6 +254,19 @@ static void ebpf_cachestat_set_hash_tables(struct cachestat_bpf *obj)
}
/**
+ * Disable Release Task
+ *
+ * Disable release task when apps is not enabled.
+ *
+ * @param obj is the main structure for bpf objects.
+ */
+static void ebpf_cachestat_disable_release_task(struct cachestat_bpf *obj)
+{
+ bpf_program__set_autoload(obj->progs.netdata_release_task_kprobe, false);
+ bpf_program__set_autoload(obj->progs.netdata_release_task_fentry, false);
+}
+
+/**
* Load and attach
*
* Load and attach the eBPF code in kernel.
@@ -268,6 +293,9 @@ static inline int ebpf_cachestat_load_and_attach(struct cachestat_bpf *obj, ebpf
ebpf_cachestat_adjust_map_size(obj, em);
+ if (!em->apps_charts && !em->cgroup_charts)
+ ebpf_cachestat_disable_release_task(obj);
+
int ret = cachestat_bpf__load(obj);
if (ret) {
return ret;
@@ -1227,7 +1255,8 @@ static void ebpf_cachestat_set_internal_value()
static int ebpf_cachestat_load_bpf(ebpf_module_t *em)
{
int ret = 0;
- if (em->load == EBPF_LOAD_LEGACY) {
+ ebpf_adjust_apps_cgroup(em, em->targets[NETDATA_KEY_CALLS_ADD_TO_PAGE_CACHE_LRU].mode);
+ if (em->load & EBPF_LOAD_LEGACY) {
em->probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &em->objects);
if (!em->probe_links) {
ret = -1;
diff --git a/collectors/ebpf.plugin/ebpf_dcstat.c b/collectors/ebpf.plugin/ebpf_dcstat.c
index 0cdae4e147..dc644a175a 100644
--- a/collectors/ebpf.plugin/ebpf_dcstat.c
+++ b/collectors/ebpf.plugin/ebpf_dcstat.c
@@ -65,6 +65,7 @@ static inline void ebpf_dc_disable_probes(struct dc_bpf *obj)
{
bpf_program__set_autoload(obj->progs.netdata_lookup_fast_kprobe, false);
bpf_program__set_autoload(obj->progs.netdata_d_lookup_kretprobe, false);
+ bpf_program__set_autoload(obj->progs.netdata_dcstat_release_task_kprobe, false);
}
/*
@@ -78,6 +79,7 @@ static inline void ebpf_dc_disable_trampoline(struct dc_bpf *obj)
{
bpf_program__set_autoload(obj->progs.netdata_lookup_fast_fentry, false);
bpf_program__set_autoload(obj->progs.netdata_d_lookup_fexit, false);
+ bpf_program__set_autoload(obj->progs.netdata_dcstat_release_task_fentry, false);
}
/**
@@ -94,6 +96,9 @@ static void ebpf_dc_set_trampoline_target(struct dc_bpf *obj)
bpf_program__set_attach_target(obj->progs.netdata_d_lookup_fexit, 0,
dc_targets[NETDATA_DC_TARGET_D_LOOKUP].name);
+
+ bpf_program__set_attach_target(obj->progs.netdata_dcstat_release_task_fentry, 0,
+ EBPF_COMMON_FNCT_CLEAN_UP);
}
/**
@@ -125,6 +130,13 @@ static int ebpf_dc_attach_probes(struct dc_bpf *obj)
if (ret)
return -1;
+ obj->links.netdata_dcstat_release_task_kprobe = bpf_program__attach_kprobe(obj->progs.netdata_dcstat_release_task_kprobe,
+ false,
+ EBPF_COMMON_FNCT_CLEAN_UP);
+ ret = libbpf_get_error(obj->links.netdata_dcstat_release_task_kprobe);
+ if (ret)
+ return -1;
+
return 0;
}
@@ -180,6 +192,19 @@ netdata_ebpf_program_loaded_t ebpf_dc_update_load(ebpf_module_t *em)
}
/**
+ * Disable Release Task
+ *
+ * Disable release task when apps is not enabled.
+ *
+ * @param obj is the main structure for bpf objects.
+ */
+static void ebpf_dc_disable_release_task(struct dc_bpf *obj)
+{
+ bpf_program__set_autoload(obj->progs.netdata_dcstat_release_task_kprobe, false);
+ bpf_program__set_autoload(obj->progs.netdata_dcstat_release_task_fentry, false);
+}
+
+/**
* Load and attach
*
* Load and attach the eBPF code in kernel.
@@ -202,6 +227,9 @@ static inline int ebpf_dc_load_and_attach(struct dc_bpf *obj, ebpf_module_t *em)
ebpf_dc_adjust_map_size(obj, em);
+ if (!em->apps_charts && !em->cgroup_charts)
+ ebpf_dc_disable_release_task(obj);
+
int ret = dc_bpf__load(obj);
if (ret) {
return ret;
@@ -1116,7 +1144,8 @@ static void ebpf_dcstat_allocate_global_vectors(int apps)
static int ebpf_dcstat_load_bpf(ebpf_module_t *em)
{
int ret = 0;
- if (em->load == EBPF_LOAD_LEGACY) {
+ ebpf_adjust_apps_cgroup(em, em->targets[NETDATA_DC_TARGET_LOOKUP_FAST].mode);
+ if (em->load & EBPF_LOAD_LEGACY) {
em->probe_links = ebpf_load_program(ebpf_plugin_dir, em, running_on_kernel, isrh, &em->objects);
if (!em->probe_links) {
ret = -1;
diff --git a/collectors/ebpf.plugin/ebpf_fd.c b/collectors/ebpf.plugin/ebpf_fd.c
index b4e577dad0..9ac14646a4 100644
--- a/collectors/ebpf.plugin/ebpf_fd.c
+++ b/collectors/ebpf.plugin/ebpf_fd.c
@@ -38,6 +38,286 @@ static netdata_idx_t *fd_values = NULL;
netdata_fd_stat_t *fd_vector = NULL;
netdata_fd_stat_t **fd_pid = NULL;
+netdata_ebpf_targets_t fd_targets[] = { {.name = "open", .mode = EBPF_LOAD_TRAMPOLINE},
+ {.name = "close", .mode = EBPF_LOAD_TRAMPOLINE},
+ {.name = NULL, .mode = EBPF_LOAD_TRAMPOLINE}};
+
+#ifdef LIBBPF_MAJOR_VERSION
+#include "includes/fd.skel.h" // BTF code
+
+static struct fd_bpf *bpf_obj = NULL;
+
+/**
+ * Disable probe
+ *
+ * Disable all probes to use exclusively another method.
+ *
+ * @param obj is the main structure for bpf objects
+*/
+static inline void ebpf_fd_disable_probes(struct fd_bpf *obj)
+{
+ bpf_program__set_autoload(obj->progs.netdata_sys_open_kprobe, false);
+ bpf_program__set_autoload(obj->progs.netdata_sys_open_kretprobe, false);
+ bpf_program__set_autoload(obj->progs.netdata_release_task_fd_kprobe, false);
+ if (running_on_kernel >= NETDATA_EBPF_KERNEL_5_11) {
+ bpf_program__set_autoload(obj->progs.netdata___close_fd_kretprobe, false);
+ bpf_program__set_autoload(obj->progs.netdata___close_fd_kprobe, false);
+ bpf_program__set_autoload(obj->progs.netdata_close_fd_kprobe, false);
+ } else {
+ bpf_program__set_autoload(obj->progs.netdata___close_fd_kprobe, false);
+ bpf_program__set_autoload(obj->progs.netdata_close_fd_kretprobe, false);
+ bpf_program__set_autoload(obj->progs.netdata_close_fd_kprobe, false);
+ }
+}
+
+/*
+ * Disable specific probe
+ *
+ * Disable probes according the kernel version
+ *
+ * @param obj is the main structure for bpf objects
+ */
+static inline void ebpf_disable_specific_probes(struct fd_bpf *obj)
+{
+ if (running_on_kernel >= NETDATA_EBPF_KERNEL_5_11) {
+ bpf_program__set_autoload(obj->progs.netdata___close_fd_kretprobe, false);
+ bpf_program__set_autoload(obj->progs.netdata___close_fd_kprobe, false);
+ } else {
+ bpf_program__set_autoload(obj->progs.netdata_close_fd_kretprobe, false);
+ bpf_program__set_autoload(obj->progs.netdata_close_fd_kprobe, false);
+ }
+}
+
+/*
+ * Disable trampoline
+ *
+ * Disable all trampoline to use exclusively another method.
+ *
+ * @param obj is the main structure for bpf objects.
+ */
+static inline void ebpf_disable_trampoline(struct fd_bpf *obj)
+{
+ bpf_program__set_autoload(obj->progs.netdata_sys_open_fentry, false);
+ bpf_program__set_autoload(obj->progs.netdata_sys_open_fexit, false);
+ bpf_program__set_autoload(obj->progs.netdata_close_fd_fentry, false);
+ bpf_program__set_autoload(obj->progs.netdata_close_fd_fexit, false);
+ bpf_program__set_autoload(obj->progs.netdata___close_fd_fentry, false);
+ bpf_program__set_autoload(obj->progs.netdata___close_fd_fexit, false);
+ bpf_program__set_autoload(obj->progs.netdata_release_task_fd_fentry, false);
+}
+
+/*
+ * Disable specific trampoline
+ *
+ * Disable trampoline according to kernel version.
+ *
+ * @param obj is the main structure for bpf objects.
+ */
+static inline void ebpf_disable_specific_trampoline(struct fd_bpf *obj)
+{
+ if (running_on_kernel >= NETDATA_EBPF_KERNEL_5_11) {
+ bpf_program__set_autoload(obj->progs.netdata___close_fd_fentry, false);
+ bpf_program__set_autoload(obj->progs.netdata___close_fd_fexit, false);
+ } else {
+ bpf_program__set_autoload(obj->progs.netdata_close_fd_fentry, false);
+ bpf_program__set_autoload(obj->progs.netdata_close_fd_fexit, 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 fd_bpf *obj)
+{
+ bpf_program__set_attach_target(obj->progs.netdata_sys_open_fentry, 0, fd_targets[NETDATA_FD_SYSCALL_OPEN].name);
+ bpf_program__set_attach_target(obj->progs.netdata_sys_open_fexit, 0, fd_targets[NETDATA_FD_SYSCALL_OPEN].name);
+ bpf_program__set_attach_target(obj->progs.netdata_release_task_fd_fentry, 0, EBPF_COMMON_FNCT_CLEAN_UP);
+
+ if (running_on_kernel >= NETDATA_EBPF_KERNEL_5_11) {
+ bpf_program__set_attach_target(
+ obj->progs.netdata_close_fd_fentry, 0, fd_targets[NETDATA_FD_SYSCALL_CLOSE].name);
+ bpf_program__set_attach_target(obj->progs.netdata_close_fd_fexit, 0, fd_targets[NETDATA_FD_SYSCALL_CLOSE].name);
+ } else {
+ bpf_program__set_attach_target(
+ obj->progs.netdata___close_fd_fentry, 0, fd_targets[NETDATA_FD_SYSCALL_CLOSE].name);
+ bpf_program__set_attach_target(
+ obj->progs.netdata___close_fd_fexit, 0, fd_targets[NETDATA_FD_SYSCALL_CLOSE].name);
+ }
+}
+
+/**
+ * Mount 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_fd_attach_probe(struct fd_bpf *obj)
+{
+ obj->links.netdata_sys_open_kprobe = bpf_program__attach_kprobe(obj->progs.netdata_sys_open_kprobe, false,
+ fd_targets[NETDATA_FD_SYSCALL_OPEN].name);
+ int ret = libbpf_get_error(obj->links.netdata_sys_open_kprobe);
+ if (ret)
+ return -1;
+
+ obj->links.netdata_sys_open_kretprobe = bpf_program__attach_kprobe(obj->progs.netdata_sys_open_kretprobe, true,
+ fd_targets[NETDATA_FD_SYSCALL_OPEN].name);
+ ret = libbpf_get_error(obj->links.netdata_sys_open_kretprobe);
+ if (ret)
+ return -1;
+
+ obj->links.netdata_release_task_fd_kprobe = bpf_program__attach_kprobe(obj->progs.netdata_release_task_fd_kprobe,
+ false,
+ EBPF_COMMON_FNCT_CLEAN_UP);
+ ret = libbpf_get_error(obj->links.netdata_release_task_fd_kprobe);
+ if (ret)
+ return -1;
+
+ if (running_on_kernel >= NETDATA_EBPF_KERNEL_5_11) {
+ obj->links.netdata_close_fd_kretprobe = bpf_program__attach_kprobe(obj->progs.netdata_close_fd_kretprobe, true,
+ fd_targets[NETDATA_FD_SYSCALL_CLOSE].name);
+ ret = libbpf_get_error(obj->links.netdata_close_fd_kretprobe);
+ if (ret)
+ return -1;
+
+ obj->links.netdata_close_fd_kprobe = bpf_program__attach_kprobe(obj->progs.netdata_close_fd_kprobe, false,
+ fd_targets[NETDATA_FD_SYSCALL_CLOSE].name);
+ ret = libbpf_get_error(obj->links.netdata_close_fd_kprobe);
+ if (ret)
+ return -1;
+ } else {
+ obj->links.netdata___close_fd_kretprobe = bpf_program__attach_kprobe(obj->progs.netdata___close_fd_kretprobe,
+ true,
+ fd_targets[NETDATA_FD_SYSCALL_CLOSE].name);
+ ret = libbpf_get_error(obj->links.netdata___close_fd_kretprobe);
+ if (ret)
+ return -1;
+
+ obj->links.netdata___close_fd_kprobe = bpf_program__attach_kprobe(obj->progs.netdata___close_fd_kprobe,
+ false,
+ fd_targets[NETDATA_FD_SYSCALL_CLOSE].name);
+ ret = libbpf_get_error(obj->links.netdata___close_fd_kprobe);
+ if (ret)
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * Set target values
+ *
+ * Set pointers used to laod data.
+ */
+static void ebpf_fd_set_target_values()
+{
+ static char *close_targets[] = {"close_fd", "__close_fd"};
+ static char *open_targets[] = {"do_sys_openat2", "do_sys_open"};
+ if (running_on_kernel >= NETDATA_EBPF_KERNEL_5_11) {
+ fd_targets[NETDATA_FD_SYSCALL_OPEN].name = open_targets[0];
+ fd_targets[NETDATA_FD_SYSCALL_CLOSE].name = close_targets[0];
+ } else {
+ fd_targets[NETDATA_FD_SYSCALL_OPEN].name = open_targets[1];
+ fd_targets[NETDATA_FD_SYSCALL_CLOSE].name = close_targets[1];
+ }
+}
+
+/**
+ * Set hash tables
+ *
+ * Set the values for maps according the value given by kernel.
+ *
+ * @param obj is the main structure for bpf objects.
+ */
+static void ebpf_fd_set_hash_tables(struct fd_bpf *obj)
+{
+ fd_maps[NETDATA_FD_GLOBAL_STATS].map_fd = bpf_map__fd(obj->maps.tbl_fd_global);
+ fd_maps[NETDATA_FD_PID_STATS].map_fd = bpf_map__fd(obj->maps.tbl_fd_pid);
+ fd_maps[NETDATA_FD_CONTROLLER].map_fd = bpf_map__fd(obj->maps.fd_ctrl);
+}
+
+/**
+ * Adjust Map Size
+ *
+ * Resize maps according input from users.
+ *
+ * @param obj is the main structure for bpf objects.
+ * @param em structure with configuration
+ */
+static void ebpf_fd_adjust_map_size(struct fd_bpf *obj, ebpf_module_t *em)
+{
+ ebpf_update_map_size(obj->maps.tbl_fd_pid, &fd_maps[NETDATA_FD_PID_STATS],
+ em, bpf_map__name(obj->maps.tbl_fd_pid));
+}
+
+/**
+ * Disable Release Task
+ *
+ * Disable release task when apps is not enabled.