Skip to content

Commit

Permalink
Split process and file descriptor (#246)
Browse files Browse the repository at this point in the history
  • Loading branch information
thiagoftsm authored Aug 4, 2021
1 parent 16ef676 commit a1ff64e
Show file tree
Hide file tree
Showing 6 changed files with 216 additions and 147 deletions.
1 change: 1 addition & 0 deletions includes/netdata_ebpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ This header has the common definitions for all `.c` files.
#include "netdata_cache.h"
#include "netdata_dc.h"
#include "netdata_disk.h"
#include "netdata_fd.h"
#include "netdata_fs.h"
#include "netdata_mount.h"
#include "netdata_network.h"
Expand Down
33 changes: 33 additions & 0 deletions includes/netdata_fd.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// SPDX-License-Identifier: GPL-3.0-or-later

#ifndef _NETDATA_EBPF_FD_H_
#define _NETDATA_EBPF_FD_H_ 1

#include <linux/sched.h>

struct netdata_fd_stat_t {
__u64 pid_tgid; //Unique identifier
__u32 pid; //process id

//Counter
__u32 open_call; //open syscalls (open and openat)
__u32 close_call; //Close syscall (close)

//Counter
__u32 open_err;
__u32 close_err;
};

enum fd_counters {
NETDATA_KEY_CALLS_DO_SYS_OPEN,
NETDATA_KEY_ERROR_DO_SYS_OPEN,

NETDATA_KEY_CALLS_CLOSE_FD,
NETDATA_KEY_ERROR_CLOSE_FD,

// Keep this as last and don't skip numbers as it is used as element counter
NETDATA_FD_COUNTER
};

#endif /* _NETDATA_EBPF_FD_H_ */

10 changes: 0 additions & 10 deletions includes/netdata_process.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,36 +10,26 @@ struct netdata_pid_stat_t {
__u32 pid; //process id

//Counter
__u32 open_call; //open syscalls (open and openat)
__u32 exit_call; //Exit syscalls (exit for exit_group)
__u32 release_call; //Exit syscalls (exit and exit_group)
__u32 fork_call; //Start syscall (fork, clone, forkv)
__u32 clone_call; //Start syscall (fork, clone, forkv)
__u32 close_call; //Close syscall (close)

//Counter
__u32 open_err;
__u32 fork_err;
__u32 clone_err;
__u32 close_err;

__u8 removeme;
};

enum process_counters {
NETDATA_KEY_CALLS_DO_SYS_OPEN,
NETDATA_KEY_ERROR_DO_SYS_OPEN,

NETDATA_KEY_CALLS_DO_EXIT,

NETDATA_KEY_CALLS_RELEASE_TASK,

NETDATA_KEY_CALLS_DO_FORK,
NETDATA_KEY_ERROR_DO_FORK,

NETDATA_KEY_CALLS_CLOSE_FD,
NETDATA_KEY_ERROR_CLOSE_FD,

NETDATA_KEY_CALLS_SYS_CLONE,
NETDATA_KEY_ERROR_SYS_CLONE,

Expand Down
1 change: 1 addition & 0 deletions kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ NETDATA_APPS= btrfs \
dc \
disk \
ext4 \
fd \
fdatasync \
fsync \
mount \
Expand Down
180 changes: 180 additions & 0 deletions kernel/fd_kern.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
#define KBUILD_MODNAME "fd_kern"
#include <linux/bpf.h>
#include <linux/version.h>
#include <linux/ptrace.h>
#include <linux/sched.h>
#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,10,17))
# include <linux/sched/task.h>
#endif

#include <linux/threads.h>
#include <linux/version.h>

#include "bpf_helpers.h"
#include "netdata_ebpf.h"

/************************************************************************************
*
* MAPS Section
*
***********************************************************************************/

struct bpf_map_def SEC("maps") tbl_fd_pid = {
.type = BPF_MAP_TYPE_HASH,
.key_size = sizeof(__u32),
.value_size = sizeof(struct netdata_fd_stat_t),
.max_entries = PID_MAX_DEFAULT
};

struct bpf_map_def SEC("maps") tbl_fd_global = {
.type = BPF_MAP_TYPE_PERCPU_ARRAY,
.key_size = sizeof(__u32),
.value_size = sizeof(__u64),
.max_entries = NETDATA_FD_COUNTER
};

struct bpf_map_def SEC("maps") fd_ctrl = {
.type = BPF_MAP_TYPE_ARRAY,
.key_size = sizeof(__u32),
.value_size = sizeof(__u32),
.max_entries = NETDATA_CONTROLLER_END
};

/************************************************************************************
*
* Probe Section
*
***********************************************************************************/

#if (LINUX_VERSION_CODE <= KERNEL_VERSION(5,5,19))
#if NETDATASEL < 2
SEC("kretprobe/do_sys_open")
#else
SEC("kprobe/do_sys_open")
#endif
#else
#if NETDATASEL < 2
SEC("kretprobe/do_sys_openat2")
#else
SEC("kprobe/do_sys_openat2")
#endif // Endif NETDATASEL
#endif //ENDIF KERNEL VERSION
int netdata_sys_open(struct pt_regs* ctx)
{
#if NETDATASEL < 2
int ret = (ssize_t)PT_REGS_RC(ctx);
#endif
struct netdata_fd_stat_t *fill;
struct netdata_fd_stat_t data = { };
__u32 key = NETDATA_CONTROLLER_APPS_ENABLED;

libnetdata_update_global(&tbl_fd_global, NETDATA_KEY_CALLS_DO_SYS_OPEN, 1);
#if NETDATASEL < 2
if (ret < 0) {
libnetdata_update_global(&tbl_fd_global, NETDATA_KEY_ERROR_DO_SYS_OPEN, 1);
}
#endif

__u32 *apps = bpf_map_lookup_elem(&fd_ctrl ,&key);
if (apps)
if (*apps == 0)
return 0;


__u64 pid_tgid = bpf_get_current_pid_tgid();
key = (__u32)(pid_tgid >> 32);
__u32 tgid = (__u32)( 0x00000000FFFFFFFF & pid_tgid);
fill = bpf_map_lookup_elem(&tbl_fd_pid ,&key);
if (fill) {
libnetdata_update_u32(&fill->open_call, 1) ;

#if NETDATASEL < 2
if (ret < 0) {
libnetdata_update_u32(&fill->open_err, 1) ;
}
#endif
} else {
data.pid_tgid = pid_tgid;
data.pid = tgid;

#if NETDATASEL < 2
if (ret < 0) {
data.open_err = 1;
} else {
#endif
data.open_err = 0;
#if NETDATASEL < 2
}
#endif
data.open_call = 1;

bpf_map_update_elem(&tbl_fd_pid, &key, &data, BPF_ANY);
}

return 0;
}

#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,11,0))
#if NETDATASEL < 2
SEC("kretprobe/close_fd")
#else
SEC("kprobe/close_fd")
#endif
#else
#if NETDATASEL < 2
SEC("kretprobe/__close_fd")
#else
SEC("kprobe/__close_fd")
#endif
#endif
int netdata_close(struct pt_regs* ctx)
{
#if NETDATASEL < 2
int ret = (int)PT_REGS_RC(ctx);
#endif
__u32 key = NETDATA_CONTROLLER_APPS_ENABLED;
struct netdata_fd_stat_t data = { };
struct netdata_fd_stat_t *fill;

libnetdata_update_global(&tbl_fd_global, NETDATA_KEY_CALLS_CLOSE_FD, 1);
#if NETDATASEL < 2
if (ret < 0) {
libnetdata_update_global(&tbl_fd_global, NETDATA_KEY_ERROR_CLOSE_FD, 1);
}
#endif

__u32 *apps = bpf_map_lookup_elem(&fd_ctrl ,&key);
if (apps)
if (*apps == 0)
return 0;

__u64 pid_tgid = bpf_get_current_pid_tgid();
key = (__u32)(pid_tgid >> 32);
__u32 tgid = (__u32)( 0x00000000FFFFFFFF & pid_tgid);
fill = bpf_map_lookup_elem(&tbl_fd_pid ,&key);
if (fill) {
libnetdata_update_u32(&fill->close_call, 1) ;

#if NETDATASEL < 2
if (ret < 0) {
libnetdata_update_u32(&fill->close_err, 1) ;
}
#endif
} else {
data.pid_tgid = pid_tgid;
data.pid = tgid;
data.close_call = 1;
#if NETDATASEL < 2
if (ret < 0) {
data.close_err = 1;
}
#endif

bpf_map_update_elem(&tbl_fd_pid, &key, &data, BPF_ANY);
}

return 0;
}

char _license[] SEC("license") = "GPL";

Loading

0 comments on commit a1ff64e

Please sign in to comment.