diff --git a/.github/workflows/eBPF_proc_image.yml b/.github/workflows/eBPF_proc_image.yml
index 50c39ebb1..744a4be55 100644
--- a/.github/workflows/eBPF_proc_image.yml
+++ b/.github/workflows/eBPF_proc_image.yml
@@ -53,8 +53,9 @@ jobs:
- name: Run proc_image
run: |
cd eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image
- make proc_image
- sudo ./proc_image -a -p 1 -t 1
+ make
+ sudo ./proc_image -a &
+ sudo ./controller -f
- name: Run test_proc
run: |
diff --git a/.gitignore b/.gitignore
index 15b9578e1..681a24621 100644
--- a/.gitignore
+++ b/.gitignore
@@ -69,6 +69,7 @@ eBPF_Supermarket/kvm_watcher/**/temp*
eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/.output/*
eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/proc_image
eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/test/test_proc
+eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/controller
# libbpf_bootstrap
.output
diff --git a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/Makefile b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/Makefile
index cbfc1e413..2c7d12a2a 100644
--- a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/Makefile
+++ b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/Makefile
@@ -42,7 +42,8 @@ CFLAGS := -g -Wall
ALL_LDFLAGS := $(LDFLAGS) $(EXTRA_LDFLAGS)
APPS = resource_image lock_image syscall_image keytime_image schedule_image
-TARGETS = proc_image
+WORKTOOL := proc_image
+CONTROLLER := controller
SRC_DIR = ./include
COMMON_OBJ = \
@@ -83,12 +84,12 @@ $(call allow-override,CC,$(CROSS_COMPILE)cc)
$(call allow-override,LD,$(CROSS_COMPILE)ld)
.PHONY: all
-all: $(TARGETS)
+all: $(CONTROLLER) $(WORKTOOL) SUCCESS_MESSAGE
.PHONY: clean
clean:
$(call msg,CLEAN)
- $(Q)rm -rf $(OUTPUT) $(TARGETS)
+ $(Q)rm -rf $(OUTPUT) $(WORKTOOL) $(CONTROLLER)
$(OUTPUT) $(OUTPUT)/libbpf $(BPFTOOL_OUTPUT):
$(call msg,MKDIR,$@)
@@ -126,17 +127,37 @@ $(OUTPUT)/%.o: $(SRC_DIR)/%.c | $(OUTPUT)
$(call msg,CC,$@)
$(Q)$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
-$(OUTPUT)/$(TARGETS).o: $(TARGETS).c $(APPS) | $(OUTPUT)
+$(OUTPUT)/%.o: $(CONTROLLER).c | $(OUTPUT)
+ $(call msg,CC,$@)
+ $(Q)$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
+
+$(OUTPUT)/$(WORKTOOL).o: $(WORKTOOL).c $(APPS) | $(OUTPUT)
$(call msg,CC,$@)
$(Q)$(CC) $(CFLAGS) $(INCLUDES) -c $(filter %.c,$^) -o $@
# Build application binary and Create a file for storing data
-$(TARGETS): %: $(OUTPUT)/%.o $(COMMON_OBJ) $(LIBBPF_OBJ) | $(OUTPUT)
+$(CONTROLLER): %: $(OUTPUT)/%.o $(COMMON_OBJ) $(LIBBPF_OBJ) | $(OUTPUT)
+ $(call msg,BINARY,$@)
+ $(Q)$(CC) $^ $(ALL_LDFLAGS) -lstdc++ -lelf -lz -o $@
+
+$(WORKTOOL): %: $(OUTPUT)/%.o $(COMMON_OBJ) $(LIBBPF_OBJ) | $(OUTPUT)
$(call msg,BINARY,$@)
$(Q)$(CC) $^ $(ALL_LDFLAGS) -lstdc++ -lelf -lz -o $@
@mkdir -p $(OUTPUT)/data
@[ -f $(OUTPUT)/data/offcpu_stack.txt ] || touch $(OUTPUT)/data/offcpu_stack.txt
+SUCCESS_MESSAGE:
+ @echo " ____ ____ ______ ____ ____ "
+ @echo " ___ / __ )/ __ \/ ____/ / __ \_________ _____ / _/___ ___ ____ _____ ____ "
+ @echo " / _ \/ __ / /_/ / /_ / /_/ / ___/ __ \/ ___/ / // __ \`__ \/ __ \`/ __ \`/ _ \\"
+ @echo "/ __/ /_/ / ____/ __/ / ____/ / / /_/ / /__ _/ // / / / / / /_/ / /_/ / __/"
+ @echo "\___/_____/_/ /_/ /_/ /_/ \____/\___/ /___/_/ /_/ /_/\__,_/\__, /\___/ "
+ @echo " /____/ "
+ @echo "Successful to compile eBPF_proc_image tools:"
+ @echo "proc_image ——— Pre-attach to eBPF program, data is collected and output after activation"
+ @echo "controller ——— Controller for proc_image tool"
+ @echo "Please start your use ~"
+
# delete failed targets
.DELETE_ON_ERROR:
diff --git a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/README.md b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/README.md
index 65a9dd56b..4626ce028 100644
--- a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/README.md
+++ b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/README.md
@@ -1,44 +1,62 @@
-# 基于eBPF的Linux系统性能监测工具-进程画像
+# 基于eBPF的进程生命周期画像
## 一、介绍
-本项目是一个Linux进程生命周期画像工具,通过该工具可以清晰展示出一个进程从创建到终止的完整生命周期,并可以额外展示出进程/线程持有锁的区间画像、进程/线程上下文切换原因的标注、线程之间依赖关系(线程)、进程关联调用栈信息标注等。在这些功能的前提下,加入了更多的可视化元素和交互方式,使得整个画像更加直观、易于理解。
+本项目是一个Linux进程生命周期画像工具,可以清晰地展示出目标线程、目标线程组甚至系统中所有线程从创建到终止的完整生命周期,所展示出的进程生命周期信息包括关键时间点信息(execve、exit、fork、vfork、pthread_create、上下CPU等)、持有锁信息、资源使用信息、调度信息、系统调用序列信息等,并在特定的信息中加入了系统相关信息以作为参考和对比,考虑到对系统性能的影响和在高负载环境下的使用,该工具支持预先挂载使用激活的操作模式,同时在这些功能的前提下,基于Prometheus和Grafana构建了一个进程可视化平台,以实现进程画像的目的,并且通过清晰的进程画像即可察觉到进程的异常行为。
-运行环境:Ubuntu 22.04,内核版本 6.2
+eBPF_proc_image 工具的框架图:
+
+
-## 二、安装依赖
+## 二、安装工具
+
+运行环境:Ubuntu 22.04,内核版本 6.2
```
sudo apt update
sudo apt install libbpf-dev clang llvm libelf-dev libpcap-dev gcc-multilib build-essential
git submodule update --init --recursive
+make
```
## 三、proc_image 工具
-目前 proc_image 工具具备的功能:
-
-- 记录进程上下CPU的时间信息
-- 记录进程的关键时间点信息,即exec和exit
-- 记录进程持有锁的区间信息,目前实现了用户态互斥锁、内核态互斥锁、用户态读写锁
-- 记录新创建进程或线程的时间信息
+proc_image 工具用于挂载 eBPF 的内核态程序,但不进行采集数据,并在用户态循环遍历 map,若有数据则输出
proc_image 工具的参数信息:
| 参数 | 描述 |
| -------------------- | ------------------------------------------------- |
-| -p, --pid=PID | 指定跟踪进程的pid,默认为0号进程 |
-| -t, --time=TIME-SEC | 设置程序的最大运行时间(0表示无限),默认一直运行 |
-| -c, --cpuid=CPUID | 为每CPU进程设置,其他进程不需要设置该参数 |
-| -r, --resource | 采集进程的资源使用情况,包括CPU利用率、内存利用率、每秒读写字节数(可持续开发) |
-| -s, --syscall | 采集进程的系统调用序列信息 |
-| -l, --lock | 采集进程持有的用户态锁信息,包括用户态互斥锁、用户态读写锁(可持续开发) |
-| -q, --quote | 在参数周围添加引号(") |
-| -k, --keytime | 采集进程关键时间点的相关信息,包括execve、exit、fork、vfork、pthread_create |
-| -S, --schedule | 采集进程的调度信息 |
-| -a, --all | 启动所有的采集进程数据的功能 |
+| -a, --all | 挂载所有的 eBPF 内核态程序,但不进行采集数据 |
+| -k, --keytime | 挂载进程关键时间点相关的 eBPF 内核态程序,但不进行采集数据 |
+| -l, --lock | 挂载进程用户态持有锁相关的 eBPF 内核态程序,但不进行采集数据 |
+| -r, --resource | 挂载进程资源使用情况相关的 eBPF 内核态程序,但不进行采集数据 |
+| -s, --syscall | 挂载进程系统调用相关的 eBPF 内核态程序,但不进行采集数据 |
+| -S, --schedule | 挂载进程调度相关的 eBPF 内核态程序,但不进行采集数据 |
| -h, --help | 显示帮助信息 |
+## 四、controller 工具
+
+controller 工具用于控制eBPF程序的执行,可动态调整数据的采集策略
+
+controller 工具的参数信息:
+
+| 参数 | 描述 |
+| ---------------------- | ------------------------------------------------------------ |
+| -a, --activate | 设置 proc_image 工具的启动策略 |
+| -d, --deactivate | 初始化为原始的失活状态 |
+| -f, --finish | 结束 proc_image 工具的运行 |
+| -p, --pid=PID | 指定跟踪进程的pid |
+| -P, --tgid=TGID | 指定跟踪进程的tgid |
+| -c, --cpuid=CPUID | 为每CPU进程设置,其他进程不需要设置该参数 |
+| -t, --time=TIME-SEC | 设置程序的最大运行时间(0表示无限),默认一直运行 |
+| -r, --resource | 采集进程的资源使用情况,包括CPU利用率、内存利用率、每秒读写字节数(可持续开发) |
+| -l, --lock | 采集进程持有用户态锁的时间信息,包括用户态互斥锁、用户态读写锁、用户态自旋锁(可持续开发) |
+| -k, --keytime=KEYTIME | 采集进程关键时间点的相关信息,包括fork、vfork、pthread_create、execve、exit、onCPU、offCPU及offCPU的原因(可持续开发) |
+| -s, --syscall=SYSCALLS | 采集进程以及系统的系统调用信息,进程的系统调用信息包括系统调用序列、前三个调用最频繁的系统调用、系统调用的平均延迟、最大延迟以及最小延迟,同时也采集了系统的这些延迟信息以作为参考和对比 |
+| -S, --schedule | 采集进程及系统的调度信息,其中系统的调度信息具有参考和对比的作用,调度信息包括调度的平均延迟、最大延迟以及最小延迟 |
+| -h, --help | 显示帮助信息 |
+
## 四、tools
tools文件夹中的eBPF程序是按照进程生命周期中数据的类型分别进行实现的:
@@ -51,18 +69,10 @@ tools文件夹中的eBPF程序是按照进程生命周期中数据的类型分
| syscall_image | 对进程的系统调用序列进行画像 |
| schedule_image | 对进程的调度信息进行画像 |
-## 五、test_proc 测试程序
-
-目前 [test_proc](./test/test_proc.c) 测试程序所具备逻辑:
+## 五、基于 Prometheus 和 Grafana 的可视化平台
-- 逻辑1:加入sleep逻辑使进程睡眠3秒,即offCPU 3秒
-- 逻辑2:加入互斥锁逻辑,为了应对复杂场景,模拟进程异常地递归加锁解锁
-- 逻辑3:加入fork和vfork逻辑,创建子进程让子进程睡眠3秒,以表示它存在的时间
-- 逻辑4:加入pthread_create逻辑,创建线程让线程睡眠3秒,以表示它存在的时间
-- 逻辑5:加入读写锁逻辑,在读模式或写模式下上锁后睡眠3s,以表示持有锁时间
-- 逻辑6:加入execve逻辑,用于测试采集到数据的准确性
-- 逻辑7:加入exit逻辑,可以手动输入程序退出的error_code值
+基于 Prometheus 和 Grafana 的可视化平台框架图:
-## 六、进程画像可视化
+
-可以参考:[进程画像可视化指南](docs/proc_image_vis_guide.md)
\ No newline at end of file
+eBPF_proc_image 工具的可视化操作可以参考:[进程画像可视化指南](docs/proc_image_vis_guide.md)
\ No newline at end of file
diff --git a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/bpf/keytime_image.bpf.c b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/bpf/keytime_image.bpf.c
index 65eb16892..d8c26f2e2 100644
--- a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/bpf/keytime_image.bpf.c
+++ b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/bpf/keytime_image.bpf.c
@@ -27,10 +27,15 @@ char LICENSE[] SEC("license") = "Dual BSD/GPL";
const volatile int max_args = DEFAULT_MAXARGS;
-const volatile pid_t target_pid = -1;
const volatile pid_t ignore_tgid = -1;
-const volatile pid_t target_tgid = -1;
-const volatile bool enable_cpu = false;
+const int key = 0;
+
+struct {
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, int);
+ __type(value, struct kt_ctrl);
+} kt_ctrl_map SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_HASH);
@@ -61,11 +66,16 @@ struct {
SEC("tracepoint/syscalls/sys_enter_execve")
int tracepoint__syscalls__sys_enter_execve(struct trace_event_raw_sys_enter* ctx)
{
+ struct kt_ctrl *kt_ctrl;
+ kt_ctrl = bpf_map_lookup_elem(&kt_ctrl_map,&key);
+ if(!kt_ctrl || !kt_ctrl->kt_func)
+ return 0;
+
int pid = bpf_get_current_pid_tgid();
int tgid = bpf_get_current_pid_tgid() >> 32;
- if(tgid!=ignore_tgid && ((target_tgid==-1 && target_pid==-1) || (target_tgid!=-1 && tgid==target_tgid) ||
- (target_pid!=-1 && pid==target_pid))){
+ if((kt_ctrl->enable_myproc || tgid!=ignore_tgid) && ((kt_ctrl->target_tgid==-1 && kt_ctrl->target_pid==-1) ||
+ (kt_ctrl->target_tgid!=-1 && tgid==kt_ctrl->target_tgid) || (kt_ctrl->target_pid!=-1 && pid==kt_ctrl->target_pid))){
struct keytime_event* event;
event = bpf_ringbuf_reserve(&keytime_rb, sizeof(*event), 0);
if(!event)
@@ -78,6 +88,8 @@ int tracepoint__syscalls__sys_enter_execve(struct trace_event_raw_sys_enter* ctx
event->type = 1;
event->pid = pid;
+ if(kt_ctrl->target_tgid != -1) event->tgid = tgid;
+ else event->tgid = -1;
event->info_count = 0;
event->info_size = 0;
event->enable_char_info = true;
@@ -137,11 +149,16 @@ int tracepoint__syscalls__sys_enter_execve(struct trace_event_raw_sys_enter* ctx
SEC("tracepoint/syscalls/sys_exit_execve")
int tracepoint__syscalls__sys_exit_execve(struct trace_event_raw_sys_exit* ctx)
{
+ struct kt_ctrl *kt_ctrl;
+ kt_ctrl = bpf_map_lookup_elem(&kt_ctrl_map,&key);
+ if(!kt_ctrl || !kt_ctrl->kt_func)
+ return 0;
+
int pid = bpf_get_current_pid_tgid();
int tgid = bpf_get_current_pid_tgid() >> 32;
- if(tgid!=ignore_tgid && ((target_tgid==-1 && target_pid==-1) || (target_tgid!=-1 && tgid==target_tgid) ||
- (target_pid!=-1 && pid==target_pid))){
+ if((kt_ctrl->enable_myproc || tgid!=ignore_tgid) && ((kt_ctrl->target_tgid==-1 && kt_ctrl->target_pid==-1) ||
+ (kt_ctrl->target_tgid!=-1 && tgid==kt_ctrl->target_tgid) || (kt_ctrl->target_pid!=-1 && pid==kt_ctrl->target_pid))){
struct keytime_event* event;
event = bpf_ringbuf_reserve(&keytime_rb, sizeof(*event), 0);
if(!event)
@@ -149,6 +166,8 @@ int tracepoint__syscalls__sys_exit_execve(struct trace_event_raw_sys_exit* ctx)
event->type = 2;
event->pid = pid;
+ if(kt_ctrl->target_tgid != -1) event->tgid = tgid;
+ else event->tgid = -1;
event->enable_char_info = false;
event->info_count = 1;
event->info[0] = ctx->ret;
@@ -163,13 +182,19 @@ int tracepoint__syscalls__sys_exit_execve(struct trace_event_raw_sys_exit* ctx)
SEC("uretprobe/fork")
int BPF_KRETPROBE(fork_exit,int ret)
{
+ struct kt_ctrl *kt_ctrl;
+ kt_ctrl = bpf_map_lookup_elem(&kt_ctrl_map,&key);
+ if(!kt_ctrl || !kt_ctrl->kt_func)
+ return 0;
+
pid_t pid = bpf_get_current_pid_tgid();
int tgid = bpf_get_current_pid_tgid() >> 32;
// 判断是否为父进程触发
- if(tgid!=ignore_tgid && ret!=0 && (target_tgid==-1 || (target_tgid!=-1 && tgid==target_tgid))){
+ if((kt_ctrl->enable_myproc || tgid!=ignore_tgid) && ret!=0 && ((kt_ctrl->target_pid ==-1 && kt_ctrl->target_tgid==-1) ||
+ (kt_ctrl->target_tgid!=-1 && tgid==kt_ctrl->target_tgid) || (kt_ctrl->target_pid!=-1 && pid==kt_ctrl->target_pid))){
pid_t child_pid = ret;
- child_create(4,child_pid,pid,&child,&keytime_rb);
+ child_create(4,child_pid,pid,&child,&keytime_rb,tgid,kt_ctrl->target_tgid);
}
return 0;
@@ -179,15 +204,20 @@ int BPF_KRETPROBE(fork_exit,int ret)
SEC("uretprobe/vfork")
int BPF_KRETPROBE(vfork_exit,int ret)
{
- struct task_struct *current = (struct task_struct *)bpf_get_current_task();
+ struct kt_ctrl *kt_ctrl;
+ kt_ctrl = bpf_map_lookup_elem(&kt_ctrl_map,&key);
+ if(!kt_ctrl || !kt_ctrl->kt_func)
+ return 0;
+
+ struct task_struct *current = (struct task_struct *)bpf_get_current_task();
pid_t ppid = BPF_CORE_READ(current,real_parent,pid);
int ptgid = BPF_CORE_READ(current,real_parent,tgid);
int tgid = bpf_get_current_pid_tgid() >> 32;
- if(tgid!=ignore_tgid && ((target_pid==-1 && target_tgid==-1) || (target_pid!=-1 && ppid==target_pid)) ||
- (target_tgid!=-1 && ptgid==target_tgid)){
+ if((kt_ctrl->enable_myproc || tgid!=ignore_tgid) && ((kt_ctrl->target_pid==-1 && kt_ctrl->target_tgid==-1) ||
+ (kt_ctrl->target_pid!=-1 && ppid==kt_ctrl->target_pid)) || (kt_ctrl->target_tgid!=-1 && ptgid==kt_ctrl->target_tgid)){
pid_t child_pid = BPF_CORE_READ(current,pid);
- child_create(6,child_pid,ppid,&child,&keytime_rb);
+ child_create(6,child_pid,ppid,&child,&keytime_rb,ptgid,kt_ctrl->target_tgid);
}
return 0;
@@ -196,10 +226,16 @@ int BPF_KRETPROBE(vfork_exit,int ret)
SEC("uprobe/pthread_create")
int BPF_KPROBE(pthread_create_enter)
{
+ struct kt_ctrl *kt_ctrl;
+ kt_ctrl = bpf_map_lookup_elem(&kt_ctrl_map,&key);
+ if(!kt_ctrl || !kt_ctrl->kt_func)
+ return 0;
+
int current = bpf_get_current_pid_tgid();
int tgid = bpf_get_current_pid_tgid() >> 32;
- if(tgid!=ignore_tgid && (target_tgid==-1 || (target_tgid!=-1 && tgid==target_tgid))){
+ if((kt_ctrl->enable_myproc || tgid!=ignore_tgid) && ((kt_ctrl->target_tgid==-1 && kt_ctrl->target_pid==-1) ||
+ (kt_ctrl->target_tgid!=-1 && tgid==kt_ctrl->target_tgid) || (kt_ctrl->target_pid!=-1 && current==kt_ctrl->target_pid))){
bool pthread_create_flag = true;
bpf_map_update_elem(&pthread_create_enable, ¤t, &pthread_create_flag, BPF_ANY);
}
@@ -210,10 +246,16 @@ int BPF_KPROBE(pthread_create_enter)
SEC("uretprobe/pthread_create")
int BPF_KRETPROBE(pthread_create_exit,int ret)
{
+ struct kt_ctrl *kt_ctrl;
+ kt_ctrl = bpf_map_lookup_elem(&kt_ctrl_map,&key);
+ if(!kt_ctrl || !kt_ctrl->kt_func)
+ return 0;
+
int current = bpf_get_current_pid_tgid();
int tgid = bpf_get_current_pid_tgid() >> 32;
- if(tgid!=ignore_tgid && (target_tgid==-1 || (target_tgid!=-1 && tgid==target_tgid))){
+ if((kt_ctrl->enable_myproc || tgid!=ignore_tgid) && ((kt_ctrl->target_tgid==-1 && kt_ctrl->target_pid==-1) ||
+ (kt_ctrl->target_tgid!=-1 && tgid==kt_ctrl->target_tgid) || (kt_ctrl->target_pid!=-1 && current==kt_ctrl->target_pid))){
bpf_map_delete_elem(&pthread_create_enable, ¤t);
}
@@ -224,11 +266,16 @@ int BPF_KRETPROBE(pthread_create_exit,int ret)
SEC("tracepoint/syscalls/sys_exit_clone3")
int tracepoint__syscalls__sys_exit_clone3(struct trace_event_raw_sys_exit* ctx)
{
+ struct kt_ctrl *kt_ctrl;
+ kt_ctrl = bpf_map_lookup_elem(&kt_ctrl_map,&key);
+ if(!kt_ctrl || !kt_ctrl->kt_func)
+ return 0;
+
pid_t current = bpf_get_current_pid_tgid();
int tgid = bpf_get_current_pid_tgid() >> 32;
- if(tgid!=ignore_tgid && ((target_tgid==-1 && target_pid==-1) || (target_tgid!=-1 && tgid==target_tgid) ||
- (target_pid!=-1 && current==target_pid))){
+ if((kt_ctrl->enable_myproc || tgid!=ignore_tgid) && ((kt_ctrl->target_tgid==-1 && kt_ctrl->target_pid==-1) ||
+ (kt_ctrl->target_tgid!=-1 && tgid==kt_ctrl->target_tgid) || (kt_ctrl->target_pid!=-1 && current==kt_ctrl->target_pid))){
// 判断是否是pthread_create函数触发的clone3系统调用
bool *pthread_create_flag;
pthread_create_flag = bpf_map_lookup_elem(&pthread_create_enable, ¤t);
@@ -237,7 +284,7 @@ int tracepoint__syscalls__sys_exit_clone3(struct trace_event_raw_sys_exit* ctx)
// 排除clone3错误返回的情况
if(new_thread <= 0) return 0;
- child_create(8,new_thread,current,&child,&keytime_rb);
+ child_create(8,new_thread,current,&child,&keytime_rb,tgid,kt_ctrl->target_tgid);
}
}
@@ -247,11 +294,16 @@ int tracepoint__syscalls__sys_exit_clone3(struct trace_event_raw_sys_exit* ctx)
SEC("tracepoint/syscalls/sys_enter_exit_group")
int tracepoint__syscalls__sys_enter_exit_group(struct trace_event_raw_sys_enter* ctx)
{
+ struct kt_ctrl *kt_ctrl;
+ kt_ctrl = bpf_map_lookup_elem(&kt_ctrl_map,&key);
+ if(!kt_ctrl || !kt_ctrl->kt_func)
+ return 0;
+
int pid = bpf_get_current_pid_tgid();
int tgid = bpf_get_current_pid_tgid() >> 32;
- if(tgid!=ignore_tgid && ((target_tgid==-1 && target_pid==-1) || (target_tgid!=-1 && tgid==target_tgid) ||
- (target_pid!=-1 && pid==target_pid))){
+ if((kt_ctrl->enable_myproc || tgid!=ignore_tgid) && ((kt_ctrl->target_tgid==-1 && kt_ctrl->target_pid==-1) ||
+ (kt_ctrl->target_tgid!=-1 && tgid==kt_ctrl->target_tgid) || (kt_ctrl->target_pid!=-1 && pid==kt_ctrl->target_pid))){
// 记录进程退出信息
struct keytime_event* event;
event = bpf_ringbuf_reserve(&keytime_rb, sizeof(*event), 0);
@@ -260,27 +312,34 @@ int tracepoint__syscalls__sys_enter_exit_group(struct trace_event_raw_sys_enter*
event->type = 3;
event->pid = pid;
+ if(kt_ctrl->target_tgid != -1) event->tgid = tgid;
+ else event->tgid = -1;
event->enable_char_info = false;
event->info_count = 1;
event->info[0] = ctx->args[0];
bpf_ringbuf_submit(event, 0);
-
- // 记录 fork 和 vfork 子进程的退出时间,并输出到 ringbuf 中
- child_exit(&child,&keytime_rb);
}
+ // 记录 fork 和 vfork 子进程的退出时间,并输出到 ringbuf 中
+ child_exit(&child,&keytime_rb);
+
return 0;
}
SEC("tracepoint/syscalls/sys_enter_exit")
int tracepoint__syscalls__sys_enter_exit(struct trace_event_raw_sys_enter* ctx)
{
+ struct kt_ctrl *kt_ctrl;
+ kt_ctrl = bpf_map_lookup_elem(&kt_ctrl_map,&key);
+ if(!kt_ctrl || !kt_ctrl->kt_func)
+ return 0;
+
int pid = bpf_get_current_pid_tgid();
int tgid = bpf_get_current_pid_tgid() >> 32;
- if(tgid!=ignore_tgid && ((target_tgid==-1 && target_pid==-1) || (target_tgid!=-1 && tgid==target_tgid) ||
- (target_pid!=-1 && pid==target_pid))){
+ if((kt_ctrl->enable_myproc || tgid!=ignore_tgid) && ((kt_ctrl->target_tgid==-1 && kt_ctrl->target_pid==-1) ||
+ (kt_ctrl->target_tgid!=-1 && tgid==kt_ctrl->target_tgid) || (kt_ctrl->target_pid!=-1 && pid==kt_ctrl->target_pid))){
// 记录进程退出信息
struct keytime_event* event;
event = bpf_ringbuf_reserve(&keytime_rb, sizeof(*event), 0);
@@ -289,23 +348,28 @@ int tracepoint__syscalls__sys_enter_exit(struct trace_event_raw_sys_enter* ctx)
event->type = 3;
event->pid = pid;
+ if(kt_ctrl->target_tgid != -1) event->tgid = tgid;
+ else event->tgid = -1;
event->enable_char_info = false;
event->info_count = 1;
event->info[0] = ctx->args[0];
bpf_ringbuf_submit(event, 0);
-
- // 记录 pthread_create 新线程的退出时间,并输出
- child_exit(&child,&keytime_rb);
}
+ // 记录 pthread_create 新线程的退出时间,并输出
+ child_exit(&child,&keytime_rb);
+
return 0;
}
SEC("tp_btf/sched_switch")
int BPF_PROG(sched_switch, bool preempt, struct task_struct *prev, struct task_struct *next)
{
- if(!enable_cpu) return 0;
+ struct kt_ctrl *kt_ctrl;
+ kt_ctrl = bpf_map_lookup_elem(&kt_ctrl_map,&key);
+ if(!kt_ctrl || !kt_ctrl->kt_cpu_func)
+ return 0;
pid_t next_pid = BPF_CORE_READ(next,pid);
int next_tgid = BPF_CORE_READ(next,tgid);
@@ -314,8 +378,8 @@ int BPF_PROG(sched_switch, bool preempt, struct task_struct *prev, struct task_s
int cpu_id = bpf_get_smp_processor_id();
// 记录 prev 进程的下CPU时的信息
- if(prev_tgid!=ignore_tgid && prev_pid!=0 && ((target_tgid==-1 && target_pid==-1) ||
- (target_tgid!=-1 && prev_tgid==target_tgid) || (target_pid!=-1 && prev_pid==target_pid))){
+ if((kt_ctrl->enable_myproc || prev_tgid!=ignore_tgid) && prev_pid!=0 && ((kt_ctrl->target_tgid==-1 && kt_ctrl->target_pid==-1) ||
+ (kt_ctrl->target_tgid!=-1 && prev_tgid==kt_ctrl->target_tgid) || (kt_ctrl->target_pid!=-1 && prev_pid==kt_ctrl->target_pid))){
struct offcpu_event* event;
event = bpf_ringbuf_reserve(&keytime_rb, sizeof(*event), 0);
@@ -324,6 +388,8 @@ int BPF_PROG(sched_switch, bool preempt, struct task_struct *prev, struct task_s
event->type = 11;
event->pid = prev_pid;
+ if(kt_ctrl->target_tgid != -1) event->tgid = prev_tgid;
+ else event->tgid = -1;
event->offcpu_time = bpf_ktime_get_ns();
event->kstack_sz = bpf_get_stack(ctx, event->kstack, sizeof(event->kstack), 0);
@@ -331,8 +397,8 @@ int BPF_PROG(sched_switch, bool preempt, struct task_struct *prev, struct task_s
}
// 记录 next 进程上CPU时的信息
- if(next_tgid!=ignore_tgid && next_pid!=0 && ((target_tgid==-1 && target_pid==-1) ||
- (target_tgid!=-1 && next_tgid==target_tgid) || (target_pid!=-1 && next_pid==target_pid))){
+ if((kt_ctrl->enable_myproc || next_tgid!=ignore_tgid) && next_pid!=0 && ((kt_ctrl->target_tgid==-1 && kt_ctrl->target_pid==-1) ||
+ (kt_ctrl->target_tgid!=-1 && next_tgid==kt_ctrl->target_tgid) || (kt_ctrl->target_pid!=-1 && next_pid==kt_ctrl->target_pid))){
struct keytime_event* event;
event = bpf_ringbuf_reserve(&keytime_rb, sizeof(*event), 0);
@@ -341,6 +407,8 @@ int BPF_PROG(sched_switch, bool preempt, struct task_struct *prev, struct task_s
event->type = 10;
event->pid = next_pid;
+ if(kt_ctrl->target_tgid != -1) event->tgid = next_tgid;
+ else event->tgid = -1;
event->enable_char_info = false;
event->info_count = 1;
event->info[0] = bpf_ktime_get_ns();
diff --git a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/bpf/lock_image.bpf.c b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/bpf/lock_image.bpf.c
index ad97ddc8f..05e7fddfd 100644
--- a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/bpf/lock_image.bpf.c
+++ b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/bpf/lock_image.bpf.c
@@ -26,7 +26,13 @@
char LICENSE[] SEC("license") = "Dual BSD/GPL";
const volatile pid_t ignore_tgid = -1;
-const volatile int target_tgid = -1;
+
+struct {
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, int);
+ __type(value, struct lock_ctrl);
+} lock_ctrl_map SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_HASH);
@@ -58,7 +64,7 @@ struct {
SEC("uprobe/pthread_mutex_lock")
int BPF_KPROBE(pthread_mutex_lock_enter, void *__mutex)
{
- record_lock_enter(target_tgid,ignore_tgid,1,1,__mutex,&lock_rb,&proc_lock);
+ record_lock_enter(ignore_tgid,1,1,__mutex,&lock_rb,&proc_lock,&lock_ctrl_map);
return 0;
}
@@ -66,7 +72,7 @@ int BPF_KPROBE(pthread_mutex_lock_enter, void *__mutex)
SEC("uretprobe/pthread_mutex_lock")
int BPF_KRETPROBE(pthread_mutex_lock_exit,int ret)
{
- record_lock_exit(target_tgid,ignore_tgid,2,1,ret,&lock_rb,&proc_lock,&locktype);
+ record_lock_exit(ignore_tgid,2,1,ret,&lock_rb,&proc_lock,&locktype,&lock_ctrl_map);
return 0;
}
@@ -74,7 +80,7 @@ int BPF_KRETPROBE(pthread_mutex_lock_exit,int ret)
SEC("uprobe/__pthread_mutex_trylock")
int BPF_KPROBE(__pthread_mutex_trylock_enter, void *__mutex)
{
- record_lock_enter(target_tgid,ignore_tgid,1,1,__mutex,&lock_rb,&proc_lock);
+ record_lock_enter(ignore_tgid,1,1,__mutex,&lock_rb,&proc_lock,&lock_ctrl_map);
return 0;
}
@@ -82,7 +88,7 @@ int BPF_KPROBE(__pthread_mutex_trylock_enter, void *__mutex)
SEC("uretprobe/__pthread_mutex_trylock")
int BPF_KRETPROBE(__pthread_mutex_trylock_exit,int ret)
{
- record_lock_exit(target_tgid,ignore_tgid,2,1,ret,&lock_rb,&proc_lock,&locktype);
+ record_lock_exit(ignore_tgid,2,1,ret,&lock_rb,&proc_lock,&locktype,&lock_ctrl_map);
return 0;
}
@@ -90,7 +96,7 @@ int BPF_KRETPROBE(__pthread_mutex_trylock_exit,int ret)
SEC("uprobe/pthread_mutex_unlock")
int BPF_KPROBE(pthread_mutex_unlock_enter, void *__rwlock)
{
- record_unlock_enter(target_tgid,ignore_tgid,1,__rwlock,&proc_unlock);
+ record_unlock_enter(ignore_tgid,1,__rwlock,&proc_unlock,&lock_ctrl_map);
return 0;
}
@@ -100,7 +106,7 @@ int BPF_KPROBE(pthread_mutex_unlock_enter, void *__rwlock)
SEC("uretprobe/pthread_mutex_unlock")
int BPF_KRETPROBE(pthread_mutex_unlock_exit)
{
- record_unlock_exit(target_tgid,ignore_tgid,3,1,&lock_rb,&proc_unlock,&locktype);
+ record_unlock_exit(ignore_tgid,3,1,&lock_rb,&proc_unlock,&locktype,&lock_ctrl_map);
return 0;
}
@@ -109,7 +115,7 @@ int BPF_KRETPROBE(pthread_mutex_unlock_exit)
SEC("uprobe/__pthread_rwlock_rdlock")
int BPF_KPROBE(__pthread_rwlock_rdlock_enter, void *__rwlock)
{
- record_lock_enter(target_tgid,ignore_tgid,4,2,__rwlock,&lock_rb,&proc_lock);
+ record_lock_enter(ignore_tgid,4,2,__rwlock,&lock_rb,&proc_lock,&lock_ctrl_map);
return 0;
}
@@ -117,7 +123,7 @@ int BPF_KPROBE(__pthread_rwlock_rdlock_enter, void *__rwlock)
SEC("uretprobe/__pthread_rwlock_rdlock")
int BPF_KRETPROBE(__pthread_rwlock_rdlock_exit,int ret)
{
- record_lock_exit(target_tgid,ignore_tgid,5,2,ret,&lock_rb,&proc_lock,&locktype);
+ record_lock_exit(ignore_tgid,5,2,ret,&lock_rb,&proc_lock,&locktype,&lock_ctrl_map);
return 0;
}
@@ -125,7 +131,7 @@ int BPF_KRETPROBE(__pthread_rwlock_rdlock_exit,int ret)
SEC("uprobe/__pthread_rwlock_tryrdlock")
int BPF_KPROBE(__pthread_rwlock_tryrdlock_enter, void *__rwlock)
{
- record_lock_enter(target_tgid,ignore_tgid,4,2,__rwlock,&lock_rb,&proc_lock);
+ record_lock_enter(ignore_tgid,4,2,__rwlock,&lock_rb,&proc_lock,&lock_ctrl_map);
return 0;
}
@@ -133,7 +139,7 @@ int BPF_KPROBE(__pthread_rwlock_tryrdlock_enter, void *__rwlock)
SEC("uretprobe/__pthread_rwlock_tryrdlock")
int BPF_KRETPROBE(__pthread_rwlock_tryrdlock_exit,int ret)
{
- record_lock_exit(target_tgid,ignore_tgid,5,2,ret,&lock_rb,&proc_lock,&locktype);
+ record_lock_exit(ignore_tgid,5,2,ret,&lock_rb,&proc_lock,&locktype,&lock_ctrl_map);
return 0;
}
@@ -141,7 +147,7 @@ int BPF_KRETPROBE(__pthread_rwlock_tryrdlock_exit,int ret)
SEC("uprobe/__pthread_rwlock_wrlock")
int BPF_KPROBE(__pthread_rwlock_wrlock_enter, void *__rwlock)
{
- record_lock_enter(target_tgid,ignore_tgid,7,2,__rwlock,&lock_rb,&proc_lock);
+ record_lock_enter(ignore_tgid,7,2,__rwlock,&lock_rb,&proc_lock,&lock_ctrl_map);
return 0;
}
@@ -149,7 +155,7 @@ int BPF_KPROBE(__pthread_rwlock_wrlock_enter, void *__rwlock)
SEC("uretprobe/__pthread_rwlock_wrlock")
int BPF_KRETPROBE(__pthread_rwlock_wrlock_exit,int ret)
{
- record_lock_exit(target_tgid,ignore_tgid,8,2,ret,&lock_rb,&proc_lock,&locktype);
+ record_lock_exit(ignore_tgid,8,2,ret,&lock_rb,&proc_lock,&locktype,&lock_ctrl_map);
return 0;
}
@@ -157,7 +163,7 @@ int BPF_KRETPROBE(__pthread_rwlock_wrlock_exit,int ret)
SEC("uprobe/__pthread_rwlock_trywrlock")
int BPF_KPROBE(__pthread_rwlock_trywrlock_enter, void *__rwlock)
{
- record_lock_enter(target_tgid,ignore_tgid,7,2,__rwlock,&lock_rb,&proc_lock);
+ record_lock_enter(ignore_tgid,7,2,__rwlock,&lock_rb,&proc_lock,&lock_ctrl_map);
return 0;
}
@@ -165,7 +171,7 @@ int BPF_KPROBE(__pthread_rwlock_trywrlock_enter, void *__rwlock)
SEC("uretprobe/__pthread_rwlock_trywrlock")
int BPF_KRETPROBE(__pthread_rwlock_trywrlock_exit,int ret)
{
- record_lock_exit(target_tgid,ignore_tgid,8,2,ret,&lock_rb,&proc_lock,&locktype);
+ record_lock_exit(ignore_tgid,8,2,ret,&lock_rb,&proc_lock,&locktype,&lock_ctrl_map);
return 0;
}
@@ -173,7 +179,7 @@ int BPF_KRETPROBE(__pthread_rwlock_trywrlock_exit,int ret)
SEC("uprobe/__pthread_rwlock_unlock")
int BPF_KPROBE(__pthread_rwlock_unlock_enter, void *__rwlock)
{
- record_unlock_enter(target_tgid,ignore_tgid,2,__rwlock,&proc_unlock);
+ record_unlock_enter(ignore_tgid,2,__rwlock,&proc_unlock,&lock_ctrl_map);
return 0;
}
@@ -181,7 +187,7 @@ int BPF_KPROBE(__pthread_rwlock_unlock_enter, void *__rwlock)
SEC("uretprobe/__pthread_rwlock_unlock")
int BPF_KRETPROBE(__pthread_rwlock_unlock_exit)
{
- record_unlock_exit(target_tgid,ignore_tgid,0,2,&lock_rb,&proc_unlock,&locktype);
+ record_unlock_exit(ignore_tgid,0,2,&lock_rb,&proc_unlock,&locktype,&lock_ctrl_map);
return 0;
}
@@ -190,7 +196,7 @@ int BPF_KRETPROBE(__pthread_rwlock_unlock_exit)
SEC("uprobe/pthread_spin_lock")
int BPF_KPROBE(pthread_spin_lock_enter, void *__spinlock)
{
- record_lock_enter(target_tgid,ignore_tgid,10,3,__spinlock,&lock_rb,&proc_lock);
+ record_lock_enter(ignore_tgid,10,3,__spinlock,&lock_rb,&proc_lock,&lock_ctrl_map);
return 0;
}
@@ -198,7 +204,7 @@ int BPF_KPROBE(pthread_spin_lock_enter, void *__spinlock)
SEC("uretprobe/pthread_spin_lock")
int BPF_KRETPROBE(pthread_spin_lock_exit,int ret)
{
- record_lock_exit(target_tgid,ignore_tgid,11,3,ret,&lock_rb,&proc_lock,&locktype);
+ record_lock_exit(ignore_tgid,11,3,ret,&lock_rb,&proc_lock,&locktype,&lock_ctrl_map);
return 0;
}
@@ -206,7 +212,7 @@ int BPF_KRETPROBE(pthread_spin_lock_exit,int ret)
SEC("uprobe/pthread_spin_trylock")
int BPF_KPROBE(pthread_spin_trylock_enter, void *__spinlock)
{
- record_lock_enter(target_tgid,ignore_tgid,10,3,__spinlock,&lock_rb,&proc_lock);
+ record_lock_enter(ignore_tgid,10,3,__spinlock,&lock_rb,&proc_lock,&lock_ctrl_map);
return 0;
}
@@ -214,7 +220,7 @@ int BPF_KPROBE(pthread_spin_trylock_enter, void *__spinlock)
SEC("uretprobe/pthread_spin_trylock")
int BPF_KRETPROBE(pthread_spin_trylock_exit,int ret)
{
- record_lock_exit(target_tgid,ignore_tgid,11,3,ret,&lock_rb,&proc_lock,&locktype);
+ record_lock_exit(ignore_tgid,11,3,ret,&lock_rb,&proc_lock,&locktype,&lock_ctrl_map);
return 0;
}
@@ -222,7 +228,7 @@ int BPF_KRETPROBE(pthread_spin_trylock_exit,int ret)
SEC("uprobe/pthread_spin_unlock")
int BPF_KPROBE(pthread_spin_unlock_enter, void *__spinlock)
{
- record_unlock_enter(target_tgid,ignore_tgid,3,__spinlock,&proc_unlock);
+ record_unlock_enter(ignore_tgid,3,__spinlock,&proc_unlock,&lock_ctrl_map);
return 0;
}
@@ -230,7 +236,7 @@ int BPF_KPROBE(pthread_spin_unlock_enter, void *__spinlock)
SEC("uretprobe/pthread_spin_unlock")
int BPF_KRETPROBE(pthread_spin_unlock_exit)
{
- record_unlock_exit(target_tgid,ignore_tgid,12,3,&lock_rb,&proc_unlock,&locktype);
+ record_unlock_exit(ignore_tgid,12,3,&lock_rb,&proc_unlock,&locktype,&lock_ctrl_map);
return 0;
}
\ No newline at end of file
diff --git a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/bpf/resource_image.bpf.c b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/bpf/resource_image.bpf.c
index ceeed1b87..3ae375525 100644
--- a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/bpf/resource_image.bpf.c
+++ b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/bpf/resource_image.bpf.c
@@ -25,10 +25,14 @@
char LICENSE[] SEC("license") = "Dual BSD/GPL";
-const volatile pid_t target_pid = -1;
-const volatile int target_cpu_id = -1;
const volatile pid_t ignore_tgid = -1;
-const volatile pid_t target_tgid = -1;
+
+struct {
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, int);
+ __type(value, struct rsc_ctrl);
+} rsc_ctrl_map SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_HASH);
@@ -47,6 +51,12 @@ struct {
SEC("kprobe/finish_task_switch.isra.0")
int kprobe__finish_task_switch(struct pt_regs *ctx)
{
+ int key = 0;
+ struct rsc_ctrl *rsc_ctrl;
+ rsc_ctrl = bpf_map_lookup_elem(&rsc_ctrl_map,&key);
+ if(!rsc_ctrl || !rsc_ctrl->rsc_func)
+ return 0;
+
struct task_struct *prev = (struct task_struct *)PT_REGS_PARM1(ctx);
pid_t prev_pid = BPF_CORE_READ(prev,pid);
int prev_cpu = bpf_get_smp_processor_id();
@@ -56,8 +66,8 @@ int kprobe__finish_task_switch(struct pt_regs *ctx)
int next_cpu = prev_cpu;
int next_tgid = BPF_CORE_READ(next,tgid);
- if(prev_tgid!=ignore_tgid && ((target_pid==-1 && target_tgid==-1) || (target_pid!=0 && prev_pid==target_pid) ||
- (target_pid==0 && prev_pid==target_pid && prev_cpu==target_cpu_id) || (prev_tgid==target_tgid))){
+ if((rsc_ctrl->enable_myproc || prev_tgid!=ignore_tgid) && ((rsc_ctrl->target_pid==-1 && rsc_ctrl->target_tgid==-1) || (rsc_ctrl->target_pid!=0 && prev_pid==rsc_ctrl->target_pid) ||
+ (rsc_ctrl->target_pid==0 && prev_pid==rsc_ctrl->target_pid && prev_cpu==rsc_ctrl->target_cpu_id) || (prev_tgid==rsc_ctrl->target_tgid))){
struct proc_id prev_pd = {};
prev_pd.pid = prev_pid;
if(prev_pid == 0) prev_pd.cpu_id = prev_cpu;
@@ -87,6 +97,8 @@ int kprobe__finish_task_switch(struct pt_regs *ctx)
#endif */
prev_total.pid = prev_pd.pid;
+ if(rsc_ctrl->target_tgid != -1) prev_total.tgid = prev_tgid;
+ else prev_total.tgid = -1;
prev_total.cpu_id = prev_cpu;
prev_total.time = bpf_ktime_get_ns() - prev_start->time;
prev_total.memused = memused;
@@ -126,9 +138,9 @@ int kprobe__finish_task_switch(struct pt_regs *ctx)
}
}
}
-
- if(next_tgid!=ignore_tgid && ((target_pid==-1 && target_tgid==-1) || (target_pid!=0 && next_pid==target_pid) ||
- (target_pid==0 && next_pid==target_pid && next_cpu==target_cpu_id) || (next_tgid==target_tgid))){
+
+ if((rsc_ctrl->enable_myproc || next_tgid!=ignore_tgid) && ((rsc_ctrl->target_pid==-1 && rsc_ctrl->target_tgid==-1) || (rsc_ctrl->target_pid!=0 && next_pid==rsc_ctrl->target_pid) ||
+ (rsc_ctrl->target_pid==0 && next_pid==rsc_ctrl->target_pid && next_cpu==rsc_ctrl->target_cpu_id) || (next_tgid==rsc_ctrl->target_tgid))){
struct proc_id next_pd = {};
struct start_rsc next_start={};
diff --git a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/bpf/schedule_image.bpf.c b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/bpf/schedule_image.bpf.c
index 58dab8e99..5cf7fb920 100644
--- a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/bpf/schedule_image.bpf.c
+++ b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/bpf/schedule_image.bpf.c
@@ -24,9 +24,14 @@
char LICENSE[] SEC("license") = "Dual BSD/GPL";
-const volatile pid_t target_pid = -1;
-const volatile int target_cpu_id = -1;
-const volatile int target_tgid = -1;
+const int key = 0;
+
+struct {
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, int);
+ __type(value, struct sched_ctrl);
+} sched_ctrl_map SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_HASH);
@@ -66,7 +71,13 @@ struct {
SEC("tp_btf/sched_wakeup")
int BPF_PROG(sched_wakeup, struct task_struct *p)
{
+ struct sched_ctrl *sched_ctrl;
+ sched_ctrl = bpf_map_lookup_elem(&sched_ctrl_map,&key);
+ if(!sched_ctrl || !sched_ctrl->sched_func)
+ return 0;
+
pid_t pid = BPF_CORE_READ(p,pid);
+ int tgid = BPF_CORE_READ(p,tgid);
int cpu = bpf_get_smp_processor_id();
struct schedule_event *schedule_event;
struct proc_id pd = {};
@@ -80,6 +91,7 @@ int BPF_PROG(sched_wakeup, struct task_struct *p)
bool e_add = false;
schedule_event.pid = pid;
+ schedule_event.tgid = tgid;
// 提前将 count 值赋值为 1,避免输出时进程还没有被调度,导致除数出现 0 的情况
schedule_event.count = 1;
schedule_event.enter_time = current_time;
@@ -96,7 +108,13 @@ int BPF_PROG(sched_wakeup, struct task_struct *p)
SEC("tp_btf/sched_wakeup_new")
int BPF_PROG(sched_wakeup_new, struct task_struct *p)
{
+ struct sched_ctrl *sched_ctrl;
+ sched_ctrl = bpf_map_lookup_elem(&sched_ctrl_map,&key);
+ if(!sched_ctrl || !sched_ctrl->sched_func)
+ return 0;
+
pid_t pid = BPF_CORE_READ(p,pid);
+ int tgid = BPF_CORE_READ(p,tgid);
int cpu = bpf_get_smp_processor_id();
struct schedule_event *schedule_event;
struct proc_id pd = {};
@@ -110,6 +128,7 @@ int BPF_PROG(sched_wakeup_new, struct task_struct *p)
bool e_add = false;
schedule_event.pid = pid;
+ schedule_event.tgid = tgid;
schedule_event.count = 1;
schedule_event.enter_time = current_time;
@@ -125,7 +144,13 @@ int BPF_PROG(sched_wakeup_new, struct task_struct *p)
SEC("tp_btf/sched_switch")
int BPF_PROG(sched_switch, bool preempt, struct task_struct *prev, struct task_struct *next)
{
+ struct sched_ctrl *sched_ctrl;
+ sched_ctrl = bpf_map_lookup_elem(&sched_ctrl_map,&key);
+ if(!sched_ctrl || !sched_ctrl->sched_func)
+ return 0;
+
pid_t prev_pid = BPF_CORE_READ(prev,pid);
+ int prev_tgid = BPF_CORE_READ(prev,tgid);
int prev_cpu = bpf_get_smp_processor_id();
unsigned int prev_state = BPF_CORE_READ(prev,__state);
pid_t next_pid = BPF_CORE_READ(next,pid);
@@ -152,6 +177,7 @@ int BPF_PROG(sched_switch, bool preempt, struct task_struct *prev, struct task_s
bool e_add = false;
schedule_event.pid = prev_pid;
+ schedule_event.tgid = prev_tgid;
schedule_event.count = 1;
schedule_event.enter_time = current_time;
@@ -184,13 +210,13 @@ int BPF_PROG(sched_switch, bool preempt, struct task_struct *prev, struct task_s
schedule_event->min_delay = this_delay;
/* 若指定 target 进程,则单独记录 target 进程的调度信息 */
- if(target_pid!=-1 && ((target_pid!=0 && next_pid==target_pid) ||
- (target_pid==0 && next_pid==target_pid && next_cpu==target_cpu_id))){
+ if(sched_ctrl->target_pid!=-1 && ((sched_ctrl->target_pid!=0 && next_pid==sched_ctrl->target_pid) ||
+ (sched_ctrl->target_pid==0 && next_pid==sched_ctrl->target_pid && next_cpu==sched_ctrl->target_cpu_id))){
bpf_map_update_elem(&target_schedule,&key,schedule_event,BPF_ANY);
}
/* 记录指定的线程组调度信息 */
- if(next_tgid == target_tgid){
+ if(next_tgid == sched_ctrl->target_tgid){
bpf_map_update_elem(&tg_schedule,&next_pid,schedule_event,BPF_ANY);
}
@@ -221,6 +247,11 @@ int BPF_PROG(sched_switch, bool preempt, struct task_struct *prev, struct task_s
SEC("tracepoint/sched/sched_process_exit")
int sched_process_exit(void *ctx)
{
+ struct sched_ctrl *sched_ctrl;
+ sched_ctrl = bpf_map_lookup_elem(&sched_ctrl_map,&key);
+ if(!sched_ctrl || !sched_ctrl->sched_func)
+ return 0;
+
struct task_struct *p = (struct task_struct *)bpf_get_current_task();
pid_t pid = BPF_CORE_READ(p,pid);
int tgid = BPF_CORE_READ(p,tgid);
@@ -244,8 +275,8 @@ int sched_process_exit(void *ctx)
}
// 若目标进程退出,删除 target_schedule map 中的数据
- if(target_pid!=-1 && ((target_pid!=0 && pid==target_pid) ||
- (target_pid==0 && pid==target_pid && cpu==target_cpu_id))){
+ if(sched_ctrl->target_pid!=-1 && ((sched_ctrl->target_pid!=0 && pid==sched_ctrl->target_pid) ||
+ (sched_ctrl->target_pid==0 && pid==sched_ctrl->target_pid && cpu==sched_ctrl->target_cpu_id))){
schedule_event = bpf_map_lookup_elem(&target_schedule,&key);
if(schedule_event){
// 将 count 设置成 0 即可实现目标进程退出标志
@@ -254,7 +285,7 @@ int sched_process_exit(void *ctx)
}
// 若目标进程中的线程退出,删除 tg_schedule map 中的数据
- if(tgid == target_tgid){
+ if(tgid == sched_ctrl->target_tgid){
bpf_map_delete_elem(&tg_schedule,&pid);
}
diff --git a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/bpf/syscall_image.bpf.c b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/bpf/syscall_image.bpf.c
index 57f9851ff..68d8f29d5 100644
--- a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/bpf/syscall_image.bpf.c
+++ b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/bpf/syscall_image.bpf.c
@@ -24,10 +24,15 @@
char LICENSE[] SEC("license") = "Dual BSD/GPL";
-const volatile pid_t target_pid = -1;
-const volatile pid_t target_tgid = -1;
-const volatile int syscalls = 0;
const volatile pid_t ignore_tgid = -1;
+const int key = 0;
+
+struct {
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, int);
+ __type(value, struct sc_ctrl);
+} sc_ctrl_map SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_HASH);
@@ -44,10 +49,15 @@ struct {
SEC("tracepoint/raw_syscalls/sys_enter")
int sys_enter(struct trace_event_raw_sys_enter *args)
{
+ struct sc_ctrl *sc_ctrl;
+ sc_ctrl = bpf_map_lookup_elem(&sc_ctrl_map,&key);
+ if(!sc_ctrl || !sc_ctrl->sc_func)
+ return 0;
+
pid_t pid = bpf_get_current_pid_tgid();
int tgid = bpf_get_current_pid_tgid() >> 32;
- if(tgid!=ignore_tgid/* && (target_pid==-1 || pid==target_pid)*/){
+ if(sc_ctrl->enable_myproc || tgid!=ignore_tgid){
u64 current_time = bpf_ktime_get_ns();
struct syscall_seq * syscall_seq;
@@ -58,8 +68,8 @@ int sys_enter(struct trace_event_raw_sys_enter *args)
syscall_seq.pid = pid;
syscall_seq.enter_time = current_time;
syscall_seq.count = 1;
- if((target_tgid==-1 && (target_pid==-1 || pid==target_pid)) ||
- (target_tgid!=-1 && tgid == target_tgid)){
+ if((sc_ctrl->target_tgid==-1 && (sc_ctrl->target_pid==-1 || pid==sc_ctrl->target_pid)) ||
+ (sc_ctrl->target_tgid!=-1 && tgid == sc_ctrl->target_tgid)){
syscall_seq.record_syscall[0] = (int)args->id;
}
@@ -67,14 +77,14 @@ int sys_enter(struct trace_event_raw_sys_enter *args)
}else{
syscall_seq->enter_time = current_time;
if(syscall_seq->count == 0){
- if((target_tgid==-1 && (target_pid==-1 || pid==target_pid)) || (target_tgid!=-1 && tgid == target_tgid)){
+ if((sc_ctrl->target_tgid==-1 && (sc_ctrl->target_pid==-1 || pid==sc_ctrl->target_pid)) || (sc_ctrl->target_tgid!=-1 && tgid == sc_ctrl->target_tgid)){
syscall_seq->record_syscall[syscall_seq->count] = (int)args->id;
}
syscall_seq->count ++;
}else if (syscall_seq->count <= MAX_SYSCALL_COUNT-1 && syscall_seq->count > 0 &&
syscall_seq->record_syscall+syscall_seq->count <= syscall_seq->record_syscall+(MAX_SYSCALL_COUNT-1)){
- if((target_tgid==-1 && (target_pid==-1 || pid==target_pid)) ||
- (target_tgid!=-1 && tgid == target_tgid)){
+ if((sc_ctrl->target_tgid==-1 && (sc_ctrl->target_pid==-1 || pid==sc_ctrl->target_pid)) ||
+ (sc_ctrl->target_tgid!=-1 && tgid == sc_ctrl->target_tgid)){
syscall_seq->record_syscall[syscall_seq->count] = (int)args->id;
}
syscall_seq->count ++;
@@ -88,10 +98,15 @@ int sys_enter(struct trace_event_raw_sys_enter *args)
SEC("tracepoint/raw_syscalls/sys_exit")
int sys_exit(struct trace_event_raw_sys_exit *args)
{
+ struct sc_ctrl *sc_ctrl;
+ sc_ctrl = bpf_map_lookup_elem(&sc_ctrl_map,&key);
+ if(!sc_ctrl || !sc_ctrl->sc_func)
+ return 0;
+
pid_t pid = bpf_get_current_pid_tgid();
int tgid = bpf_get_current_pid_tgid() >> 32;
- if(tgid!=ignore_tgid/* && (target_pid==-1 || pid==target_pid)*/){
+ if(sc_ctrl->enable_myproc || tgid!=ignore_tgid){
u64 current_time = bpf_ktime_get_ns();
long long unsigned int this_delay;
struct syscall_seq * syscall_seq;
@@ -103,7 +118,7 @@ int sys_exit(struct trace_event_raw_sys_exit *args)
this_delay = current_time-syscall_seq->enter_time;
- if(syscall_seq->count < syscalls){
+ if(syscall_seq->count < sc_ctrl->syscalls){
syscall_seq->sum_delay += this_delay;
if(this_delay > syscall_seq->max_delay)
syscall_seq->max_delay = this_delay;
@@ -117,8 +132,8 @@ int sys_exit(struct trace_event_raw_sys_exit *args)
syscall_seq->max_delay = this_delay;
if(syscall_seq->min_delay==0 || this_delaymin_delay)
syscall_seq->min_delay = this_delay;
- if((target_tgid==-1 && (target_pid==-1 || pid==target_pid)) ||
- (target_tgid!=-1 && tgid == target_tgid)){
+ if((sc_ctrl->target_tgid==-1 && (sc_ctrl->target_pid==-1 || pid==sc_ctrl->target_pid)) ||
+ (sc_ctrl->target_tgid!=-1 && tgid == sc_ctrl->target_tgid)){
syscall_seq->proc_count += syscall_seq->count;
syscall_seq->proc_sd += syscall_seq->sum_delay;
}
@@ -136,8 +151,8 @@ int sys_exit(struct trace_event_raw_sys_exit *args)
e->count = syscall_seq->count;
for(int i=0; i<=syscall_seq->count-1 && i<=MAX_SYSCALL_COUNT-1; i++)
e->record_syscall[i] = syscall_seq->record_syscall[i];
- if((target_tgid==-1 && (target_pid==-1 || pid==target_pid)) ||
- (target_tgid!=-1 && tgid == target_tgid)){
+ if((sc_ctrl->target_tgid==-1 && (sc_ctrl->target_pid==-1 || pid==sc_ctrl->target_pid)) ||
+ (sc_ctrl->target_tgid!=-1 && tgid == sc_ctrl->target_tgid)){
e->proc_count = syscall_seq->proc_count;
e->proc_sd = syscall_seq->proc_sd;
}
@@ -156,6 +171,11 @@ int sys_exit(struct trace_event_raw_sys_exit *args)
SEC("tracepoint/sched/sched_process_exit")
int sched_process_exit(void *ctx)
{
+ struct sc_ctrl *sc_ctrl;
+ sc_ctrl = bpf_map_lookup_elem(&sc_ctrl_map,&key);
+ if(!sc_ctrl || !sc_ctrl->sc_func)
+ return 0;
+
struct task_struct *p = (struct task_struct *)bpf_get_current_task();
pid_t pid = BPF_CORE_READ(p,pid);
diff --git a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/controller.c b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/controller.c
new file mode 100644
index 000000000..121a8fdb1
--- /dev/null
+++ b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/controller.c
@@ -0,0 +1,291 @@
+// Copyright 2023 The LMP Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// author: zhangziheng0525@163.com
+//
+// used to control the execution of proc_image tool
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "proc_image.h"
+#include "hashmap.h"
+#include "helpers.h"
+
+static struct env {
+ // 1代表activate;2代表deactivate;3代表finish
+ int usemode;
+ int pid;
+ int tgid;
+ int cpu_id;
+ int time;
+ int syscalls;
+ bool enable_myproc;
+ bool output_resourse;
+ bool output_schedule;
+ bool create_thread;
+ bool exit_thread;
+ bool enable_resource;
+ bool first_rsc;
+ bool enable_cpu;
+ bool enable_keytime;
+ bool enable_lock;
+ bool enable_syscall;
+ bool enable_schedule;
+} env = {
+ .usemode = 0,
+ .pid = -1,
+ .tgid = -1,
+ .cpu_id = -1,
+ .time = 0,
+ .syscalls = 0,
+ .enable_myproc = false,
+ .output_resourse = false,
+ .output_schedule = false,
+ .create_thread = false,
+ .exit_thread = false,
+ .enable_resource = false,
+ .first_rsc = true,
+ .enable_cpu = false,
+ .enable_keytime = false,
+ .enable_lock = false,
+ .enable_syscall = false,
+ .enable_schedule = false,
+};
+
+const char argp_program_doc[] ="Trace process to get process image.\n";
+
+static const struct argp_option opts[] = {
+ { "activate", 'a', NULL, 0, "Set startup policy of proc_image tool" },
+ { "deactivate", 'd', NULL, 0, "Initialize to the original deactivated state" },
+ { "finish", 'f', NULL, 0, "Finish to run eBPF tool" },
+ { "pid", 'p', "PID", 0, "Process ID to trace" },
+ { "tgid", 'P', "TGID", 0, "Thread group to trace" },
+ { "cpuid", 'c', "CPUID", 0, "Set For Tracing per-CPU Process(other processes don't need to set this parameter)" },
+ { "time", 't', "TIME-SEC", 0, "Max Running Time(0 for infinite)" },
+ { "myproc", 'm', NULL, 0, "Trace the process of the tool itself (not tracked by default)" },
+ { "resource", 'r', NULL, 0, "Collects resource usage information about processes" },
+ { "keytime", 'k', "KEYTIME", 0, "Collects keytime information about processes(0:except CPU kt_info,1:all kt_info,any 0 or 1 when deactivated)" },
+ { "lock", 'l', NULL, 0, "Collects lock information about processes" },
+ { "syscall", 's', "SYSCALLS", 0, "Collects syscall sequence (1~50) information about processes(any 1~50 when deactivated)" },
+ { "schedule", 'S', NULL, 0, "Collects schedule information about processes (trace tool process)" },
+ { NULL, 'h', NULL, OPTION_HIDDEN, "show the full help" },
+ {},
+};
+
+static error_t parse_arg(int key, char *arg, struct argp_state *state)
+{
+ long pid;
+ long tgid;
+ long cpu_id;
+ long syscalls;
+ long enable_cpu;
+ switch (key) {
+ case 'a':
+ env.usemode = 1;
+ break;
+ case 'd':
+ env.usemode = 2;
+ break;
+ case 'f':
+ env.usemode = 3;
+ break;
+ case 'p':
+ errno = 0;
+ pid = strtol(arg, NULL, 10);
+ if (errno || pid < 0) {
+ warn("Invalid PID: %s\n", arg);
+ // 调用argp_usage函数,用于打印用法信息并退出程序
+ argp_usage(state);
+ }
+ env.pid = pid;
+ break;
+ case 'P':
+ errno = 0;
+ tgid = strtol(arg, NULL, 10);
+ if (errno || tgid < 0) {
+ warn("Invalid TGID: %s\n", arg);
+ // 调用argp_usage函数,用于打印用法信息并退出程序
+ argp_usage(state);
+ }
+ env.tgid = tgid;
+ break;
+ case 'c':
+ errno = 0;
+ cpu_id = strtol(arg, NULL, 10);
+ if(cpu_id < 0){
+ warn("Invalid CPUID: %s\n", arg);
+ argp_usage(state);
+ }
+ env.cpu_id = cpu_id;
+ break;
+ case 't':
+ env.time = strtol(arg, NULL, 10);
+ if(env.time) alarm(env.time);
+ break;
+ case 'm':
+ env.enable_myproc = true;
+ break;
+ case 'r':
+ env.enable_resource = true;
+ break;
+ case 'k':
+ enable_cpu = strtol(arg, NULL, 10);
+ if(enable_cpu<0 || enable_cpu>1){
+ warn("Invalid KEYTIME: %s\n", arg);
+ argp_usage(state);
+ }
+ env.enable_cpu = enable_cpu;
+ env.enable_keytime = true;
+ break;
+ case 'l':
+ env.enable_lock = true;
+ break;
+ case 's':
+ syscalls = strtol(arg, NULL, 10);
+ if(syscalls<=0 || syscalls>50){
+ warn("Invalid SYSCALLS: %s\n", arg);
+ argp_usage(state);
+ }
+ env.syscalls = syscalls;
+ env.enable_syscall = true;
+ case 'S':
+ env.enable_schedule = true;
+ break;
+ case 'h':
+ argp_state_help(state, stderr, ARGP_HELP_STD_HELP);
+ break;
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+
+ return 0;
+}
+
+int deactivate_mode(){
+ int err;
+
+ if(env.enable_resource){
+ struct rsc_ctrl rsc_ctrl = {false,-1,-1,false,-1};
+ err = update_rsc_ctrl_map(rsc_ctrl);
+ if(err < 0) return err;
+ }
+
+ if(env.enable_keytime){
+ struct kt_ctrl kt_ctrl = {false,false,false,-1,-1};
+ err = update_kt_ctrl_map(kt_ctrl);
+ if(err < 0) return err;
+ }
+
+ if(env.enable_lock){
+ struct lock_ctrl lock_ctrl = {false,false,-1,-1};
+ err = update_lock_ctrl_map(lock_ctrl);
+ if(err < 0) return err;
+ }
+
+ if(env.enable_syscall){
+ struct sc_ctrl sc_ctrl = {false,false,-1,-1,0};
+ err = update_sc_ctrl_map(sc_ctrl);
+ if(err < 0) return err;
+ }
+
+ if(env.enable_schedule){
+ struct sched_ctrl sched_ctrl = {false,-1,-1,-1};
+ err = update_sched_ctrl_map(sched_ctrl);
+ if(err < 0) return err;
+ }
+
+ return 0;
+}
+
+static void sig_handler(int signo)
+{
+ deactivate_mode();
+}
+
+int main(int argc, char **argv)
+{
+ int err;
+ static const struct argp argp = {
+ .options = opts,
+ .parser = parse_arg,
+ .doc = argp_program_doc,
+ };
+
+ err = argp_parse(&argp, argc, argv, 0, NULL, NULL);
+ if (err)
+ return err;
+
+ signal(SIGALRM,sig_handler);
+ signal(SIGINT,sig_handler);
+ signal(SIGTERM,sig_handler);
+
+ if(env.usemode == 1){ // activate mode
+ if(env.enable_resource){
+ struct rsc_ctrl rsc_ctrl = {true, env.pid, env.cpu_id, env.enable_myproc, env.tgid};
+ err = update_rsc_ctrl_map(rsc_ctrl);
+ if(err < 0) return err;
+ }
+
+ if(env.enable_keytime){
+ struct kt_ctrl kt_ctrl = {true,env.enable_cpu,env.enable_myproc,env.pid,env.tgid};
+ err = update_kt_ctrl_map(kt_ctrl);
+ if(err < 0) return err;
+ }
+
+ if(env.enable_lock){
+ struct lock_ctrl lock_ctrl = {true,env.enable_myproc,env.pid,env.tgid};
+ err = update_lock_ctrl_map(lock_ctrl);
+ if(err < 0) return err;
+ }
+
+ if(env.enable_syscall){
+ struct sc_ctrl sc_ctrl = {true,env.enable_myproc,env.pid,env.tgid,env.syscalls};
+ err = update_sc_ctrl_map(sc_ctrl);
+ if(err < 0) return err;
+ }
+
+ if(env.enable_schedule){
+ struct sched_ctrl sched_ctrl = {true,env.pid,env.cpu_id,env.tgid};
+ err = update_sched_ctrl_map(sched_ctrl);
+ if(err < 0) return err;
+ }
+
+ if(env.time!=0) pause();
+ }else if(env.usemode == 2){ // deactivate mode
+ err = deactivate_mode();
+ if(err<0){
+ fprintf(stderr, "Failed to deactivate\n");
+ return err;
+ }
+ }else if(env.usemode == 3){ // finish mode
+ const char *command = "pkill proc_image";
+ int status = system(command);
+ if (status == -1) {
+ perror("system");
+ }
+ }else{
+ // 输出help信息
+ printf("Please enter the usage mode(activate/deactivate/finish) before selecting the function\n");
+ argp_help(&argp, stderr, ARGP_HELP_LONG, argv[0]);
+ }
+
+ return 0;
+}
\ No newline at end of file
diff --git a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/docs/images/eBPF_proc_image.png b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/docs/images/eBPF_proc_image.png
new file mode 100644
index 000000000..df78641c4
Binary files /dev/null and b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/docs/images/eBPF_proc_image.png differ
diff --git a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/docs/images/visualization_platform.png b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/docs/images/visualization_platform.png
new file mode 100644
index 000000000..039052268
Binary files /dev/null and b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/docs/images/visualization_platform.png differ
diff --git a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/include/helpers.h b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/include/helpers.h
index 7ebfbaf47..617b314cb 100644
--- a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/include/helpers.h
+++ b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/include/helpers.h
@@ -24,7 +24,7 @@
.func_name = #sym_name); \
skel->links.prog_name = bpf_program__attach_uprobe_opts( \
skel->progs.prog_name, \
- env.pid, \
+ -1, \
object, \
0, \
&uprobe_opts); \
@@ -73,6 +73,12 @@ typedef unsigned int u32;
#define KEYTIME_IMAGE 4
#define SCHEDULE_IMAGE 5
+const char *rsc_ctrl_path = "/sys/fs/bpf/proc_image_map/rsc_ctrl_map";
+const char *kt_ctrl_path = "/sys/fs/bpf/proc_image_map/kt_ctrl_map";
+const char *lock_ctrl_path = "/sys/fs/bpf/proc_image_map/lock_ctrl_map";
+const char *sched_ctrl_path = "/sys/fs/bpf/proc_image_map/sched_ctrl_map";
+const char *sc_ctrl_path = "/sys/fs/bpf/proc_image_map/sc_ctrl_map";
+
struct proc_syscall_info {
int first_syscall;
int second_syscall;
@@ -138,5 +144,114 @@ void update_syscalls(u32 *syscalls, const struct syscall_seq *e, int *first_sysc
*third_syscall = e->record_syscall[i];
}
}
+}
+
+int common_pin_map(struct bpf_map **bpf_map, const struct bpf_object *obj, const char *map_name, const char *ctrl_path)
+{
+ int ret;
+
+ *bpf_map = bpf_object__find_map_by_name(obj, map_name);
+ if (!*bpf_map) {
+ fprintf(stderr, "Failed to find BPF map\n");
+ return -1;
+ }
+ // 用于防止上次没有成功 unpin 掉这个 map
+ bpf_map__unpin(*bpf_map, ctrl_path);
+ ret = bpf_map__pin(*bpf_map, ctrl_path);
+ if (ret){
+ fprintf(stderr, "Failed to pin BPF map\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int update_rsc_ctrl_map(struct rsc_ctrl rsc_ctrl){
+ int err,key = 0;
+ int srcmap_fd;
+
+ srcmap_fd = bpf_obj_get(rsc_ctrl_path);
+ if (srcmap_fd < 0) {
+ fprintf(stderr,"Failed to open rsc_ctrl_map file\n");
+ return srcmap_fd;
+ }
+ err = bpf_map_update_elem(srcmap_fd,&key,&rsc_ctrl, 0);
+ if(err < 0){
+ fprintf(stderr, "Failed to update rsc_ctrl_map elem\n");
+ return err;
+ }
+
+ return 0;
+}
+
+int update_kt_ctrl_map(struct kt_ctrl kt_ctrl){
+ int err,key = 0;
+ int ktmap_fd;
+
+ ktmap_fd = bpf_obj_get(kt_ctrl_path);
+ if (ktmap_fd < 0) {
+ fprintf(stderr,"Failed to open kt_ctrl_map file\n");
+ return ktmap_fd;
+ }
+ err = bpf_map_update_elem(ktmap_fd,&key,&kt_ctrl, 0);
+ if(err < 0){
+ fprintf(stderr, "Failed to update kt_ctrl_map elem\n");
+ return err;
+ }
+
+ return 0;
+}
+
+int update_lock_ctrl_map(struct lock_ctrl lock_ctrl){
+ int err,key = 0;
+ int lockmap_fd;
+
+ lockmap_fd = bpf_obj_get(lock_ctrl_path);
+ if (lockmap_fd < 0) {
+ fprintf(stderr,"Failed to open lock_ctrl_map file\n");
+ return lockmap_fd;
+ }
+ err = bpf_map_update_elem(lockmap_fd,&key,&lock_ctrl, 0);
+ if(err < 0){
+ fprintf(stderr, "Failed to update lock_ctrl_map elem\n");
+ return err;
+ }
+
+ return 0;
+}
+
+int update_sc_ctrl_map(struct sc_ctrl sc_ctrl){
+ int err,key = 0;
+ int scmap_fd;
+
+ scmap_fd = bpf_obj_get(sc_ctrl_path);
+ if (scmap_fd < 0) {
+ fprintf(stderr,"Failed to open sc_ctrl_map file\n");
+ return scmap_fd;
+ }
+ err = bpf_map_update_elem(scmap_fd,&key,&sc_ctrl, 0);
+ if(err < 0){
+ fprintf(stderr, "Failed to update sc_ctrl_map elem\n");
+ return err;
+ }
+
+ return 0;
+}
+
+int update_sched_ctrl_map(struct sched_ctrl sched_ctrl){
+ int err,key = 0;
+ int schedmap_fd;
+
+ schedmap_fd = bpf_obj_get(sched_ctrl_path);
+ if (schedmap_fd < 0) {
+ fprintf(stderr,"Failed to open sched_ctrl_map file\n");
+ return schedmap_fd;
+ }
+ err = bpf_map_update_elem(schedmap_fd,&key,&sched_ctrl, 0);
+ if(err < 0){
+ fprintf(stderr, "Failed to update sched_ctrl_map elem\n");
+ return err;
+ }
+ return 0;
}
\ No newline at end of file
diff --git a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/include/keytime_image.h b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/include/keytime_image.h
index 45c8aa041..c1ee7e6f1 100644
--- a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/include/keytime_image.h
+++ b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/include/keytime_image.h
@@ -17,11 +17,13 @@
// Variable definitions and help functions for keytime in the process
// 记录开始时间,并输出
-static int child_create(int type, pid_t child_pid, pid_t pid, void *child, void *keytime_rb)
+static int child_create(int type, pid_t child_pid, pid_t pid, void *child, void *keytime_rb, int tgid, int target_tgid)
{
struct child_info child_info = {};
child_info.type = type;
child_info.ppid = pid;
+ if(target_tgid != -1) child_info.ptgid = tgid;
+ else child_info.ptgid = -1;
if(bpf_map_update_elem(child, &child_pid, &child_info, BPF_ANY))
return 0;
@@ -32,6 +34,8 @@ static int child_create(int type, pid_t child_pid, pid_t pid, void *child, void
e->type = type;
e->pid = pid;
+ if(target_tgid != -1) e->tgid = tgid;
+ else e->tgid = -1;
e->enable_char_info = false;
e->info_count = 1;
e->info[0] = child_pid;
@@ -54,6 +58,7 @@ static int child_exit(void *child, void *keytime_rb)
e->type = child_info->type + 1;
e->pid = child_info->ppid;
+ e->tgid = child_info->ptgid;
e->enable_char_info = false;
e->info_count = 1;
e->info[0] = child_pid;
diff --git a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/include/lock_image.h b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/include/lock_image.h
index 036286c15..693e804e3 100644
--- a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/include/lock_image.h
+++ b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/include/lock_image.h
@@ -16,12 +16,19 @@
//
// Variable definitions and help functions for lock in the process
-static int record_lock_enter(int target_tgid,pid_t ignore_tgid,int lock_status,int flag,void *__lock,void *lock_rb,void *proc_lock)
+static int record_lock_enter(pid_t ignore_tgid,int lock_status,int flag,void *__lock,void *lock_rb,void *proc_lock,void *lock_ctrl_map)
{
+ int key = 0;
+ struct lock_ctrl *lock_ctrl;
+ lock_ctrl = bpf_map_lookup_elem(lock_ctrl_map,&key);
+ if(!lock_ctrl || !lock_ctrl->lock_func)
+ return 0;
+
pid_t pid = bpf_get_current_pid_tgid();
int tgid = bpf_get_current_pid_tgid() >> 32;
- if(tgid!=ignore_tgid && (target_tgid==-1 || (target_tgid!=-1 && tgid==target_tgid))){
+ if((lock_ctrl->enable_myproc || tgid!=ignore_tgid) && ((lock_ctrl->target_pid==-1 && lock_ctrl->target_tgid==-1) ||
+ (lock_ctrl->target_pid!=0 && pid==lock_ctrl->target_pid) || (lock_ctrl->target_tgid!=0 && tgid==lock_ctrl->target_tgid))){
u64 lock_ptr = (u64)__lock;
struct proc_flag proc_flag = {};
@@ -37,6 +44,8 @@ static int record_lock_enter(int target_tgid,pid_t ignore_tgid,int lock_status,i
e->lock_status = lock_status;
e->pid = pid;
+ if(lock_ctrl->target_tgid != -1) e->tgid = tgid;
+ else e->tgid = -1;
e->lock_ptr = lock_ptr;
e->time = bpf_ktime_get_ns();
@@ -46,12 +55,19 @@ static int record_lock_enter(int target_tgid,pid_t ignore_tgid,int lock_status,i
return 0;
}
-static int record_lock_exit(int target_tgid,pid_t ignore_tgid,int lock_status,int flag,int ret,void *lock_rb,void *proc_lock,void *locktype)
+static int record_lock_exit(pid_t ignore_tgid,int lock_status,int flag,int ret,void *lock_rb,void *proc_lock,void *locktype,void *lock_ctrl_map)
{
+ int key = 0;
+ struct lock_ctrl *lock_ctrl;
+ lock_ctrl = bpf_map_lookup_elem(lock_ctrl_map,&key);
+ if(!lock_ctrl || !lock_ctrl->lock_func)
+ return 0;
+
pid_t pid = bpf_get_current_pid_tgid();
int tgid = bpf_get_current_pid_tgid() >> 32;
- if(tgid!=ignore_tgid && (target_tgid==-1 || (target_tgid!=-1 && tgid==target_tgid))){
+ if((lock_ctrl->enable_myproc || tgid!=ignore_tgid) && ((lock_ctrl->target_pid==-1 && lock_ctrl->target_tgid==-1) ||
+ (lock_ctrl->target_pid!=0 && pid==lock_ctrl->target_pid) || (lock_ctrl->target_tgid!=0 && tgid==lock_ctrl->target_tgid))){
u64 *lock_ptr;
u64 temp_lock_ptr;
struct proc_flag proc_flag = {};
@@ -82,6 +98,8 @@ static int record_lock_exit(int target_tgid,pid_t ignore_tgid,int lock_status,in
e->lock_status = lock_status;
e->pid = pid;
+ if(lock_ctrl->target_tgid != -1) e->tgid = tgid;
+ else e->tgid = -1;
e->ret = ret;
e->lock_ptr = temp_lock_ptr;
e->time = bpf_ktime_get_ns();
@@ -92,12 +110,19 @@ static int record_lock_exit(int target_tgid,pid_t ignore_tgid,int lock_status,in
return 0;
}
-static int record_unlock_enter(int target_tgid,pid_t ignore_tgid,int flag,void *__lock,void *proc_unlock)
+static int record_unlock_enter(pid_t ignore_tgid,int flag,void *__lock,void *proc_unlock,void *lock_ctrl_map)
{
+ int key = 0;
+ struct lock_ctrl *lock_ctrl;
+ lock_ctrl = bpf_map_lookup_elem(lock_ctrl_map,&key);
+ if(!lock_ctrl || !lock_ctrl->lock_func)
+ return 0;
+
pid_t pid = bpf_get_current_pid_tgid();
int tgid = bpf_get_current_pid_tgid() >> 32;
- if(tgid!=ignore_tgid && (target_tgid==-1 || (target_tgid!=-1 && tgid==target_tgid))){
+ if((lock_ctrl->enable_myproc || tgid!=ignore_tgid) && ((lock_ctrl->target_pid==-1 && lock_ctrl->target_tgid==-1) ||
+ (lock_ctrl->target_pid!=0 && pid==lock_ctrl->target_pid) || (lock_ctrl->target_tgid!=0 && tgid==lock_ctrl->target_tgid))){
u64 lock_ptr = (u64)__lock;
struct proc_flag proc_flag = {};
@@ -110,12 +135,19 @@ static int record_unlock_enter(int target_tgid,pid_t ignore_tgid,int flag,void *
return 0;
}
-static int record_unlock_exit(int target_tgid,pid_t ignore_tgid,int lock_status,int flag,void *lock_rb,void *proc_unlock,void *locktype)
+static int record_unlock_exit(pid_t ignore_tgid,int lock_status,int flag,void *lock_rb,void *proc_unlock,void *locktype,void *lock_ctrl_map)
{
+ int key = 0;
+ struct lock_ctrl *lock_ctrl;
+ lock_ctrl = bpf_map_lookup_elem(lock_ctrl_map,&key);
+ if(!lock_ctrl || !lock_ctrl->lock_func)
+ return 0;
+
pid_t pid = bpf_get_current_pid_tgid();
int tgid = bpf_get_current_pid_tgid() >> 32;
- if(tgid!=ignore_tgid && (target_tgid==-1 || (target_tgid!=-1 && tgid==target_tgid))){
+ if((lock_ctrl->enable_myproc || tgid!=ignore_tgid) && ((lock_ctrl->target_pid==-1 && lock_ctrl->target_tgid==-1) ||
+ (lock_ctrl->target_pid!=0 && pid==lock_ctrl->target_pid) || (lock_ctrl->target_tgid!=0 && tgid==lock_ctrl->target_tgid))){
u64 *lock_ptr;
u64 temp_lock_ptr;
struct proc_flag proc_flag = {};
@@ -148,6 +180,8 @@ static int record_unlock_exit(int target_tgid,pid_t ignore_tgid,int lock_status,
e->lock_status = lock_status;
e->pid = pid;
+ if(lock_ctrl->target_tgid != -1) e->tgid = tgid;
+ else e->tgid = -1;
e->lock_ptr = temp_lock_ptr;
e->time = bpf_ktime_get_ns();
diff --git a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/include/proc_image.h b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/include/proc_image.h
index 53575e1b3..ecfc1905f 100644
--- a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/include/proc_image.h
+++ b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/include/proc_image.h
@@ -32,6 +32,14 @@
typedef __u64 stack_trace_t[MAX_STACK_DEPTH];
// resource_image
+struct rsc_ctrl{
+ bool rsc_func;
+ pid_t target_pid;
+ int target_cpu_id;
+ bool enable_myproc;
+ pid_t target_tgid;
+};
+
struct proc_id{
int pid;
int cpu_id;
@@ -45,6 +53,7 @@ struct start_rsc{
struct total_rsc{
int pid;
+ int tgid;
int cpu_id;
long long unsigned int time;
long unsigned int memused;
@@ -53,6 +62,14 @@ struct total_rsc{
};
//syscall_image
+struct sc_ctrl {
+ bool sc_func;
+ bool enable_myproc;
+ pid_t target_pid;
+ pid_t target_tgid;
+ int syscalls;
+};
+
struct syscall_seq{
int pid;
int tgid;
@@ -67,6 +84,13 @@ struct syscall_seq{
};
// lock_image
+struct lock_ctrl{
+ bool lock_func;
+ bool enable_myproc;
+ pid_t target_pid;
+ pid_t target_tgid;
+};
+
struct proc_flag{
int pid;
// 1代表用户态互斥锁
@@ -84,15 +108,25 @@ struct lock_event{
*/
int lock_status;
int pid;
+ int tgid;
int ret;
long long unsigned int lock_ptr;
long long unsigned int time;
};
// keytime_image
+struct kt_ctrl{
+ bool kt_func;
+ bool kt_cpu_func;
+ bool enable_myproc;
+ pid_t target_pid;
+ pid_t target_tgid;
+};
+
struct child_info{
int type;
int ppid;
+ int ptgid;
};
struct keytime_event{
@@ -106,6 +140,7 @@ struct keytime_event{
*/
int type;
int pid;
+ int tgid;
bool enable_char_info;
int info_count;
long long unsigned int info[6];
@@ -118,14 +153,23 @@ struct offcpu_event{
// 为固定值 11,为了标识 offCPU事件
int type;
int pid;
+ int tgid;
long long unsigned int offcpu_time;
__s32 kstack_sz;
stack_trace_t kstack;
};
// schedule_image
+struct sched_ctrl {
+ bool sched_func;
+ pid_t target_pid;
+ int target_cpu_id;
+ int target_tgid;
+};
+
struct schedule_event{
int pid;
+ int tgid;
int prio;
int count;
long long unsigned int enter_time;
diff --git a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/proc_image.c b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/proc_image.c
index 27adbea40..b52a77712 100644
--- a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/proc_image.c
+++ b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/proc_image.c
@@ -42,22 +42,13 @@ static int prev_image = 0;
static volatile bool exiting = false;
static const char object[] = "/usr/lib/x86_64-linux-gnu/libc.so.6";
static struct env {
- int pid;
- int tgid;
int ignore_tgid;
- int cpu_id;
- int time;
- bool enable_myproc;
bool output_resourse;
bool output_schedule;
bool create_thread;
bool exit_thread;
bool enable_resource;
bool first_rsc;
- int syscalls;
-/* int first_syscall;
- int second_syscall;
- int third_syscall; */
u64 sum_delay;
u64 sum_count;
u64 max_delay;
@@ -65,28 +56,22 @@ static struct env {
bool enable_hashmap;
bool enable_syscall;
bool enable_lock;
- bool quote;
int max_args;
bool enable_keytime;
- bool enable_cpu;
int stack_count;
bool enable_schedule;
+ int rsc_prev_tgid;
+ int kt_prev_tgid;
+ int lock_prev_tgid;
+ int sched_prev_tgid;
+ int sc_prev_tgid;
} env = {
- .pid = -1,
- .tgid = -1,
- .cpu_id = -1,
- .time = 0,
- .enable_myproc = false,
.output_resourse = false,
.output_schedule = false,
.create_thread = false,
.exit_thread = false,
.enable_resource = false,
.first_rsc = true,
- .syscalls = 0,
-/* .first_syscall = 0,
- .second_syscall = 0,
- .third_syscall = 0, */
.sum_delay = 0,
.sum_count = 0,
.max_delay = 0,
@@ -94,16 +79,25 @@ static struct env {
.enable_hashmap = false,
.enable_syscall = false,
.enable_lock = false,
- .quote = false,
.max_args = DEFAULT_MAXARGS,
.enable_keytime = false,
- .enable_cpu = false,
.stack_count = 0,
.enable_schedule = false,
+ .rsc_prev_tgid = 0,
+ .kt_prev_tgid = 0,
+ .lock_prev_tgid = 0,
+ .sched_prev_tgid = 0,
+ .sc_prev_tgid = 0,
};
struct hashmap *map = NULL;
+static int scmap_fd;
+static int rscmap_fd;
+static int lockmap_fd;
+static int ktmap_fd;
+static int schedmap_fd;
+
static struct timespec prevtime;
static struct timespec currentime;
@@ -131,100 +125,36 @@ char *task_state[] = {"TASK_RUNNING", "TASK_INTERRUPTIBLE", "TASK_UNINTERRUPTIBL
const char argp_program_doc[] ="Trace process to get process image.\n";
static const struct argp_option opts[] = {
- { "pid", 'p', "PID", 0, "Process ID to trace" },
- { "tgid", 'P', "TGID", 0, "Thread group to trace" },
- { "cpuid", 'c', "CPUID", 0, "Set For Tracing per-CPU Process(other processes don't need to set this parameter)" },
- { "time", 't', "TIME-SEC", 0, "Max Running Time(0 for infinite)" },
- { "myproc", 'm', NULL, 0, "Trace the process of the tool itself (not tracked by default)" },
- { "all", 'a', NULL, 0, "Start all functions(but not track tool progress)" },
- { "resource", 'r', NULL, 0, "Collects resource usage information about processes" },
- { "syscall", 's', "SYSCALLS", 0, "Collects syscall sequence (1~50) information about processes" },
- { "lock", 'l', NULL, 0, "Collects lock information about processes" },
- { "quote", 'q', NULL, 0, "Add quotemarks (\") around arguments" },
- { "keytime", 'k', "ENABLE_CPU", 0, "Collects keytime information about processes(0:except CPU kt_info,1:all kt_info)" },
- { "schedule", 'S', NULL, 0, "Collects schedule information about processes (trace tool process)" },
+ { "all", 'a', NULL, 0, "Attach all eBPF functions(but do not start)" },
+ { "resource", 'r', NULL, 0, "Attach eBPF functions about resource usage(but do not start)" },
+ { "syscall", 's', NULL, 0, "Attach eBPF functions about syscall sequence(but do not start)" },
+ { "lock", 'l', NULL, 0, "Attach eBPF functions about lock(but do not start)" },
+ { "keytime", 'k', NULL, 0, "Attach eBPF functions about keytime(but do not start)" },
+ { "schedule", 'S', NULL, 0, "Attach eBPF functions about schedule (but do not start)" },
{ NULL, 'h', NULL, OPTION_HIDDEN, "show the full help" },
{},
};
static error_t parse_arg(int key, char *arg, struct argp_state *state)
{
- long pid;
- long tgid;
- long cpu_id;
- long syscalls;
- long enable_cpu;
switch (key) {
- case 'p':
- errno = 0;
- pid = strtol(arg, NULL, 10);
- if (errno || pid < 0) {
- warn("Invalid PID: %s\n", arg);
- // 调用argp_usage函数,用于打印用法信息并退出程序
- argp_usage(state);
- }
- env.pid = pid;
- break;
- case 'P':
- errno = 0;
- tgid = strtol(arg, NULL, 10);
- if (errno || tgid < 0) {
- warn("Invalid TGID: %s\n", arg);
- // 调用argp_usage函数,用于打印用法信息并退出程序
- argp_usage(state);
- }
- env.tgid = tgid;
- break;
- case 'c':
- cpu_id = strtol(arg, NULL, 10);
- if(cpu_id < 0){
- warn("Invalid CPUID: %s\n", arg);
- argp_usage(state);
- }
- env.cpu_id = cpu_id;
- break;
- case 't':
- env.time = strtol(arg, NULL, 10);
- if(env.time) alarm(env.time);
- break;
- case 'm':
- env.enable_myproc = true;
- break;
case 'a':
env.enable_resource = true;
- env.syscalls = 10;
env.enable_syscall = true;
env.enable_lock = true;
env.enable_keytime = true;
- env.enable_cpu = true;
env.enable_schedule = true;
break;
case 'r':
env.enable_resource = true;
break;
case 's':
- syscalls = strtol(arg, NULL, 10);
- if(syscalls<=0 && syscalls>50){
- warn("Invalid SYSCALLS: %s\n", arg);
- argp_usage(state);
- }
- env.syscalls = syscalls;
env.enable_syscall = true;
break;
case 'l':
env.enable_lock = true;
break;
- case 'q':
- env.quote = true;
- break;
case 'k':
- errno = 0;
- enable_cpu = strtol(arg, NULL, 10);
- if(errno || (enable_cpu<0 && enable_cpu>1)){
- warn("Invalid KEYTIME: %s\n", arg);
- argp_usage(state);
- }
- env.enable_cpu = enable_cpu;
env.enable_keytime = true;
break;
case 'S':
@@ -240,16 +170,25 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state)
return 0;
}
-static int print_resource(struct bpf_map *map)
+static int print_resource(struct bpf_map *map,int rscmap_fd)
{
- struct proc_id lookup_key = {-1}, next_key;
- int err, fd = bpf_map__fd(map);
+ int err,key = 0;
+ struct rsc_ctrl rsc_ctrl ={};
+ err = bpf_map_lookup_elem(rscmap_fd,&key,&rsc_ctrl);
+ if (err < 0) {
+ fprintf(stderr, "failed to lookup infos: %d\n", err);
+ return -1;
+ }
+ if(!rsc_ctrl.rsc_func)
+ return 0;
if(env.first_rsc){
env.first_rsc = false;
goto delete_elem;
}
-
+
+ struct proc_id lookup_key = {-1,-1}, next_key;
+ int fd = bpf_map__fd(map);
struct total_rsc event;
float pcpu,pmem;
double read_rate,write_rate;
@@ -260,16 +199,25 @@ static int print_resource(struct bpf_map *map)
int min = localTime->tm_min;
int sec = localTime->tm_sec;
long long unsigned int interval;
+ int rsc_cur_tgid = 0;
+
+ if(rsc_ctrl.target_tgid != -1) rsc_cur_tgid = 2;
+ else rsc_cur_tgid = 1;
while (!bpf_map_get_next_key(fd, &lookup_key, &next_key)) {
- if(prev_image != RESOURCE_IMAGE){
+ if(prev_image != RESOURCE_IMAGE || env.rsc_prev_tgid != rsc_cur_tgid){
printf("RESOURCE ------------------------------------------------------------------------------------------------\n");
printf("%-8s ","TIME");
- if(env.tgid != -1) printf("%-6s ","TGID");
+ if(rsc_ctrl.target_tgid != -1){
+ printf("%-6s ","TGID");
+ env.rsc_prev_tgid = 2;
+ }else{
+ env.rsc_prev_tgid = 1;
+ }
printf("%-6s %-6s %-6s %-6s %-12s %-12s\n","PID","CPU-ID","CPU(%)","MEM(%)","READ(kb/s)","WRITE(kb/s)");
prev_image = RESOURCE_IMAGE;
}
-
+
err = bpf_map_lookup_elem(fd, &next_key, &event);
if (err < 0) {
fprintf(stderr, "failed to lookup infos: %d\n", err);
@@ -290,7 +238,7 @@ static int print_resource(struct bpf_map *map)
if(pcpu<=100 && pmem<=100){
printf("%02d:%02d:%02d ",hour,min,sec);
- if(env.tgid != -1) printf("%-6d ",env.tgid);
+ if(rsc_ctrl.target_tgid != -1) printf("%-6d ",event.tgid);
printf("%-6d %-6d %-6.3f %-6.3f %-12.2lf %-12.2lf\n",
event.pid,event.cpu_id,pcpu,pmem,read_rate,write_rate);
}
@@ -318,11 +266,20 @@ static int print_resource(struct bpf_map *map)
return 0;
}
-static int print_schedule(struct bpf_map *proc_map,struct bpf_map *target_map,struct bpf_map *tg_map,struct bpf_map *sys_map)
+static int print_schedule(struct bpf_map *proc_map,struct bpf_map *target_map,struct bpf_map *tg_map,struct bpf_map *sys_map,int schedmap_fd)
{
+ int err,key = 0;
+ struct sched_ctrl sched_ctrl ={};
+
+ err = bpf_map_lookup_elem(schedmap_fd,&key,&sched_ctrl);
+ if (err < 0) {
+ fprintf(stderr, "failed to lookup infos: %d\n", err);
+ return -1;
+ }
+ if(!sched_ctrl.sched_func) return 0;
+
struct proc_id lookup_key = {-1}, next_key;
int l_key = -1, n_key;
- int err;
int proc_fd = bpf_map__fd(proc_map);
int target_fd = bpf_map__fd(target_map);
int tg_fd = bpf_map__fd(tg_map);
@@ -337,17 +294,25 @@ static int print_schedule(struct bpf_map *proc_map,struct bpf_map *target_map,st
u64 proc_avg_delay;
u64 target_avg_delay;
u64 sys_avg_delay;
- int key = 0;
+ int sched_cur_tgid = 0;
- if(prev_image != SCHEDULE_IMAGE){
+ if(sched_ctrl.target_tgid != -1) sched_cur_tgid = 2;
+ else sched_cur_tgid = 1;
+
+ if(prev_image != SCHEDULE_IMAGE || env.sched_prev_tgid != sched_cur_tgid){
printf("SCHEDULE ----------------------------------------------------------------------------------------------------------------------\n");
printf("%-8s ","TIME");
- if(env.tgid != -1) printf("%-6s ","TGID");
+ if(sched_ctrl.target_tgid != -1){
+ printf("%-6s ","TGID");
+ env.sched_prev_tgid = 2;
+ }else{
+ env.sched_prev_tgid = 1;
+ }
printf("%-6s %-4s %s\n","PID","PRIO","| P_AVG_DELAY(ms) S_AVG_DELAY(ms) | P_MAX_DELAY(ms) S_MAX_DELAY(ms) | P_MIN_DELAY(ms) S_MIN_DELAY(ms) |");
prev_image = SCHEDULE_IMAGE;
}
- if(env.pid==-1 && env.tgid==-1){
+ if(sched_ctrl.target_pid==-1 && sched_ctrl.target_tgid==-1){
while (!bpf_map_get_next_key(proc_fd, &lookup_key, &next_key)) {
err = bpf_map_lookup_elem(proc_fd, &next_key, &proc_event);
if (err < 0) {
@@ -369,7 +334,7 @@ static int print_schedule(struct bpf_map *proc_map,struct bpf_map *target_map,st
lookup_key = next_key;
}
- }else if(env.pid!=-1 && env.tgid==-1){
+ }else if(sched_ctrl.target_pid!=-1 && sched_ctrl.target_tgid==-1){
err = bpf_map_lookup_elem(target_fd, &key, &proc_event);
if (err < 0) {
fprintf(stderr, "failed to lookup infos: %d\n", err);
@@ -390,7 +355,7 @@ static int print_schedule(struct bpf_map *proc_map,struct bpf_map *target_map,st
hour,min,sec,proc_event.pid,proc_event.prio,target_avg_delay/1000000.0,sys_avg_delay/1000000.0,
proc_event.max_delay/1000000.0,sys_event.max_delay/1000000.0,proc_event.min_delay/1000000.0,sys_event.min_delay/1000000.0);
}
- }else if(env.pid==-1 && env.tgid!=-1){
+ }else if(sched_ctrl.target_pid==-1 && sched_ctrl.target_tgid!=-1){
while (!bpf_map_get_next_key(tg_fd, &l_key, &n_key)) {
err = bpf_map_lookup_elem(tg_fd, &n_key, &proc_event);
if (err < 0) {
@@ -407,7 +372,7 @@ static int print_schedule(struct bpf_map *proc_map,struct bpf_map *target_map,st
sys_avg_delay = sys_event.sum_delay/sys_event.sum_count;
printf("%02d:%02d:%02d %-6d %-6d %-4d | %-15lf %-15lf | %-15lf %-15lf | %-15lf %-15lf |\n",
- hour,min,sec,env.tgid,proc_event.pid,proc_event.prio,proc_avg_delay/1000000.0,sys_avg_delay/1000000.0,
+ hour,min,sec,proc_event.tgid,proc_event.pid,proc_event.prio,proc_avg_delay/1000000.0,sys_avg_delay/1000000.0,
proc_event.max_delay/1000000.0,sys_event.max_delay/1000000.0,proc_event.min_delay/1000000.0,sys_event.min_delay/1000000.0);
l_key = n_key;
@@ -421,6 +386,16 @@ static int print_schedule(struct bpf_map *proc_map,struct bpf_map *target_map,st
static int print_syscall(void *ctx, void *data,unsigned long data_sz)
{
+ int err,key = 0;
+ struct sc_ctrl sc_ctrl ={};
+
+ err = bpf_map_lookup_elem(scmap_fd,&key,&sc_ctrl);
+ if (err < 0) {
+ fprintf(stderr, "failed to lookup infos: %d\n", err);
+ return -1;
+ }
+ if(!sc_ctrl.sc_func) return 0;
+
const struct syscall_seq *e = data;
u64 avg_delay;
time_t now = time(NULL);
@@ -428,11 +403,20 @@ static int print_syscall(void *ctx, void *data,unsigned long data_sz)
int hour = localTime->tm_hour;
int min = localTime->tm_min;
int sec = localTime->tm_sec;
+ int sc_cur_tgid = 0;
- if(prev_image != SYSCALL_IMAGE){
+ if(sc_ctrl.target_tgid != -1) sc_cur_tgid = 2;
+ else sc_cur_tgid = 1;
+
+ if(prev_image != SYSCALL_IMAGE || env.sc_prev_tgid != sc_cur_tgid){
printf("SYSCALL ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n");
printf("%-8s ","TIME");
- if(env.tgid != -1) printf("%-6s ","TGID");
+ if(sc_ctrl.target_tgid != -1){
+ printf("%-6s ","TGID");
+ env.sc_prev_tgid = 2;
+ }else{
+ env.sc_prev_tgid = 1;
+ }
printf("%-6s %-14s %-14s %-14s %-103s %-8s\n",
"PID","1st/num","2nd/num","3nd/num","| P_AVG_DELAY(ns) S_AVG_DELAY(ns) | P_MAX_DELAY(ns) S_MAX_DELAY(ns) | P_MIN_DELAY(ns) S_MIN_DELAY(ns) |","SYSCALLS");
@@ -455,9 +439,9 @@ static int print_syscall(void *ctx, void *data,unsigned long data_sz)
env.enable_hashmap = true;
}
- if((env.pid==-1 && env.tgid==-1) || e->pid==env.pid || e->tgid==env.tgid){
+ if((sc_ctrl.target_pid==-1 && sc_ctrl.target_tgid==-1) || e->pid==sc_ctrl.target_pid || e->tgid==sc_ctrl.target_tgid){
printf("%02d:%02d:%02d ",hour,min,sec);
- if(env.tgid != -1) printf("%-6d ",env.tgid);
+ if(sc_ctrl.target_tgid != -1) printf("%-6d ",e->tgid);
printf("%-6d ",e->pid);
struct syscall_hash *syscall_hash = (struct syscall_hash *)hashmap_get(map,&(struct syscall_hash){.key=e->pid});
@@ -495,17 +479,26 @@ static int print_syscall(void *ctx, void *data,unsigned long data_sz)
static int print_lock(void *ctx, void *data,unsigned long data_sz)
{
const struct lock_event *e = data;
+ int lock_cur_tgid = 0;
+
+ if(e->tgid != -1) lock_cur_tgid = 2;
+ else lock_cur_tgid = 1;
- if(prev_image != LOCK_IMAGE){
+ if(prev_image != LOCK_IMAGE || env.lock_prev_tgid != lock_cur_tgid){
printf("USERLOCK ------------------------------------------------------------------------------------------------\n");
printf("%-15s ","TIME");
- if(env.tgid != -1) printf("%-6s ","TGID");
+ if(e->tgid != -1){
+ printf("%-6s ","TGID");
+ env.lock_prev_tgid = 2;
+ } else {
+ env.lock_prev_tgid = 1;
+ }
printf("%-6s %-15s %s\n","PID","LockAddr","LockStatus");
prev_image = LOCK_IMAGE;
}
printf("%-15lld ",e->time);
- if(env.tgid != -1) printf("%-6d ",env.tgid);
+ if(e->tgid != -1) printf("%-6d ",e->tgid);
printf("%-6d %-15lld ",e->pid,e->lock_ptr);
if(e->lock_status==2 || e->lock_status==5 || e->lock_status==8 || e->lock_status==11){
printf("%s-%d\n",lock_status[e->lock_status],e->ret);
@@ -540,30 +533,13 @@ static void print_info1(const struct keytime_event *e)
{
int i, args_counter = 0;
- if (env.quote)
- putchar('"');
-
for (i = 0; i < e->info_size && args_counter < e->info_count; i++) {
char c = e->char_info[i];
-
- if (env.quote) {
- if (c == '\0') {
- args_counter++;
- putchar('"');
- putchar(' ');
- if (args_counter < e->info_count) {
- putchar('"');
- }
- } else {
- quoted_symbol(c);
- }
+ if (c == '\0') {
+ args_counter++;
+ putchar(' ');
} else {
- if (c == '\0') {
- args_counter++;
- putchar(' ');
- } else {
- putchar(c);
- }
+ putchar(c);
}
}
if (e->info_count == env.max_args + 1) {
@@ -576,11 +552,7 @@ static void print_info2(const struct keytime_event *e)
int i=0;
for(int tmp=e->info_count; tmp>0 ; tmp--){
- if(env.quote){
- printf("\"%llu\" ",e->info[i++]);
- }else{
- printf("%llu ",e->info[i++]);
- }
+ printf("%llu ",e->info[i++]);
}
}
@@ -605,22 +577,31 @@ static int print_keytime(void *ctx, void *data,unsigned long data_sz)
int hour = localTime->tm_hour;
int min = localTime->tm_min;
int sec = localTime->tm_sec;
+ int kt_cur_tgid = 0;
+
+ if(e->tgid != -1) kt_cur_tgid = 2;
+ else kt_cur_tgid = 1;
if(e->type == 11){
is_offcpu = true;
}
- if(prev_image != KEYTIME_IMAGE){
+ if(prev_image != KEYTIME_IMAGE || env.kt_prev_tgid != kt_cur_tgid){
printf("KEYTIME -------------------------------------------------------------------------------------------------\n");
printf("%-8s ","TIME");
- if(env.tgid != -1) printf("%-6s ","TGID");
+ if(e->tgid != -1){
+ printf("%-6s ","TGID");
+ env.kt_prev_tgid = 2;
+ } else {
+ env.kt_prev_tgid = 1;
+ }
printf("%-6s %-15s %s\n","PID","EVENT","ARGS/RET/OTHERS");
prev_image = KEYTIME_IMAGE;
}
printf("%02d:%02d:%02d ",hour,min,sec);
- if(env.tgid != -1) printf("%-6d ",env.tgid);
+ if(e->tgid != -1) printf("%-6d ",e->tgid);
if(!is_offcpu){
printf("%-6d %-15s ",e->pid,keytime_type[e->type]);
if(e->type==4 || e->type==5 || e->type==6 || e->type==7 || e->type==8 || e->type==9){
@@ -642,7 +623,7 @@ static int print_keytime(void *ctx, void *data,unsigned long data_sz)
if(env.stack_count < 100){
FILE *file = fopen("./.output/data/offcpu_stack.txt", "a");
fprintf(file, "TIME:%02d:%02d:%02d ", hour,min,sec);
- if(env.tgid != -1) fprintf(file, "TGID:%-6d ",env.tgid);
+ if(offcpu_event->tgid != -1) fprintf(file, "TGID:%-6d ",offcpu_event->tgid);
fprintf(file, "PID:%-6d OFFCPU_TIME:%llu\n",offcpu_event->pid,offcpu_event->offcpu_time);
for(int i=0 ; ikstack[i],file);
@@ -653,7 +634,7 @@ static int print_keytime(void *ctx, void *data,unsigned long data_sz)
}else{
FILE *file = fopen("./.output/data/offcpu_stack.txt", "w");
fprintf(file, "TIME:%02d:%02d:%02d ", hour,min,sec);
- if(env.tgid != -1) fprintf(file, "TGID:%-6d ",env.tgid);
+ if(offcpu_event->tgid != -1) fprintf(file, "TGID:%-6d ",offcpu_event->tgid);
fprintf(file, "PID:%-6d OFFCPU_TIME:%llu\n",offcpu_event->pid,offcpu_event->offcpu_time);
for(int i=0 ; ikstack[i],file);
@@ -745,14 +726,20 @@ static void sig_handler(int signo)
int main(int argc, char **argv)
{
struct resource_image_bpf *resource_skel = NULL;
+ struct bpf_map *rsc_ctrl_map = NULL;
struct syscall_image_bpf *syscall_skel = NULL;
struct ring_buffer *syscall_rb = NULL;
+ struct bpf_map *sc_ctrl_map = NULL;
struct lock_image_bpf *lock_skel = NULL;
struct ring_buffer *lock_rb = NULL;
+ struct bpf_map *lock_ctrl_map = NULL;
struct keytime_image_bpf *keytime_skel = NULL;
struct ring_buffer *keytime_rb = NULL;
+ struct bpf_map *kt_ctrl_map = NULL;
struct schedule_image_bpf *schedule_skel = NULL;
+ struct bpf_map *sched_ctrl_map = NULL;
pthread_t thread_enable;
+ int key = 0;
int err;
static const struct argp argp = {
.options = opts,
@@ -770,7 +757,8 @@ int main(int argc, char **argv)
/* 设置libbpf错误和调试信息回调 */
libbpf_set_print(libbpf_print_fn);
- signal(SIGALRM,sig_handler);
+ signal(SIGINT, sig_handler);
+ //signal(SIGTERM, sig_handler);
if(env.enable_resource){
resource_skel = resource_image_bpf__open();
@@ -779,10 +767,7 @@ int main(int argc, char **argv)
return 1;
}
- resource_skel->rodata->target_pid = env.pid;
- resource_skel->rodata->target_cpu_id = env.cpu_id;
- if(!env.enable_myproc) resource_skel->rodata->ignore_tgid = env.ignore_tgid;
- resource_skel->rodata->target_tgid = env.tgid;
+ resource_skel->rodata->ignore_tgid = env.ignore_tgid;
err = resource_image_bpf__load(resource_skel);
if (err) {
@@ -790,6 +775,18 @@ int main(int argc, char **argv)
goto cleanup;
}
+ err = common_pin_map(&rsc_ctrl_map,resource_skel->obj,"rsc_ctrl_map",rsc_ctrl_path);
+ if(err < 0){
+ goto cleanup;
+ }
+ rscmap_fd = bpf_map__fd(rsc_ctrl_map);
+ struct rsc_ctrl init_value= {false,-1,-1,false,-1};
+ err = bpf_map_update_elem(rscmap_fd, &key, &init_value, 0);
+ if(err < 0){
+ fprintf(stderr, "Failed to update elem\n");
+ goto cleanup;
+ }
+
err = resource_image_bpf__attach(resource_skel);
if (err) {
fprintf(stderr, "Failed to attach BPF resource skeleton\n");
@@ -804,10 +801,7 @@ int main(int argc, char **argv)
return 1;
}
- syscall_skel->rodata->target_pid = env.pid;
- syscall_skel->rodata->target_tgid = env.tgid;
- syscall_skel->rodata->syscalls = env.syscalls;
- if(!env.enable_myproc) syscall_skel->rodata->ignore_tgid = env.ignore_tgid;
+ syscall_skel->rodata->ignore_tgid = env.ignore_tgid;
err = syscall_image_bpf__load(syscall_skel);
if (err) {
@@ -815,6 +809,18 @@ int main(int argc, char **argv)
goto cleanup;
}
+ err = common_pin_map(&sc_ctrl_map,syscall_skel->obj,"sc_ctrl_map",sc_ctrl_path);
+ if(err < 0){
+ goto cleanup;
+ }
+ scmap_fd = bpf_map__fd(sc_ctrl_map);
+ struct sc_ctrl init_value= {false,false,-1,-1,0};
+ err = bpf_map_update_elem(scmap_fd, &key, &init_value, 0);
+ if(err < 0){
+ fprintf(stderr, "Failed to update elem\n");
+ goto cleanup;
+ }
+
err = syscall_image_bpf__attach(syscall_skel);
if (err) {
fprintf(stderr, "Failed to attach BPF syscall skeleton\n");
@@ -838,8 +844,7 @@ int main(int argc, char **argv)
return 1;
}
- if(!env.enable_myproc) lock_skel->rodata->ignore_tgid = env.ignore_tgid;
- lock_skel->rodata->target_tgid = env.tgid;
+ lock_skel->rodata->ignore_tgid = env.ignore_tgid;
err = lock_image_bpf__load(lock_skel);
if (err) {
@@ -847,6 +852,18 @@ int main(int argc, char **argv)
goto cleanup;
}
+ err = common_pin_map(&lock_ctrl_map,lock_skel->obj,"lock_ctrl_map",lock_ctrl_path);
+ if(err < 0){
+ goto cleanup;
+ }
+ lockmap_fd = bpf_map__fd(lock_ctrl_map);
+ struct lock_ctrl init_value = {false,false,-1,-1};
+ err = bpf_map_update_elem(lockmap_fd, &key, &init_value, 0);
+ if(err < 0){
+ fprintf(stderr, "Failed to update elem\n");
+ goto cleanup;
+ }
+
/* 附加跟踪点处理程序 */
err = lock_attach(lock_skel);
if (err) {
@@ -871,10 +888,7 @@ int main(int argc, char **argv)
return 1;
}
- keytime_skel->rodata->target_pid = env.pid;
- if(!env.enable_myproc) keytime_skel->rodata->ignore_tgid = env.ignore_tgid;
- keytime_skel->rodata->target_tgid = env.tgid;
- keytime_skel->rodata->enable_cpu = env.enable_cpu;
+ keytime_skel->rodata->ignore_tgid = env.ignore_tgid;
err = keytime_image_bpf__load(keytime_skel);
if (err) {
@@ -887,6 +901,18 @@ int main(int argc, char **argv)
fprintf(stderr, "failed to load kallsyms\n");
goto cleanup;
}
+
+ err = common_pin_map(&kt_ctrl_map,keytime_skel->obj,"kt_ctrl_map",kt_ctrl_path);
+ if(err < 0){
+ goto cleanup;
+ }
+ ktmap_fd = bpf_map__fd(kt_ctrl_map);
+ struct kt_ctrl init_value = {false,false,false,-1,-1};
+ err = bpf_map_update_elem(ktmap_fd, &key, &init_value, 0);
+ if(err < 0){
+ fprintf(stderr, "Failed to update elem\n");
+ goto cleanup;
+ }
/* 附加跟踪点处理程序 */
err = keytime_attach(keytime_skel);
@@ -912,16 +938,24 @@ int main(int argc, char **argv)
return 1;
}
- schedule_skel->rodata->target_pid = env.pid;
- schedule_skel->rodata->target_tgid = env.tgid;
- schedule_skel->rodata->target_cpu_id = env.cpu_id;
-
err = schedule_image_bpf__load(schedule_skel);
if (err) {
fprintf(stderr, "Failed to load and verify BPF schedule skeleton\n");
goto cleanup;
}
+ err = common_pin_map(&sched_ctrl_map,schedule_skel->obj,"sched_ctrl_map",sched_ctrl_path);
+ if(err < 0){
+ goto cleanup;
+ }
+ schedmap_fd = bpf_map__fd(sched_ctrl_map);
+ struct sched_ctrl init_value= {false,-1,-1,-1};
+ err = bpf_map_update_elem(schedmap_fd, &key, &init_value, 0);
+ if(err < 0){
+ fprintf(stderr, "Failed to update elem\n");
+ goto cleanup;
+ }
+
err = schedule_image_bpf__attach(schedule_skel);
if (err) {
fprintf(stderr, "Failed to attach BPF schedule skeleton\n");
@@ -951,7 +985,7 @@ int main(int argc, char **argv)
}
if(env.enable_resource && env.output_resourse){
- err = print_resource(resource_skel->maps.total);
+ err = print_resource(resource_skel->maps.total,rscmap_fd);
/* Ctrl-C will cause -EINTR */
if (err == -EINTR) {
err = 0;
@@ -1003,7 +1037,7 @@ int main(int argc, char **argv)
if(env.enable_schedule && env.output_schedule){
err = print_schedule(schedule_skel->maps.proc_schedule,schedule_skel->maps.target_schedule,
- schedule_skel->maps.tg_schedule,schedule_skel->maps.sys_schedule);
+ schedule_skel->maps.tg_schedule,schedule_skel->maps.sys_schedule,schedmap_fd);
/* Ctrl-C will cause -EINTR */
if (err == -EINTR) {
err = 0;
@@ -1017,16 +1051,31 @@ int main(int argc, char **argv)
/* 卸载BPF程序 */
cleanup:
- resource_image_bpf__destroy(resource_skel);
- ring_buffer__free(syscall_rb);
- syscall_image_bpf__destroy(syscall_skel);
- ring_buffer__free(lock_rb);
- lock_image_bpf__destroy(lock_skel);
- ring_buffer__free(keytime_rb);
- keytime_image_bpf__destroy(keytime_skel);
- schedule_image_bpf__destroy(schedule_skel);
- hashmap_free(map);
- ksyms__free(ksyms);
+ if(env.enable_resource){
+ bpf_map__unpin(rsc_ctrl_map, rsc_ctrl_path);
+ resource_image_bpf__destroy(resource_skel);
+ }
+ if(env.enable_syscall){
+ bpf_map__unpin(sc_ctrl_map, sc_ctrl_path);
+ ring_buffer__free(syscall_rb);
+ hashmap_free(map);
+ syscall_image_bpf__destroy(syscall_skel);
+ }
+ if(env.enable_lock){
+ bpf_map__unpin(lock_ctrl_map, lock_ctrl_path);
+ ring_buffer__free(lock_rb);
+ lock_image_bpf__destroy(lock_skel);
+ }
+ if(env.enable_keytime){
+ bpf_map__unpin(kt_ctrl_map, kt_ctrl_path);
+ ksyms__free(ksyms);
+ ring_buffer__free(keytime_rb);
+ keytime_image_bpf__destroy(keytime_skel);
+ }
+ if(env.enable_schedule){
+ bpf_map__unpin(sched_ctrl_map, sched_ctrl_path);
+ schedule_image_bpf__destroy(schedule_skel);
+ }
return err < 0 ? -err : 0;
}
\ No newline at end of file
diff --git a/eBPF_Visualization/eBPF_prometheus/Makefile b/eBPF_Visualization/eBPF_prometheus/Makefile
index 763e16961..a0f985b7a 100644
--- a/eBPF_Visualization/eBPF_prometheus/Makefile
+++ b/eBPF_Visualization/eBPF_prometheus/Makefile
@@ -2,9 +2,11 @@ Prometheus_image = prom/prometheus
all:
go mod tidy
go build -o data-visual ./main.go
+ @mkdir -p ./.output/data
+ @touch ./.output/data/offcpu_stack.txt
start_service:
./runimages.sh
clean_data:
- rm ./dao/data.db
+ rm -rf ./dao/data.db ./.output/data