projekt

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit bec74fc8413ba79d7bf367e9c421692299d1955d
Author: jbitta <bittara3@uniba.sk>
Date:   Wed, 11 Dec 2024 23:21:47 +0100

init

Diffstat:
A.gitignore | 6++++++
AMakefile | 38++++++++++++++++++++++++++++++++++++++
AREADME.md | 22++++++++++++++++++++++
Amain.c | 192+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Anapady.org | 17+++++++++++++++++
Aprocess_exit.bpf.c | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aprocess_exit.h | 28++++++++++++++++++++++++++++
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 */