From de5213f2cf3c4d48fa5ff316d69bb193b145a231 Mon Sep 17 00:00:00 2001 From: Monkey857 Date: Fri, 20 Dec 2024 14:51:49 +0800 Subject: [PATCH 1/2] update --- .../kvm_watcher/src/kvm_watcher.c | 45 ++++++++++++++++--- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/eBPF_Supermarket/kvm_watcher/src/kvm_watcher.c b/eBPF_Supermarket/kvm_watcher/src/kvm_watcher.c index cc0158d1d..41b901c8d 100644 --- a/eBPF_Supermarket/kvm_watcher/src/kvm_watcher.c +++ b/eBPF_Supermarket/kvm_watcher/src/kvm_watcher.c @@ -1238,6 +1238,27 @@ int print_exit_map(struct kvm_watcher_bpf *skel) { __print_exit_map(userspace_exit_fd, EXIT_USERSPACE_NR); return 0; } +// 移动光标到指定位置 +void move_cursor(int row, int col) { + printf("\033[%d;%dH", row, col); // ANSI 转义序列:移动光标到指定行列 +} +// 打印容器系统调用固定描述内容 +void print_description() { + move_cursor(1, 1); // 将光标移到第 1 行第 1 列 + printf("功能描述:实时监控指定容器的系统调用统计数据\n"); + move_cursor(2, 1); + printf("采集内容:统计指定容器中所有进程调用次数最多的前5个系统调用信息\n"); + move_cursor(3, 1); + printf("容器ID: %s\n",env.hostname); + move_cursor(4, 1); + printf("--------------------------------------------\n"); + move_cursor(5, 1); + printf("%-13s %-10s %-10s %-10s %-10s %-15s\n", + "ContainerID", "Comm", "Pid", "SYSCALLID", "Counts", "AVG_DELAY(us)"); + move_cursor(6, 1); + printf("==============================================================\n"); +} + int memset_big_struct(struct kvm_watcher_bpf *skel){ //对占用大内存的结构体的map进行初始化 int fd_memset = bpf_map__fd(skel->maps.proc_syscall_info); @@ -1284,7 +1305,9 @@ int print_container_syscall(struct kvm_watcher_bpf *skel){ int err ; //打印表头 - printf("%-13s %-10s %-10s %-10s %-10s %-10s\n","ContainerID", "Comm","Pid","SYSCALLID","Counts","avage_DELAY(us)"); + //printf("%-13s %-10s %-10s %-10s %-10s %-10s\n","ContainerID", "Comm","Pid","SYSCALLID","Counts","avage_DELAY(us)"); + print_description(); + move_cursor(7, 1); while(!bpf_map_get_next_key(fd,&lookup_key,&next_key)){ err = bpf_map_lookup_elem(fd,&next_key,&values); if (err < 0) { @@ -1294,6 +1317,7 @@ int print_container_syscall(struct kvm_watcher_bpf *skel){ //找出最大的前五个系统调用号 int max[5] = {-1, -1, -1, -1, -1}; // 记录前五个最大值的下标 int top_values[5] = {0,0,0,0,0}; // 记录前五个最大值 + uint64_t result = -1; for (int i = 0; i < 462; i++) { for (int j = 0; j < 5; j++) { if (values.syscall_id_counts[i] > top_values[j]) { @@ -1312,11 +1336,14 @@ int print_container_syscall(struct kvm_watcher_bpf *skel){ if(max[i] == -1){ continue; } - uint64_t result = values.syscall_total_delay[max[i]] / values.syscall_id_counts[max[i]]; + result = values.syscall_total_delay[max[i]] / values.syscall_id_counts[max[i]]; printf("%-13s %-10s %-10d %-10d %-10d %llu\n",values.container_id,values.proc_name,next_key, max[i],values.syscall_id_counts[max[i]],result); } lookup_key = next_key; + if(result != -1){ + printf("==============================================================\n"); + } } memset(&lookup_key, 0, sizeof(pid_t)); memset(&next_key, 0, sizeof(pid_t)); @@ -1328,9 +1355,7 @@ int print_container_syscall(struct kvm_watcher_bpf *skel){ } lookup_key = next_key; } - printf("--------------------------\n"); return 0; - } void print_map_and_check_error(int (*print_func)(struct kvm_watcher_bpf *), struct kvm_watcher_bpf *skel, @@ -1341,7 +1366,10 @@ void print_map_and_check_error(int (*print_func)(struct kvm_watcher_bpf *), printf("Error printing %s map: %d\n", map_name, err); } } - +void clear_screen() { + // ANSI 转义序列清屏 + printf("\033[H\033[J"); +} void print_logo() { char *logo = LOGO_STRING; char command[512]; @@ -1356,7 +1384,6 @@ int attach_probe(struct kvm_watcher_bpf *skel) { return kvm_watcher_bpf__attach(skel); } int main(int argc, char **argv) { - // 定义一个环形缓冲区 struct ring_buffer *rb = NULL; struct kvm_watcher_bpf *skel; @@ -1420,6 +1447,10 @@ int main(int argc, char **argv) { fprintf(stderr, "Please specify an option using %s.\n", OPTIONS_LIST); goto cleanup; } + //实现刷屏操作 + clear_screen(); + fflush(stdout); + print_description(); //打印结果 while (!exiting) { err = ring_buffer__poll(rb, RING_BUFFER_TIMEOUT_MS /* timeout, ms */); @@ -1437,8 +1468,8 @@ int main(int argc, char **argv) { err); } if (env.execute_container_syscall){ - //print_map_and_check_error(print_container_syscall,skel,"container_syscall",err); print_container_syscall(skel); + clear_screen(); } /* Ctrl-C will cause -EINTR */ if (err == -EINTR) { From f93a9064c8bd6b60eebcdb90edd92d1b519599e6 Mon Sep 17 00:00:00 2001 From: Monkey857 Date: Fri, 10 Jan 2025 19:19:56 +0800 Subject: [PATCH 2/2] mod_code --- .../kvm_watcher/include/bpf/container.h | 57 ++++++++++--- .../kvm_watcher/src/kvm_watcher.bpf.c | 80 ++----------------- 2 files changed, 56 insertions(+), 81 deletions(-) diff --git a/eBPF_Supermarket/kvm_watcher/include/bpf/container.h b/eBPF_Supermarket/kvm_watcher/include/bpf/container.h index 0bb0ae68e..6dda002cb 100644 --- a/eBPF_Supermarket/kvm_watcher/include/bpf/container.h +++ b/eBPF_Supermarket/kvm_watcher/include/bpf/container.h @@ -61,7 +61,8 @@ static int trace_container_sys_entry(struct trace_event_raw_sys_enter *args){ bpf_map_update_elem(&id,&pid,&syscall_id,BPF_ANY); return 0; } -static int trace_container_sys_exit(struct trace_event_raw_sys_exit *args,void *rb,struct common_event *e){ + +static int trace_container_sys_exit(struct trace_event_raw_sys_exit *args){ u64 exit_time = bpf_ktime_get_ns(); pid_t pid = bpf_get_current_pid_tgid(); u64 delay,start_time,syscallid; @@ -89,7 +90,12 @@ static int trace_container_sys_exit(struct trace_event_raw_sys_exit *args,void * if (!syscall_value) { return 0; } - + //检查 syscallid 是否超出范围 + //逻辑检查应该放到获取结构体之后的第一步操作,提前的检查让路径变得显式且安全,否则验证器可能无法通过 + if (syscallid >= MAX_SYSCALL_NUM || syscallid < 0) { + return 0; // 如果超出范围,直接返回 + } + // 读取 container_id int ret = bpf_probe_read_kernel_str(syscall_value->container_id, sizeof(syscall_value->container_id), contain_id); if (ret < 0) { @@ -97,19 +103,12 @@ static int trace_container_sys_exit(struct trace_event_raw_sys_exit *args,void * return 0; } - // 打印读取的 container_id - bpf_printk("container_id: %s\n", syscall_value->container_id); - // 获取进程名并存储 ret = bpf_get_current_comm(syscall_value->proc_name, sizeof(syscall_value->proc_name)); if (ret < 0) { bpf_printk("Failed to read process name, error code: %d\n", ret); return 0; } - //检查 syscallid 是否超出范围 - if (syscallid >= MAX_SYSCALL_NUM || syscallid < 0) { - return 0; // 如果超出范围,直接返回 - } syscall_value->syscall_total_delay[syscallid] += delay; // 加上 delay 的值 syscall_value->syscall_id_counts[syscallid] += 1; // 计数加 1 return 0; @@ -118,4 +117,44 @@ static int trace_container_sys_exit(struct trace_event_raw_sys_exit *args,void * struct data_t { char nodename[MAX_NODENAME_LEN]; }; +static bool is_container_task(const volatile char *hostname){ + struct task_struct *task; + struct nsproxy *ns; + struct uts_namespace *uts; + struct data_t data = {}; + // 获取当前任务的 task_struct + task = (struct task_struct *)bpf_get_current_task(); + + // 获取 nsproxy + bpf_probe_read_kernel(&ns, sizeof(ns), &task->nsproxy); + if (!ns) { + return false; + } + + // 获取 uts_namespace + bpf_probe_read_kernel(&uts, sizeof(uts), &ns->uts_ns); + if (!uts) { + return false; + } + // 读取主机名 + bpf_probe_read_kernel_str(&data.nodename, sizeof(data.nodename), uts->name.nodename); + // 打印主机名 + bool is_equal = true; + for(int i = 0;insproxy); - if (!ns) { - return false; - } - - // 获取 uts_namespace - bpf_probe_read_kernel(&uts, sizeof(uts), &ns->uts_ns); - if (!uts) { - return false; - } - // 读取主机名 - bpf_probe_read_kernel_str(&data.nodename, sizeof(data.nodename), uts->name.nodename); - // 打印主机名 - - for(int i = 0;insproxy); - if (!ns) { - return false; - } - - // 获取 uts_namespace - bpf_probe_read_kernel(&uts, sizeof(uts), &ns->uts_ns); - if (!uts) { - return false; - } - // 读取主机名 - bpf_probe_read_kernel_str(&data.nodename, sizeof(data.nodename), uts->name.nodename); - // 打印主机名 - - for(int i = 0;i