summaryrefslogtreecommitdiffstats
path: root/src/collectors/ebpf.plugin/ebpf_apps.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/collectors/ebpf.plugin/ebpf_apps.h')
-rw-r--r--src/collectors/ebpf.plugin/ebpf_apps.h304
1 files changed, 291 insertions, 13 deletions
diff --git a/src/collectors/ebpf.plugin/ebpf_apps.h b/src/collectors/ebpf.plugin/ebpf_apps.h
index a2cbaf3b7..98c9995da 100644
--- a/src/collectors/ebpf.plugin/ebpf_apps.h
+++ b/src/collectors/ebpf.plugin/ebpf_apps.h
@@ -39,10 +39,55 @@
#include "ebpf_swap.h"
#include "ebpf_vfs.h"
-#define EBPF_MAX_COMPARE_NAME 100
+#define EBPF_MAX_COMPARE_NAME 95
#define EBPF_MAX_NAME 100
-#define EBPF_CLEANUP_FACTOR 10
+#define EBPF_CLEANUP_FACTOR 2
+
+enum ebpf_pids_index {
+ EBPF_PIDS_PROCESS_IDX,
+ EBPF_PIDS_SOCKET_IDX,
+ EBPF_PIDS_CACHESTAT_IDX,
+ EBPF_PIDS_DCSTAT_IDX,
+ EBPF_PIDS_SWAP_IDX,
+ EBPF_PIDS_VFS_IDX,
+ EBPF_PIDS_FD_IDX,
+ EBPF_PIDS_SHM_IDX,
+
+ EBPF_PIDS_PROC_FILE,
+ EBPF_PIDS_END_IDX
+};
+
+extern int pids_fd[EBPF_PIDS_END_IDX];
+
+enum ebpf_main_index {
+ EBPF_MODULE_PROCESS_IDX,
+ EBPF_MODULE_SOCKET_IDX,
+ EBPF_MODULE_CACHESTAT_IDX,
+ EBPF_MODULE_SYNC_IDX,
+ EBPF_MODULE_DCSTAT_IDX,
+ EBPF_MODULE_SWAP_IDX,
+ EBPF_MODULE_VFS_IDX,
+ EBPF_MODULE_FILESYSTEM_IDX,
+ EBPF_MODULE_DISK_IDX,
+ EBPF_MODULE_MOUNT_IDX,
+ EBPF_MODULE_FD_IDX,
+ EBPF_MODULE_HARDIRQ_IDX,
+ EBPF_MODULE_SOFTIRQ_IDX,
+ EBPF_MODULE_OOMKILL_IDX,
+ EBPF_MODULE_SHM_IDX,
+ EBPF_MODULE_MDFLUSH_IDX,
+ EBPF_MODULE_FUNCTION_IDX,
+ /* THREADS MUST BE INCLUDED BEFORE THIS COMMENT */
+ EBPF_OPTION_ALL_CHARTS,
+ EBPF_OPTION_VERSION,
+ EBPF_OPTION_HELP,
+ EBPF_OPTION_GLOBAL_CHART,
+ EBPF_OPTION_RETURN_MODE,
+ EBPF_OPTION_LEGACY,
+ EBPF_OPTION_CORE,
+ EBPF_OPTION_UNITTEST
+};
// ----------------------------------------------------------------------------
// Structures used to read information from kernel ring
@@ -63,10 +108,21 @@ typedef struct ebpf_process_stat {
//Counter
uint32_t task_err;
-
- uint8_t removeme;
} ebpf_process_stat_t;
+typedef struct __attribute__((packed)) ebpf_publish_process {
+ uint64_t ct;
+
+ //Counter
+ uint32_t exit_call;
+ uint32_t release_call;
+ uint32_t create_process;
+ uint32_t create_thread;
+
+ //Counter
+ uint32_t task_err;
+} ebpf_publish_process_t;
+
// ----------------------------------------------------------------------------
// pid_stat
//
@@ -108,21 +164,246 @@ struct ebpf_target {
struct ebpf_target *target; // the one that will be reported to netdata
struct ebpf_target *next;
};
-
extern struct ebpf_target *apps_groups_default_target;
extern struct ebpf_target *apps_groups_root_target;
extern struct ebpf_target *users_root_target;
extern struct ebpf_target *groups_root_target;
+extern uint64_t collect_pids;
+
+// ebpf_pid_data
+typedef struct __attribute__((packed)) ebpf_pid_data {
+ uint32_t pid;
+ uint32_t ppid;
+ uint64_t thread_collecting;
+
+ char comm[EBPF_MAX_COMPARE_NAME + 1];
+ char *cmdline;
+
+ uint32_t has_proc_file;
+ uint32_t not_updated;
+ int children_count; // number of processes directly referencing this
+ int merged;
+ int sortlist; // higher numbers = top on the process tree
+
+ struct ebpf_target *target; // the one that will be reported to netdata
+ struct ebpf_pid_data *parent;
+ struct ebpf_pid_data *prev;
+ struct ebpf_pid_data *next;
+
+ netdata_publish_fd_stat_t *fd;
+ netdata_publish_swap_t *swap;
+ netdata_publish_shm_t *shm; // this has a leak issue
+ netdata_publish_dcstat_t *dc;
+ netdata_publish_vfs_t *vfs;
+ netdata_publish_cachestat_t *cachestat;
+ ebpf_publish_process_t *process;
+ ebpf_socket_publish_apps_t *socket;
+
+} ebpf_pid_data_t;
+
+extern ebpf_pid_data_t *ebpf_pids;
+extern ebpf_pid_data_t *ebpf_pids_link_list;
+extern size_t ebpf_all_pids_count;
+extern size_t ebpf_hash_table_pids_count;
+void ebpf_del_pid_entry(pid_t pid);
+
+static inline void *ebpf_cachestat_allocate_publish()
+{
+ ebpf_hash_table_pids_count++;
+ return callocz(1, sizeof(netdata_publish_cachestat_t));
+}
+
+static inline void ebpf_cachestat_release_publish(netdata_publish_cachestat_t *ptr)
+{
+ ebpf_hash_table_pids_count--;
+ freez(ptr);
+}
+
+static inline void *ebpf_dcallocate_publish()
+{
+ ebpf_hash_table_pids_count++;
+ return callocz(1, sizeof(netdata_publish_dcstat_t));
+}
+
+static inline void ebpf_dc_release_publish(netdata_publish_dcstat_t *ptr)
+{
+ ebpf_hash_table_pids_count--;
+ freez(ptr);
+}
+
+static inline void *ebpf_fd_allocate_publish()
+{
+ ebpf_hash_table_pids_count++;
+ return callocz(1, sizeof(netdata_publish_fd_stat_t));
+}
+
+static inline void ebpf_fd_release_publish(netdata_publish_fd_stat_t *ptr)
+{
+ ebpf_hash_table_pids_count--;
+ freez(ptr);
+}
+
+static inline void *ebpf_shm_allocate_publish()
+{
+ ebpf_hash_table_pids_count++;
+ return callocz(1, sizeof(netdata_publish_shm_t));
+}
+
+static inline void ebpf_shm_release_publish(netdata_publish_shm_t *ptr)
+{
+ ebpf_hash_table_pids_count--;
+ freez(ptr);
+}
+
+static inline void *ebpf_socket_allocate_publish()
+{
+ ebpf_hash_table_pids_count++;
+ return callocz(1, sizeof(ebpf_socket_publish_apps_t));
+}
+
+static inline void ebpf_socket_release_publish(ebpf_socket_publish_apps_t *ptr)
+{
+ ebpf_hash_table_pids_count--;
+ freez(ptr);
+}
+
+static inline void *ebpf_swap_allocate_publish_swap()
+{
+ ebpf_hash_table_pids_count++;
+ return callocz(1, sizeof(netdata_publish_swap_t));
+}
+
+static inline void ebpf_swap_release_publish(netdata_publish_swap_t *ptr)
+{
+ ebpf_hash_table_pids_count--;
+ freez(ptr);
+}
+
+static inline void *ebpf_vfs_allocate_publish()
+{
+ ebpf_hash_table_pids_count++;
+ return callocz(1, sizeof(netdata_publish_vfs_t));
+}
+
+static inline void ebpf_vfs_release_publish(netdata_publish_vfs_t *ptr)
+{
+ ebpf_hash_table_pids_count--;
+ freez(ptr);
+}
+
+static inline void *ebpf_process_allocate_publish()
+{
+ ebpf_hash_table_pids_count++;
+ return callocz(1, sizeof(ebpf_publish_process_t));
+}
+
+static inline void ebpf_process_release_publish(ebpf_publish_process_t *ptr)
+{
+ ebpf_hash_table_pids_count--;
+ freez(ptr);
+}
+
+static inline ebpf_pid_data_t *ebpf_get_pid_data(uint32_t pid, uint32_t tgid, char *name, uint32_t idx) {
+ ebpf_pid_data_t *ptr = &ebpf_pids[pid];
+ ptr->thread_collecting |= 1<<idx;
+ // The caller is getting data to work.
+ if (!name && idx != EBPF_PIDS_PROC_FILE)
+ return ptr;
+
+ if (ptr->pid == pid) {
+ return ptr;
+ }
+
+ ptr->pid = pid;
+ ptr->ppid = tgid;
+
+ if (name)
+ strncpyz(ptr->comm, name, EBPF_MAX_COMPARE_NAME);
+
+ if (likely(ebpf_pids_link_list))
+ ebpf_pids_link_list->prev = ptr;
+
+ ptr->next = ebpf_pids_link_list;
+ ebpf_pids_link_list = ptr;
+ if (idx == EBPF_PIDS_PROC_FILE) {
+ ebpf_all_pids_count++;
+ }
+
+ return ptr;
+}
+
+static inline void ebpf_release_pid_data(ebpf_pid_data_t *eps, int fd, uint32_t key, uint32_t idx)
+{
+ if (fd) {
+ bpf_map_delete_elem(fd, &key);
+ }
+ eps->thread_collecting &= ~(1<<idx);
+ if (!eps->thread_collecting && !eps->has_proc_file) {
+ ebpf_del_pid_entry((pid_t)key);
+ }
+}
+
+static inline void ebpf_reset_specific_pid_data(ebpf_pid_data_t *ptr)
+{
+ int idx;
+ uint32_t pid = ptr->pid;
+ for (idx = EBPF_PIDS_PROCESS_IDX; idx < EBPF_PIDS_PROC_FILE; idx++) {
+ if (!(ptr->thread_collecting & (1<<idx))) {
+ continue;
+ }
+ // Check if we still have the map loaded
+ int fd = pids_fd[idx];
+ if (fd <= STDERR_FILENO)
+ continue;
+
+ bpf_map_delete_elem(fd, &pid);
+ ebpf_hash_table_pids_count--;
+ void *clean;
+ switch (idx) {
+ case EBPF_PIDS_PROCESS_IDX:
+ clean = ptr->process;
+ break;
+ case EBPF_PIDS_SOCKET_IDX:
+ clean = ptr->socket;
+ break;
+ case EBPF_PIDS_CACHESTAT_IDX:
+ clean = ptr->cachestat;
+ break;
+ case EBPF_PIDS_DCSTAT_IDX:
+ clean = ptr->dc;
+ break;
+ case EBPF_PIDS_SWAP_IDX:
+ clean = ptr->swap;
+ break;
+ case EBPF_PIDS_VFS_IDX:
+ clean = ptr->vfs;
+ break;
+ case EBPF_PIDS_FD_IDX:
+ clean = ptr->fd;
+ break;
+ case EBPF_PIDS_SHM_IDX:
+ clean = ptr->shm;
+ break;
+ default:
+ clean = NULL;
+ }
+ freez(clean);
+ }
+
+ ebpf_del_pid_entry(pid);
+}
+
typedef struct ebpf_pid_stat {
- int32_t pid;
+ uint32_t pid;
+ uint64_t thread_collecting;
char comm[EBPF_MAX_COMPARE_NAME + 1];
char *cmdline;
uint32_t log_thrown;
// char state;
- int32_t ppid;
+ uint32_t ppid;
int children_count; // number of processes directly referencing this
unsigned char keep : 1; // 1 when we need to keep this process in memory even after it exited
@@ -199,8 +480,6 @@ static inline void debug_log_int(const char *fmt, ...)
// ----------------------------------------------------------------------------
// Exported variabled and functions
//
-extern struct ebpf_pid_stat **ebpf_all_pids;
-
int ebpf_read_apps_groups_conf(struct ebpf_target **apps_groups_default_target,
struct ebpf_target **apps_groups_root_target,
const char *path,
@@ -216,7 +495,7 @@ int ebpf_read_hash_table(void *ep, int fd, uint32_t pid);
int get_pid_comm(pid_t pid, size_t n, char *dest);
-void collect_data_for_all_processes(int tbl_pid_stats_fd, int maps_per_core);
+void collect_data_for_all_processes(int tbl_pid_stats_fd, int maps_per_core, uint32_t max_period);
void ebpf_process_apps_accumulator(ebpf_process_stat_t *out, int maps_per_core);
// The default value is at least 32 times smaller than maximum number of PIDs allowed on system,
@@ -227,8 +506,7 @@ void ebpf_process_apps_accumulator(ebpf_process_stat_t *out, int maps_per_core);
#define NETDATA_EBPF_ALLOC_MIN_ELEMENTS 256
// ARAL Sectiion
-extern void ebpf_aral_init(void);
-extern ebpf_pid_stat_t *ebpf_get_pid_entry(pid_t pid, pid_t tgid);
+void ebpf_aral_init(void);
extern ebpf_process_stat_t *process_stat_vector;
extern ARAL *ebpf_aral_vfs_pid;
@@ -240,7 +518,7 @@ extern ARAL *ebpf_aral_shm_pid;
void ebpf_shm_aral_init();
netdata_publish_shm_t *ebpf_shm_stat_get(void);
void ebpf_shm_release(netdata_publish_shm_t *stat);
-void ebpf_cleanup_exited_pids(int max);
+void ebpf_parse_proc_files();
// ARAL Section end