summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2025-03-07 21:27:32 +0200
committerPaul Buetow <paul@buetow.org>2025-03-07 21:27:32 +0200
commit527a001b458384cc81fe74314e3ceb765c6a6130 (patch)
treee2f5762d121f35a1118cbd31180b7a9a1b3d152c
parent4460a68aa299ad6b63ffbbbb23585b93fad9feee (diff)
add ior stuff
-rw-r--r--assets/ior-small.pngbin0 -> 46683 bytes
-rw-r--r--assets/ior.pngbin0 -> 951451 bytes
-rw-r--r--assets/ior.xcfbin0 -> 1944490 bytes
-rw-r--r--internal/c/ior.bpf.c20
-rw-r--r--internal/ior.go95
5 files changed, 115 insertions, 0 deletions
diff --git a/assets/ior-small.png b/assets/ior-small.png
new file mode 100644
index 0000000..157df17
--- /dev/null
+++ b/assets/ior-small.png
Binary files differ
diff --git a/assets/ior.png b/assets/ior.png
new file mode 100644
index 0000000..4b08952
--- /dev/null
+++ b/assets/ior.png
Binary files differ
diff --git a/assets/ior.xcf b/assets/ior.xcf
new file mode 100644
index 0000000..c9b6665
--- /dev/null
+++ b/assets/ior.xcf
Binary files differ
diff --git a/internal/c/ior.bpf.c b/internal/c/ior.bpf.c
new file mode 100644
index 0000000..7c41551
--- /dev/null
+++ b/internal/c/ior.bpf.c
@@ -0,0 +1,20 @@
+//+build ignore
+
+#include "vmlinux.h"
+#include <bpf/bpf_helpers.h>
+#include "types.h"
+#include "maps.h"
+#include "flags.h"
+
+/**
+ * Including .c files, as linking several .o files into one single .o file doesn't work
+ * with shared BPF state such as ring buffers, maps and globals so well. Other BPF projects
+ * come along with one huuuuughe .c file with all the BPF code in it. I am rather
+ * splitting the code up into several smaller files.
+ */
+#include "filter.c"
+
+// Auto-generated tracepoints.
+#include "generated/tracepoints.c"
+
+char LICENSE[] SEC("license") = "Dual BSD/GPL";
diff --git a/internal/ior.go b/internal/ior.go
new file mode 100644
index 0000000..af97e55
--- /dev/null
+++ b/internal/ior.go
@@ -0,0 +1,95 @@
+package internal
+
+import "C"
+
+import (
+ "fmt"
+ "os"
+ "os/signal"
+ "runtime/pprof"
+ "syscall"
+
+ "ior/internal/flags"
+ "ior/internal/generated/tracepoints"
+
+ bpf "github.com/aquasecurity/libbpfgo"
+)
+
+func attachTracepoints(bpfModule *bpf.Module) error {
+ for _, name := range tracepoints.List {
+ prog, err := bpfModule.GetProgram(fmt.Sprintf("handle_%s", name))
+ if err != nil {
+ return fmt.Errorf("Failed to get BPF program handle_%s: %v", name, err)
+ }
+ fmt.Println("Attached prog handle_" + name)
+
+ if _, err = prog.AttachTracepoint("syscalls", name); err != nil {
+ // OK, older Kernel versions may not have this tracepoint!
+ fmt.Println(fmt.Errorf("Failed to attach to %s tracepoint: %v", name, err))
+ continue
+ }
+ fmt.Println("Attached tracepoint " + name)
+ }
+
+ return nil
+}
+
+func Run(flags flags.Flags) {
+ bpfModule, err := bpf.NewModuleFromFile("ior.bpf.o")
+ if err != nil {
+ panic(err)
+ }
+ defer bpfModule.Close()
+
+ if err := flags.ResizeBPFMaps(bpfModule); err != nil {
+ panic(err)
+ }
+
+ if err := flags.SetBPF(bpfModule); err != nil {
+ panic(err)
+ }
+
+ if err := bpfModule.BPFLoadObject(); err != nil {
+ panic(err)
+ }
+
+ if err := attachTracepoints(bpfModule); err != nil {
+ panic(err)
+ }
+
+ // 4096 channel size, minimises event drops
+ ch := make(chan []byte, 4096)
+ rb, err := bpfModule.InitRingBuf("event_map", ch)
+ if err != nil {
+ panic(err)
+ }
+ rb.Poll(300)
+
+ var cpuProfile, memProfile *os.File
+ if flags.PprofEnable {
+ if cpuProfile, err = os.Create("ior.cpuprofile"); err != nil {
+ panic(err)
+ }
+ if memProfile, err = os.Create("ior.memprofile"); err != nil {
+ panic(err)
+ }
+ pprof.StartCPUProfile(cpuProfile)
+ }
+
+ c := make(chan os.Signal, 1)
+ signal.Notify(c, os.Interrupt, syscall.SIGTERM)
+ go func() {
+ <-c
+ fmt.Println("Shutting down...")
+ if flags.PprofEnable {
+ fmt.Println("Stoppig profiling, writing ior.cpuprofile and ior.memprofile")
+ pprof.StopCPUProfile()
+ pprof.WriteHeapProfile(memProfile)
+ }
+ os.Exit(0)
+ }()
+
+ newEventLoop(flags).run(ch)
+
+ fmt.Println("Good bye")
+}