commit bec74fc8413ba79d7bf367e9c421692299d1955d
Author: jbitta <bittara3@uniba.sk>
Date: Wed, 11 Dec 2024 23:21:47 +0100
init
Diffstat:
7 files changed, 357 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,6 @@
+main
+source.tar.gz
+source-c.tar.gz
+process_exit.bpf.o
+process_exit.skel.h
+vmlinux.h
diff --git a/Makefile b/Makefile
@@ -0,0 +1,38 @@
+ARCH=$(shell uname -m | sed 's/x86_64/x86/' | sed 's/aarch64/arm64/')
+
+run: main
+ sudo ./main
+
+main: main.c process_exit.skel.h
+ gcc -Wall -o main main.c -L../libbpf/src -l:libbpf.a -lelf -lz
+
+website: webpage/index.html
+ scp webpage/index.html bittara3@davinci.fmph.uniba.sk:~/public_html/index.html
+
+process_exit.bpf.o: process_exit.bpf.c vmlinux.h
+ clang \
+ -target bpf \
+ -D __TARGET_ARCH_$(ARCH) \
+ -I/usr/include/$(shell uname -m)-linux-gnu \
+ -Wall -O2 -g -c process_exit.bpf.c -o process_exit.bpf.o
+
+process_exit.skel.h: process_exit.bpf.o
+ bpftool gen skeleton process_exit.bpf.o > process_exit.skel.h
+
+vmlinux.h:
+ bpftool btf dump file /sys/kernel/btf/vmlinux format c > vmlinux.h
+
+clean:
+ rm process_exit.bpf.o
+ rm main
+
+source:
+ mkdir -p source-c
+ cp main.c process_exit.h process_exit.bpf.c source-c
+ tar czf source-c.tar.gz source-c/
+
+# gcc -Wall -o main main.c -L../libbpf/src -l:libbpf.a -lelf -lz
+
+# bpf-gcc -I/usr/include/ -mxbpf exit.bpf.c -o exit.bpf.o
+
+.PHONY: run website clean source
diff --git a/README.md b/README.md
@@ -0,0 +1,22 @@
+# Dependencie
+
+Na debianových systémoch
+```bash
+sudo apt install bpfcc-tools python3-bpfcc libbpfcc libbpfcc-dev
+```
+
+Pre iné systémy sú inštrukcie tu: https://github.com/iovisor/bcc/blob/master/INSTALL.md
+
+# Spustenie
+```bash
+make
+```
+alebo
+```bash
+python3 main.py # alebo ./main.py
+```
+
+# Prepínače
+`-h` - help
+`-c, --csv` - výstup vo formáte csv
+`-f FILE, --file FILE` - výstup zapíš do súbora `FILE`
diff --git a/main.c b/main.c
@@ -0,0 +1,192 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <errno.h>
+#include <stdint.h>
+#include <bpf/libbpf.h>
+#include "process_exit.h"
+#include "process_exit.skel.h"
+
+/* #define x x */
+
+static int libbpf_print_fn(enum libbpf_print_level level,
+ const char* format, va_list args) {
+ if (level >= LIBBPF_DEBUG)
+ return 0;
+
+ return vfprintf(stderr, format, args);
+}
+
+static int csv = 0;
+static FILE* output_file = 0;
+static uint32_t parameter_flags = 0;
+
+void parse_options(int argc, char* argv[], const char** file) {
+ static struct option long_options[] = {
+ { "csv" , no_argument, 0, 'c' },
+ { "file" , required_argument, 0, 'f' },
+ { "filter", required_argument, 0, 'F' },
+ { "help" , no_argument, 0, 'h' },
+ { 0 , 0, 0, 0 },
+ };
+
+ int ret = EXIT_FAILURE;
+ int opt;
+ while ((opt = getopt_long(argc, argv, "cf:hF:", long_options, NULL)) != -1) {
+ switch (opt) {
+ case 'c':
+ csv = 1;
+ break;
+ case 'f':
+ *file = optarg;
+ break;
+ case 'F':
+ break;
+ case 'h':
+ ret = EXIT_SUCCESS;
+ default:
+ fprintf(stderr, "Usage: %s [-c] [-f file]\n", argv[0]);
+ exit(ret);
+ }
+ }
+}
+
+void handle_event(void* ctx, int cpu, void* data, unsigned int data_sz) {
+ const struct data_t* event = (struct data_t*)data;
+ (void)ctx;
+ (void)cpu;
+ (void)data_sz;
+
+ const char* output_format = "%-16s %-7d %-7d %-7d %-7d %-7.3f %-7.3f %-7.3f %-7d %-7d %-7d %-7d %-7.3f %-7.3f %-7d %-7d %-7d %-7d\n";
+ if (csv) {
+ output_format = "%s,%d,%d,%d,%d,%.3f,%.3f,%.3f,%d,%d,%d,%d,%.3f,%.3f,%d,%d,%d,%d\n";
+ }
+
+ float age = (event->exit_time - event->start_time) / 1e9;
+
+ fprintf(output_file,
+ output_format,
+ event->task,
+ event->tgid,
+ event->pid,
+ event->ppid,
+ event->uid,
+ age,
+ event->utime / 1e9,
+ event->stime / 1e9,
+ event->exit_code,
+ event->exit_signal,
+ event->nvcsw,
+ event->nivcsw,
+ event->cutime / 1e9,
+ event->cstime / 1e9,
+ event->inblock,
+ event->oublock,
+ event->cinblock,
+ event->coublock);
+
+ fflush(output_file);
+}
+
+void lost_event(void* ctx, int cpu, long long unsigned cnt) {
+ (void)ctx;
+ (void)cpu;
+ (void)cnt;
+
+ printf("lost event\n");
+}
+
+void print_header(void) {
+ const char* output_format = "%-16s %-7s %-7s %-7s %-7s %-7s %-7s %-7s %-7s %-7s %-7s %-7s %-7s %-7s %-7s %-7s %-7s %-7s\n";
+ if (csv) {
+ output_format = "%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n";
+ }
+ fprintf(output_file, output_format,
+ "PCOMM",
+ "TGID",
+ "PID",
+ "PPID",
+ "UID",
+ "age",
+ "utime",
+ "stime",
+ "exit",
+ "exitsig",
+ "nvcs",
+ "nivcs",
+ "cutime",
+ "cstime",
+ "inblock",
+ "oublock",
+ "cinblock",
+ "coublock");
+ fflush(output_file);
+}
+
+int main(int argc, char* argv[]) {
+
+ output_file = stdout;
+ const char* file_name = NULL;
+ parse_options(argc, argv, &file_name);
+
+ if (getuid() != 0) {
+ fprintf(stderr, "You should run this program with root privileges.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ libbpf_set_print(libbpf_print_fn);
+
+ struct process_exit_bpf* skel = process_exit_bpf__open_and_load();
+ if (!skel) {
+ fprintf(stderr, "Failed to open BPF object file\n");
+ return 1;
+ }
+
+ int err = process_exit_bpf__attach(skel);
+ if (err) {
+ fprintf(stderr, "Failed to attach BPF skeleton: %d\n", err);
+ process_exit_bpf__destroy(skel);
+ return 1;
+ }
+
+ struct perf_buffer* pb = perf_buffer__new(bpf_map__fd(skel->maps.output),
+ 8,
+ handle_event,
+ lost_event,
+ NULL,
+ NULL);
+ if (!pb) {
+ err = -1;
+ fprintf(stderr, "Failed to create ring buffer\n");
+ process_exit_bpf__destroy(skel);
+ return -err;
+ }
+
+ int writing_to_file = 0;
+ if (file_name != NULL && strcmp(file_name, "-") != 0) {
+ output_file = fopen(file_name, "w+");
+ writing_to_file = 1;
+ }
+
+ print_header();
+ while (1) {
+ err = perf_buffer__poll(pb, 1000);
+ if (err == -EINTR) {
+ err = 0;
+ break;
+ }
+ if (err < 0) {
+ printf("Error polling perf buffer: %d\n", err);
+ break;
+ }
+ }
+
+ if (writing_to_file) {
+ fclose(output_file);
+ }
+
+ perf_buffer__free(pb);
+ process_exit_bpf__destroy(skel);
+
+ return -err;
+}
diff --git a/napady.org b/napady.org
@@ -0,0 +1,17 @@
+* zaznamenavat syscall open
+vieme zaznamenavat, ktore procesy otvaraju vela suborov
+ine parametre
+add child times - tgid
+kumulativny udaj o potomkoch / potomkovia
+exit_code X
+pricina exitu
+pouzite resources
+pocet packetov
+getrusage X
+diskove_operacie X
+context_switch X
+child_times X
+add filters
+waitpid makra na extrakciu dat z exit_code
+children diskove operacie rozdelene
+prepinac na kumulativne / separatne statistiky
diff --git a/process_exit.bpf.c b/process_exit.bpf.c
@@ -0,0 +1,54 @@
+#include "vmlinux.h"
+#include <bpf/bpf_tracing.h>
+#include "process_exit.h"
+
+struct {
+ __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
+ __uint(key_size, sizeof(u32));
+ __uint(value_size, sizeof(u32));
+} output SEC(".maps");
+
+SEC("tracepoint/sched/sched_process_exit")
+int sched_process_exit(void* ctx)
+{
+ struct task_struct* task = (typeof(task))bpf_get_current_task();
+ struct data_t data = {};
+
+ bpf_probe_read_kernel(&data.start_time, sizeof(data.start_time), &task->start_time);
+ data.exit_time = bpf_ktime_get_ns(),
+ bpf_probe_read_kernel(&data.utime, sizeof(data.utime), &task->utime);
+ bpf_probe_read_kernel(&data.stime, sizeof(data.stime), &task->stime);
+ bpf_probe_read_kernel(&data.tgid, sizeof(data.tgid), &task->tgid);
+ bpf_probe_read_kernel(&data.pid, sizeof(data.pid), &task->pid);
+
+ struct task_struct* real_parent = NULL;
+ bpf_probe_read_kernel(&real_parent, sizeof(struct task_struct*), &task->real_parent);
+ bpf_probe_read_kernel(&data.ppid, sizeof(data.ppid), &real_parent->pid);
+
+ struct cred* real_cred = NULL;
+ bpf_probe_read_kernel(&real_cred, sizeof(struct cred*), &task->real_cred);
+ bpf_probe_read_kernel(&data.uid, sizeof(data.uid), &real_cred->uid);
+
+ bpf_probe_read_kernel(&data.exit_code, sizeof(data.exit_code), &task->exit_code);
+ bpf_probe_read_kernel(&data.exit_signal, sizeof(data.exit_signal), &task->exit_signal);
+ bpf_probe_read_kernel(&data.nvcsw, sizeof(data.nvcsw), &task->nvcsw);
+ bpf_probe_read_kernel(&data.nivcsw, sizeof(data.nivcsw), &task->nivcsw);
+
+ struct signal_struct* sig = NULL;
+ bpf_probe_read_kernel(&sig, sizeof(struct signal_struct*), &task->signal);
+ bpf_probe_read_kernel(&data.cutime, sizeof(data.cutime), &sig->cutime);
+ bpf_probe_read_kernel(&data.cstime, sizeof(data.cstime), &sig->cstime);
+ bpf_probe_read_kernel(&data.inblock, sizeof(data.inblock), &sig->inblock);
+ bpf_probe_read_kernel(&data.oublock, sizeof(data.oublock), &sig->oublock);
+ bpf_probe_read_kernel(&data.cinblock, sizeof(data.cinblock), &sig->cinblock);
+ bpf_probe_read_kernel(&data.coublock, sizeof(data.coublock), &sig->coublock);
+
+ bpf_get_current_comm(&data.task, sizeof(data.task));
+
+ bpf_perf_event_output(ctx, &output, BPF_F_CURRENT_CPU,
+ &data, sizeof(data));
+
+ return 0;
+}
+
+char LICENSE[] SEC("license") = "Dual BSD/GPL";
diff --git a/process_exit.h b/process_exit.h
@@ -0,0 +1,28 @@
+#ifndef PROCESS_EXIT_H
+#define PROCESS_EXIT_H
+
+#define TASK_COMM_LEN 16
+
+struct data_t {
+ __u64 start_time;
+ __u64 exit_time;
+ __u64 utime;
+ __u64 stime;
+ __u32 tgid;
+ __u32 pid;
+ __u32 ppid;
+ __u32 uid;
+ __s32 exit_code;
+ __s32 exit_signal;
+ __u64 nvcsw;
+ __u64 nivcsw;
+ __u64 cutime;
+ __u64 cstime;
+ __u64 inblock;
+ __u64 oublock;
+ __u64 cinblock;
+ __u64 coublock;
+ char task[TASK_COMM_LEN];
+};
+
+#endif /* PROCESS_EXIT_H */