Skip to content

Commit

Permalink
Merge pull request #959 from Monkey857/develop
Browse files Browse the repository at this point in the history
kvm_watcher:修复bug
  • Loading branch information
chenamy2017 authored Jan 13, 2025
2 parents d500c06 + f93a906 commit 46262da
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 81 deletions.
57 changes: 48 additions & 9 deletions eBPF_Supermarket/kvm_watcher/include/bpf/container.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -89,27 +90,25 @@ 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) {
bpf_printk("Failed to read container_id from kernel space, error code: %d\n", ret);
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;
Expand All @@ -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;i<MAX_NODENAME_LEN;i++){
if(data.nodename[i] != hostname[i]){
is_equal = false; //表明匹配失败了,该进程和需要监听的id不相等
break;
}
if(data.nodename[i]=='\0'||hostname[i]=='\0'){
break;
}
}
if (is_equal){ //表明匹配成功,该进程是需要监听的容器里的进程
pid_t pid = bpf_get_current_pid_tgid();
bpf_map_update_elem(&container_id_map,&pid,&data.nodename,BPF_ANY);
return true;
} else {
return false;
}
}
#endif /* __CONTAINER_H */
80 changes: 8 additions & 72 deletions eBPF_Supermarket/kvm_watcher/src/kvm_watcher.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,84 +245,20 @@ int BPF_KPROBE(kp_start_sw_timer, struct kvm_lapic *apic) {
CHECK_PID(vm_pid);
return trace_start_sw_timer(apic);
}

//采集容器的系统用调用信息
SEC("tracepoint/raw_syscalls/sys_enter")
int tp_container_sys_entry(struct trace_event_raw_sys_enter *args) {
//过滤进程
if (hostname == NULL || hostname[0] == '\0') {

return false; // 提前返回
}
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);
// 打印主机名

for(int i = 0;i<MAX_NODENAME_LEN;i++){
if(data.nodename[i] != hostname[i]){
return 0;
}
if(data.nodename[i]=='\0'||hostname[i]=='\0'){
break;
}
if(is_container_task(hostname)){
return trace_container_sys_entry(args);
}else{
return 0;
}
pid_t pid = bpf_get_current_pid_tgid();
bpf_map_update_elem(&container_id_map,&pid,&data.nodename,BPF_ANY);
return trace_container_sys_entry(args);
}
SEC("tracepoint/raw_syscalls/sys_exit")
int tracepoint__syscalls__sys_exit(struct trace_event_raw_sys_exit *args) {
//过滤进程
if (hostname == NULL || hostname[0] == '\0') {
return false;
}
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);
// 打印主机名

for(int i = 0;i<MAX_NODENAME_LEN;i++){
if(data.nodename[i] != hostname[i]){
return 0;
}
if(data.nodename[i]=='\0'||hostname[i]=='\0'){
break;
}
if(is_container_task(hostname)){
return trace_container_sys_exit(args);
}else{
return 0;
}
return trace_container_sys_exit(args, &rb, e);
}

0 comments on commit 46262da

Please sign in to comment.