summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2024-02-13 10:26:47 +0200
committerPaul Buetow <paul@buetow.org>2024-02-13 10:26:47 +0200
commita1b917899d564d681f0dce682583d951e0c8a3ae (patch)
treefa7a7594a5a855d4f5019543827f7a4e783e2d56
parente43fba8ef47a7a435809ebc09c799254c1c1fcf7 (diff)
collect enter and exit times of the syscall tracepoints
-rw-r--r--cmd/ioriotng/main.go16
-rw-r--r--ioriotng.bpf.c30
-rw-r--r--maps.bpf.h19
3 files changed, 49 insertions, 16 deletions
diff --git a/cmd/ioriotng/main.go b/cmd/ioriotng/main.go
index eb4d222..cf9c4a0 100644
--- a/cmd/ioriotng/main.go
+++ b/cmd/ioriotng/main.go
@@ -25,8 +25,8 @@ type openEvent struct {
FD int32
OpID int32
TID uint32
- EnterTime int64
- ExitTime int64
+ EnterTime uint64
+ ExitTime uint64
Filename [256]byte
Comm [16]byte
}
@@ -34,20 +34,22 @@ type openEvent struct {
func (e openEvent) String() string {
filename := e.Filename[:]
comm := e.Comm[:]
- return fmt.Sprintf("opId:%d tid:%v fd:%v filename:%s, comm:%s",
- e.OpID, e.TID, e.FD, string(filename), string(comm))
+ duration := (e.ExitTime - e.EnterTime) / 1000000000000.0
+ return fmt.Sprintf("%vms %v %v opId:%d tid:%v fd:%v filename:%s, comm:%s",
+ duration, e.ExitTime, e.EnterTime, e.OpID, e.TID, e.FD, string(filename), string(comm))
}
type fdEvent struct {
FD int32
OpID int32
TID uint32
- EnterTime int64
- ExitTime int64
+ EnterTime uint64
+ ExitTime uint64
}
func (e fdEvent) String() string {
- return fmt.Sprintf("opId:%d tid:%v fd:%v", e.OpID, e.TID, e.FD)
+ duration := (e.ExitTime - e.EnterTime) / 1000000000000.0
+ return fmt.Sprintf("%vms %v %v opId:%d tid:%v fd:%v", duration, e.ExitTime, e.EnterTime, e.OpID, e.TID, e.FD)
}
func resizeMap(module *bpf.Module, name string, size uint32) error {
diff --git a/ioriotng.bpf.c b/ioriotng.bpf.c
index d9b0f5a..8f39573 100644
--- a/ioriotng.bpf.c
+++ b/ioriotng.bpf.c
@@ -5,8 +5,6 @@
#include <bpf/bpf_helpers.h>
#include "maps.bpf.h"
-// TODO: Split out this file into several *.bpf.c programs.
-
// TODO: Make UID_FILTER configurable via a flag from the userland part.
// For now, this is set to my own user for development purposes.
#define UID_FILTER 1001
@@ -19,6 +17,7 @@ int handle_enter_open(struct trace_event_raw_sys_enter *ctx) {
u32 tid = bpf_get_current_pid_tgid();
struct open_event event = {
.op_id = OPEN,
+ .enter_time = bpf_ktime_get_ns(),
};
bpf_probe_read_user_str(event.filename, sizeof(event.filename), (void *)ctx->args[0]);
@@ -40,6 +39,7 @@ int handle_exit_open(struct trace_event_raw_sys_exit *ctx) {
return 0;
}
eventp->fd = ctx->ret;
+ eventp->exit_time = bpf_ktime_get_ns();
bpf_perf_event_output(ctx, &open_event_map, BPF_F_CURRENT_CPU, eventp, sizeof(struct open_event));
bpf_map_delete_elem(&open_event_temp_map, &tid);
@@ -52,7 +52,10 @@ int handle_enter_openat(struct trace_event_raw_sys_enter *ctx) {
return 0;
u32 tid = bpf_get_current_pid_tgid();
- struct open_event event = { .op_id = OPEN_AT };
+ struct open_event event = {
+ .op_id = OPEN_AT,
+ .enter_time = bpf_ktime_get_ns(),
+ };
bpf_probe_read_user_str(event.filename, sizeof(event.filename), (void *)ctx->args[1]);
bpf_get_current_comm(&event.comm, sizeof(event.comm));
@@ -75,12 +78,31 @@ int handle_enter_close(struct trace_event_raw_sys_enter *ctx) {
if ((bpf_get_current_uid_gid() & 0xFFFFFFFF) != UID_FILTER)
return 0;
+ u32 tid = bpf_get_current_pid_tgid();
struct fd_event event = {
.fd = (int)ctx->args[0],
.op_id = CLOSE,
.tid = bpf_get_current_pid_tgid(),
+ .enter_time = bpf_ktime_get_ns(),
};
- bpf_perf_event_output(ctx, &fd_event_map, BPF_F_CURRENT_CPU, &event, sizeof(struct fd_event));
+ bpf_map_update_elem(&fd_event_temp_map, &tid, &event, BPF_ANY);
+
+ return 0;
+}
+
+SEC("tracepoint/syscalls/sys_exit_close")
+int handle_exit_close(struct trace_event_raw_sys_enter *ctx) {
+ if ((bpf_get_current_uid_gid() & 0xFFFFFFFF) != UID_FILTER)
+ return 0;
+
+ u32 tid = bpf_get_current_pid_tgid();
+ struct open_event *eventp = bpf_map_lookup_elem(&fd_event_temp_map, &tid);
+ if (!eventp) {
+ return 0;
+ }
+ eventp->exit_time = bpf_ktime_get_ns();
+ bpf_perf_event_output(ctx, &fd_event_map, BPF_F_CURRENT_CPU, eventp, sizeof(struct fd_event));
+ bpf_map_delete_elem(&fd_event_temp_map, &tid);
return 0;
}
diff --git a/maps.bpf.h b/maps.bpf.h
index 3cdfe25..d0bcb2f 100644
--- a/maps.bpf.h
+++ b/maps.bpf.h
@@ -1,11 +1,13 @@
//+build ignore
+#define TEMP_MAP_SIZES 1024 // Adjust size as needed
+
struct open_event {
int fd;
int op_id;
u32 tid;
- long enter_time;
- long exit_time;
+ __u64 enter_time;
+ __u64 exit_time;
char filename[256];
char comm[16];
};
@@ -21,15 +23,15 @@ struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(key_size, sizeof(u32));
__uint(value_size, sizeof(struct open_event));
- __uint(max_entries, 128); // Adjust size as needed
+ __uint(max_entries, TEMP_MAP_SIZES);
} open_event_temp_map SEC(".maps");
struct fd_event {
int fd;
int op_id;
u32 tid;
- long enter_time;
- long exit_time;
+ __u64 enter_time;
+ __u64 exit_time;
};
struct {
@@ -38,3 +40,10 @@ struct {
__uint(value_size, sizeof(u32));
} fd_event_map SEC(".maps");
+// Map to temporarily store info from the enter tracepoinut for the exit one
+struct {
+ __uint(type, BPF_MAP_TYPE_HASH);
+ __uint(key_size, sizeof(u32));
+ __uint(value_size, sizeof(struct fd_event));
+ __uint(max_entries, TEMP_MAP_SIZES);
+} fd_event_temp_map SEC(".maps");