From 48d00b1c681667490a9dd2b873f2aedf67220152 Mon Sep 17 00:00:00 2001 From: zhangzihengya Date: Mon, 8 Apr 2024 22:42:14 +0800 Subject: [PATCH 1/8] Supports pre-on-demand mounting, activation and output when in use --- .github/workflows/eBPF_proc_image.yml | 5 +- .gitignore | 1 + .../CPU_Subsystem/eBPF_proc_image/Makefile | 19 +- .../eBPF_proc_image/bpf/keytime_image.bpf.c | 123 ++++-- .../eBPF_proc_image/bpf/lock_image.bpf.c | 52 +-- .../eBPF_proc_image/bpf/resource_image.bpf.c | 28 +- .../eBPF_proc_image/bpf/schedule_image.bpf.c | 49 ++- .../eBPF_proc_image/bpf/syscall_image.bpf.c | 50 ++- .../eBPF_proc_image/controller.c | 291 +++++++++++++++ .../eBPF_proc_image/include/helpers.h | 117 +++++- .../eBPF_proc_image/include/keytime_image.h | 7 +- .../eBPF_proc_image/include/lock_image.h | 50 ++- .../eBPF_proc_image/include/proc_image.h | 44 +++ .../eBPF_proc_image/proc_image.c | 352 +++++++++--------- 14 files changed, 916 insertions(+), 272 deletions(-) create mode 100644 eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/controller.c 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..f38aff3f2 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: $(WORKTOOL) $(CONTROLLER) .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,12 +127,20 @@ $(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 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..1b544bebe 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,18 @@ 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 target_pid = -1; const volatile pid_t ignore_tgid = -1; -const volatile pid_t target_tgid = -1; -const volatile bool enable_cpu = false; +const volatile int key = 0; +// const volatile pid_t target_tgid = -1; +// const volatile bool enable_cpu = false; + +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 +69,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 +91,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 +152,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 +169,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 +185,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_tgid==-1 || + (kt_ctrl->target_tgid!=-1 && tgid==kt_ctrl->target_tgid))){ 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 +207,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 +229,15 @@ 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_tgid!=-1 && tgid==kt_ctrl->target_tgid))){ bool pthread_create_flag = true; bpf_map_update_elem(&pthread_create_enable, ¤t, &pthread_create_flag, BPF_ANY); } @@ -210,10 +248,15 @@ 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_tgid!=-1 && tgid==kt_ctrl->target_tgid))){ bpf_map_delete_elem(&pthread_create_enable, ¤t); } @@ -224,11 +267,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 +285,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 +295,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,6 +313,8 @@ 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]; @@ -276,11 +331,16 @@ int tracepoint__syscalls__sys_enter_exit_group(struct trace_event_raw_sys_enter* 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,6 +349,8 @@ 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]; @@ -305,7 +367,10 @@ int tracepoint__syscalls__sys_enter_exit(struct trace_event_raw_sys_enter* ctx) 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 +379,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 +389,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 +398,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 +408,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..9c46a88e3 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 volatile 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..2f287a021 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 volatile 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/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..a920b12a3 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,17 @@ 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; } 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 +74,20 @@ 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, }; 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 +115,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 +160,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; @@ -262,14 +191,28 @@ static int print_resource(struct bpf_map *map) long long unsigned int interval; while (!bpf_map_get_next_key(fd, &lookup_key, &next_key)) { + err = bpf_map_lookup_elem(fd, &next_key, &event); + if (err < 0) { + fprintf(stderr, "failed to lookup infos: %d\n", err); + return -1; + } + if(prev_image != RESOURCE_IMAGE){ printf("RESOURCE ------------------------------------------------------------------------------------------------\n"); printf("%-8s ","TIME"); - if(env.tgid != -1) printf("%-6s ","TGID"); + if(event.tgid != -1) printf("%-6s ","TGID"); 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); + return -1; + } + + err = bpf_map_lookup_elem(fd, &next_key, &event); if (err < 0) { fprintf(stderr, "failed to lookup infos: %d\n", err); @@ -290,7 +233,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(event.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 +261,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 +289,16 @@ 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; - + if(prev_image != SCHEDULE_IMAGE){ printf("SCHEDULE ----------------------------------------------------------------------------------------------------------------------\n"); printf("%-8s ","TIME"); - if(env.tgid != -1) printf("%-6s ","TGID"); + if(sched_ctrl.target_tgid != -1) printf("%-6s ","TGID"); 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 +320,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 +341,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 +358,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; @@ -428,11 +379,19 @@ 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 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(prev_image != SYSCALL_IMAGE){ printf("SYSCALL ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n"); printf("%-8s ","TIME"); - if(env.tgid != -1) printf("%-6s ","TGID"); + if(sc_ctrl.target_tgid != -1) printf("%-6s ","TGID"); 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 +414,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}); @@ -499,13 +458,13 @@ static int print_lock(void *ctx, void *data,unsigned long data_sz) if(prev_image != LOCK_IMAGE){ printf("USERLOCK ------------------------------------------------------------------------------------------------\n"); printf("%-15s ","TIME"); - if(env.tgid != -1) printf("%-6s ","TGID"); + if(e->tgid != -1) printf("%-6s ","TGID"); 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 +499,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 +518,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++]); } } @@ -613,14 +551,14 @@ static int print_keytime(void *ctx, void *data,unsigned long data_sz) if(prev_image != KEYTIME_IMAGE){ printf("KEYTIME -------------------------------------------------------------------------------------------------\n"); printf("%-8s ","TIME"); - if(env.tgid != -1) printf("%-6s ","TGID"); + if(e->tgid != -1) printf("%-6s ","TGID"); 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 +580,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 +591,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 +683,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 +714,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 +724,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 +732,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 +758,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 +766,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 +801,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 +809,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 +845,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 +858,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 +895,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 +942,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 +994,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 +1008,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 From c9717757b9077d03e8a208f50e7f3d0f2c9bfbf7 Mon Sep 17 00:00:00 2001 From: zhangzihengya Date: Tue, 9 Apr 2024 11:16:17 +0800 Subject: [PATCH 2/8] new framework passes proc_test --- .../CPU_Subsystem/eBPF_proc_image/Makefile | 10 +++++++ .../eBPF_proc_image/bpf/keytime_image.bpf.c | 27 +++++++++---------- .../eBPF_proc_image/bpf/schedule_image.bpf.c | 2 +- .../eBPF_proc_image/bpf/syscall_image.bpf.c | 2 +- 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/Makefile b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/Makefile index f38aff3f2..5bd60cbfd 100644 --- a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/Makefile +++ b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/Makefile @@ -145,6 +145,16 @@ $(WORKTOOL): %: $(OUTPUT)/%.o $(COMMON_OBJ) $(LIBBPF_OBJ) | $(OUTPUT) $(Q)$(CC) $^ $(ALL_LDFLAGS) -lstdc++ -lelf -lz -o $@ @mkdir -p $(OUTPUT)/data @[ -f $(OUTPUT)/data/offcpu_stack.txt ] || touch $(OUTPUT)/data/offcpu_stack.txt + @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/bpf/keytime_image.bpf.c b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/bpf/keytime_image.bpf.c index 1b544bebe..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,11 +27,8 @@ 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 int key = 0; -// const volatile pid_t target_tgid = -1; -// const volatile bool enable_cpu = false; +const int key = 0; struct { __uint(type, BPF_MAP_TYPE_ARRAY); @@ -194,8 +191,8 @@ int BPF_KRETPROBE(fork_exit,int ret) int tgid = bpf_get_current_pid_tgid() >> 32; // 判断是否为父进程触发 - if((kt_ctrl->enable_myproc || tgid!=ignore_tgid) && ret!=0 && (kt_ctrl->target_tgid==-1 || - (kt_ctrl->target_tgid!=-1 && tgid==kt_ctrl->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,tgid,kt_ctrl->target_tgid); } @@ -237,7 +234,8 @@ int BPF_KPROBE(pthread_create_enter) int current = bpf_get_current_pid_tgid(); int tgid = bpf_get_current_pid_tgid() >> 32; - if((kt_ctrl->enable_myproc || tgid!=ignore_tgid) && (kt_ctrl->target_tgid==-1 || (kt_ctrl->target_tgid!=-1 && tgid==kt_ctrl->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); } @@ -256,7 +254,8 @@ int BPF_KRETPROBE(pthread_create_exit,int ret) int current = bpf_get_current_pid_tgid(); int tgid = bpf_get_current_pid_tgid() >> 32; - if((kt_ctrl->enable_myproc || tgid!=ignore_tgid) && (kt_ctrl->target_tgid==-1 || (kt_ctrl->target_tgid!=-1 && tgid==kt_ctrl->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); } @@ -320,11 +319,11 @@ int tracepoint__syscalls__sys_enter_exit_group(struct trace_event_raw_sys_enter* 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; } @@ -356,11 +355,11 @@ int tracepoint__syscalls__sys_enter_exit(struct trace_event_raw_sys_enter* ctx) 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; } 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 9c46a88e3..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,7 +24,7 @@ char LICENSE[] SEC("license") = "Dual BSD/GPL"; -const volatile int key = 0; +const int key = 0; struct { __uint(type, BPF_MAP_TYPE_ARRAY); 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 2f287a021..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 @@ -25,7 +25,7 @@ char LICENSE[] SEC("license") = "Dual BSD/GPL"; const volatile pid_t ignore_tgid = -1; -const volatile int key = 0; +const int key = 0; struct { __uint(type, BPF_MAP_TYPE_ARRAY); From b7dcab749dbbf57ddb1dc878990438a05eca1b88 Mon Sep 17 00:00:00 2001 From: zhangzihengya Date: Tue, 9 Apr 2024 12:35:16 +0800 Subject: [PATCH 3/8] md output --- .../CPU_Subsystem/eBPF_proc_image/Makefile | 4 +- .../eBPF_proc_image/proc_image.c | 109 ++++++++++++------ 2 files changed, 79 insertions(+), 34 deletions(-) diff --git a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/Makefile b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/Makefile index 5bd60cbfd..2c7d12a2a 100644 --- a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/Makefile +++ b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/Makefile @@ -84,7 +84,7 @@ $(call allow-override,CC,$(CROSS_COMPILE)cc) $(call allow-override,LD,$(CROSS_COMPILE)ld) .PHONY: all -all: $(WORKTOOL) $(CONTROLLER) +all: $(CONTROLLER) $(WORKTOOL) SUCCESS_MESSAGE .PHONY: clean clean: @@ -145,6 +145,8 @@ $(WORKTOOL): %: $(OUTPUT)/%.o $(COMMON_OBJ) $(LIBBPF_OBJ) | $(OUTPUT) $(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 " / _ \/ __ / /_/ / /_ / /_/ / ___/ __ \/ ___/ / // __ \`__ \/ __ \`/ __ \`/ _ \\" 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 a920b12a3..b52a77712 100644 --- a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/proc_image.c +++ b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/proc_image.c @@ -60,6 +60,11 @@ static struct env { bool enable_keytime; 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 = { .output_resourse = false, .output_schedule = false, @@ -78,6 +83,11 @@ static struct env { .enable_keytime = 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; @@ -189,30 +199,25 @@ static int print_resource(struct bpf_map *map,int rscmap_fd) 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)) { - err = bpf_map_lookup_elem(fd, &next_key, &event); - if (err < 0) { - fprintf(stderr, "failed to lookup infos: %d\n", err); - return -1; - } - - if(prev_image != RESOURCE_IMAGE){ + if(prev_image != RESOURCE_IMAGE || env.rsc_prev_tgid != rsc_cur_tgid){ printf("RESOURCE ------------------------------------------------------------------------------------------------\n"); printf("%-8s ","TIME"); - if(event.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); - return -1; - } - - + err = bpf_map_lookup_elem(fd, &next_key, &event); if (err < 0) { fprintf(stderr, "failed to lookup infos: %d\n", err); @@ -233,7 +238,7 @@ static int print_resource(struct bpf_map *map,int rscmap_fd) if(pcpu<=100 && pmem<=100){ printf("%02d:%02d:%02d ",hour,min,sec); - if(event.tgid != -1) printf("%-6d ",event.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); } @@ -289,11 +294,20 @@ 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 sched_cur_tgid = 0; + + if(sched_ctrl.target_tgid != -1) sched_cur_tgid = 2; + else sched_cur_tgid = 1; - if(prev_image != SCHEDULE_IMAGE){ + if(prev_image != SCHEDULE_IMAGE || env.sched_prev_tgid != sched_cur_tgid){ printf("SCHEDULE ----------------------------------------------------------------------------------------------------------------------\n"); printf("%-8s ","TIME"); - if(sched_ctrl.target_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; } @@ -372,13 +386,6 @@ 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) { - const struct syscall_seq *e = data; - u64 avg_delay; - time_t now = time(NULL); - struct tm *localTime = localtime(&now); - int hour = localTime->tm_hour; - int min = localTime->tm_min; - int sec = localTime->tm_sec; int err,key = 0; struct sc_ctrl sc_ctrl ={}; @@ -387,11 +394,29 @@ static int print_syscall(void *ctx, void *data,unsigned long data_sz) 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); + struct tm *localTime = localtime(&now); + int hour = localTime->tm_hour; + int min = localTime->tm_min; + int sec = localTime->tm_sec; + int sc_cur_tgid = 0; + + if(sc_ctrl.target_tgid != -1) sc_cur_tgid = 2; + else sc_cur_tgid = 1; - if(prev_image != SYSCALL_IMAGE){ + if(prev_image != SYSCALL_IMAGE || env.sc_prev_tgid != sc_cur_tgid){ printf("SYSCALL ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n"); printf("%-8s ","TIME"); - if(sc_ctrl.target_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"); @@ -454,11 +479,20 @@ 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(e->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; } @@ -543,15 +577,24 @@ 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(e->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; From 54c09619fb702879d26f23fc8037155fee33ae0f Mon Sep 17 00:00:00 2001 From: zhangzihengya Date: Wed, 10 Apr 2024 22:59:48 +0800 Subject: [PATCH 4/8] md readme --- .../CPU_Subsystem/eBPF_proc_image/README.md | 74 ++++++++++-------- .../docs/images/eBPF_proc_image.png | Bin 0 -> 139850 bytes .../docs/images/visualization_platform.png | Bin 0 -> 104774 bytes eBPF_Visualization/eBPF_prometheus/Makefile | 4 +- 4 files changed, 45 insertions(+), 33 deletions(-) create mode 100644 eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/docs/images/eBPF_proc_image.png create mode 100644 eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/docs/images/visualization_platform.png diff --git a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/README.md b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/README.md index 65a9dd56b..28ee71eb4 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 +具体可视化操作可以参考:[进程画像可视化指南](docs/proc_image_vis_guide.md) \ 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 0000000000000000000000000000000000000000..df78641c49d597490dacb139a344313b8b3d7246 GIT binary patch literal 139850 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 E0b!(;`2YX_ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..03905226844c6adaf0f6b26a50781a5a6efac4b9 GIT binary patch literal 104774 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

P}M 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 #s z#jf{8fsBha_fx_g0`oOC8F#ddjIi}&gXX65W!ho|y<29v%f5ncxkspXi`^p8_eQsp zTjmG3$pN6t?wx|dM#GM)ItG9~{0!KcPRsVBdeq{1ZPU5liKq1dAOzkGm_%P7u-Kac zBSvdz-u+YX)xWxxy`)YGaCkF-i*PP_x!`&-*Q+{yQk?0b@UnmeRkzlz(mO?9kKo#S z{r&gTyZ6>Qa2{*FrH%1?Ee7FVy{eo3fc>3L97^={$}?E3uaB7DpIobLRGhfHSz8}|omf{WpoPlc?WFbu7z~Tq<2ntf!EJK z)MlZCxfOseuOj|pg)a2oN9l7aF&8p_Y>XmwVyOR`(F+%x>wTgN0w6CMl|jMs2+}NxfB~;D%qCT3 zOEKm6Guc*<7AvePN2sX9?!B&2E6}LQAj*=`RYW`>S}v(dtXq-~1(vT{(xQ8|xG&S{ zd0h`vMLa(YZ>72JWyNvqWiwBskDXT~?KMxgxF{lnh-L@FZe~yj&g4F!VuC<&wDN@J zg&PA&dEd8H$aQhZIo(_(U3RA{^O_fHqwnsv(n}bx-+AAfHCFFE%(fWQSSuRqQ~n;s z?<^Xt|5D^++F}D@Os`-Xm>bewu;Zmkr4~5O`LVH`FedvFGk`xmAp_`D{GHptj}3k`A3DPyJB`PO;ID-i6k(cnPET z5KVpWftYFC9bZA&JE+?)vH2ZgkzapQAs|VJi~PCb-rAN#x$TI9rF1EDKFvm8R_lcx z`~VHah-{dX6PZABxHymi0tLbX0dj+8u0lc)&;mWr@B{VOVkmm#<9=NE`+)k%lABoSj{@NJbdu=PT17+U>jf&dtN;qxhv9i z7+^#$c~Eyahp?Mk(Y??MBiNs$IW=SjflFT`pV#;c?V|bCkrzvXKrB{rFpwmE{oTd< z{%@XK`+k%~1Nr;Q>lD(dyS=2M;|T4!GR~34ahUyD;+HAJ?2^_)&CSK%Dssae{2p5G zre?nVT=3k5gROKAf&1k*jw?Ti%EeK5n4x@klfY^9$~k^MR5E5oE;3*-3gy+@%@?>K zYv6*)e!R`a!RYlx=X${2gI?2y0urd+e!lyQKtboCfYVCG%6s75tCYo{A_Y?ModF-L zjRjxr$KY#*^7s6Rdak`79NBpWd)nHP>7_%3)k*Qf8vcUG-$VOOCgmuL8u<>B4GuP8 zAKZVS)hc9F`IZ@e{7NdDBtFMk==?nyQTj<%+fAJecZI5v6Xar45Ue=+InQ!#RbRP^ zX40spdO)zj7X+%`_;TSnzma74VW^~T;h*;v!iWi4&v@VUX?7G643jWwEizbDI8FaP z5?~WN_pZ!adP{fW)jLD$Vf7?cYel&$buLPb_3u+(?S~(Rs(IPc zRux=jM>55V$5Ow*xCQy3Z=g;Z1=)K$_{#IWX$|XozaS5L-&j7i$To^Lo5)OnIquPFnRV6;tO?}Gs{N;1+Kp#LIt@%0Ls!{ ze%9-~p%#Aw`M>%Pcbi~zL*Ai}p0sIjEJD=^NvzOYDKqbUIOmuB)y4vaKkdEz89qM2 zzfgLi&5pbF7JE9+yic3JAkeJi{Le3tw+;cdcoagtQDPT5fMbDJ!XJ&5)7#_7M4#9H zSMzDWb@pHHUQOO$tLdY}eH72F(DAT%4|Q+lKD^goqu$j-UvghfwzvBqazU4et(@PC z+PpUNwK9m2KYc#?i&k5=2mT73+p?ERByU`}{e+2t(>nMSenn_D8M=jnoH>(eRu97c zJ9cX97Ap1)^$O4w@8);s(d@a(2wJaRV!9u05I<3f1H6jg_QBj&W&@o%Fb2;RH^_;b_!a57?9b#f(3JZzci<(lobbsQ=Qm;Bh6= zjUvl-<4yiy2hf*u+|{LVM|JeB``6LX2R*Ey@jgWvcO zUU4l?Cgcce^>HOb%Xc+@VXS^7EO&nU-3(^o*tFMOXBL!y9-*AZ@@H4Z4X*EwOC|Es zYG2i^^*!V_TZQry!RpE^1ev=!$YsLWA{ytt%q98WZ1Pe?!2SL7A_{0mlX!mFK5V}w zSxmyqi4d@EsYkP#ecW>?ZMk(JRz^KJv9HkPr6o=BqZ*+jXQnA7itwlEXwqp*(!H+CwAr}iP?8Za*XFA1&-Cq#b%CY zH@$#odvpzoHxFu+l=YeQG!OwXfbh|wP|o4g1n;*W?$W>5`=|QzdPX%eI~F+J5G$s? zcmFlz%v3Mk7u?c`K+i16#Ma~_3DFZ4<=eq~IpxS)Pb|UDTNQE4`>|{p`K5`r1d9tYYD;Reg_~*YckSpYxFUH}?XgG*8v@ z0IIQC?4JePOai0iF}u$|s`0san|y_h1w5T2V@3!FOkfBUbWRmZV_o^|LtCcuhJ#h({aN{wpmRtP^Db36l_2GN)W8?V^aw7+>cfNfb^}Jt#RIh*Z zL#$q&=vhu-(`1u9X&_C2*Q;kc3-g6vPZze}qjOxEdB07Tut%(HT1S*5H&m$&;MxZp z@&3TH_Lql)-#50O0K*5deEY+pHLvJUh1D$K#smud{NvP00`Yz@@}ir)bmkrrW>$>^ z0?EVzh9>F(FRs-a;Y{5xT@LVM@;383yxhyO`BJP9%2vYYDf;SUEVX;mt6)SC;;BUW zY;9@taxNn(ctK1A&Re8BdLuLzWY{MiExBI>S^yC4JP_R+|aOWR)dvdIEx zD2V$3_Yzc4Oj?1V$gJ||=G?+l-o5sAI67Li;7hO2Y___B)J4Cpp^MRC0{dv40=%o@>88U11dOoxgPoxI z5AAwUp}qD8H%BIgto+G->z?#Yg$~sIvD|3O>GR z8L)ytZ2^x@9rd{NVSn?d%d)RoqV9lV$+a>veV+gEKDk5x-h%oF9)0#77io^ye);F& zdVVaznN!ckKHcYEk~P<=EL+oiensSMFq-x{LREpMqp z(g-A%>JUE~?Jow>=ce%H4S@JEl|ElH+iUw{HWsmG;rQ;GiSJ%{7_e%Az~XU0Y(Thm zVA~p;s|hCgE?u8d3tDL1#Ee7CKhjbdnt57Dp4t@unvHRmh9UUUU67}bTUgm7w6`tSk4(@vWJC#dafM*TLn2wyV0nG(e=#d82#NP$6G&_ zjW5EEsI?%X383W2`n+(ml7N{Lh`xdO)dPuhI7!CuC)u^ilF|c~5`b8o^99Hb{&UGG z0Ir!4IA3+4t$*7tsP&L?Q^FYV4anUzTYkC_?*33PbACZp{c?L(e$h-*tl*bE58^73 znUXnYWXOMfU%Y5(_8jKW(6rsQHdd~5duo*&W$ib}NuW}4(02Q3SJ*GfSWmkeeGEG8 z4<0fs*Mc-#XLSYl{Su)GSO{luG8wm zgF?QS+iSrDZ*9+dAH)oeLZDSqq?e&o*IdH1Xw&c2_We!<8hoj>55GMC+kBaCTe1ya zAG4aQOwb>PaVutBYFZn0?JjFAw-}wfzm%*eqTd;tVWfPJiFO<>k0`#e)*Ky5lrqcq zqRd$&I4e0viK*MwE_6J6i*cRR;8#O;|h}gxE(eJ;)+#$ z9OihDQYD!0qpYaS*w|V(&D8bHun3;YLH5-5>V>!uIO4`89M5VNpvG=xE?)?;v>4O$ z+?#~-ai#%}&EOOeLU4M0Td5h#i? z*32p0bzl&76Mv+5WhUM(s_ISY@_uBrL=8~ITki`jaXe9gEs&T5JX}XN^SYZlZ8#gL zZ20Y0+F(os8&gw-=m~oLI1p?~PgYz!nH*UBgP&aE;G#~)M4)k9Y7T@iagvbVaC(JP z@raBKKiEc!!WQb2Xk$l?XN{i^)Mbc?6O{9*ssKS{z}dExtAA1_>m6G9V#wn%iTF($ z+r(zwZSM&C+eUA%?CW(qR;Jl%H!dK@oc>{&$|Kfl5C*Y$buWz%qfeEX)*8<9gp&gn ze6irF?8yZJNp3!_aL9Xw*M&vn^2`=>q_34!*wHno3ZJpOP6{%FxiHZ?_-y~o7*vPj zGV#Qls}QxTyFiMiWoi|W^BZ3%N2{N-O?;!nW@7l0l{59Ox`r9;4<7J&Qi7;9c$04- zYg0vyEtXfKS^WB=8x7GyUPQX%9uYn^lQ0mZ&1H?<+?*bONCKN@w>5m~cDG)D!}>tMME0xt7nx`Y zkRI=Cy_1+9gzyIUgzKqT&3W2xu*$z|xZGYjPWYjTO;fraL4?LOeW#nd?`=J&2>%v5 zHUldhI1lq(jIfYGyE~7}%&byy+%MPj5>Ssw5d~szCiJxA(HGyOvl}5pM#x2I!VB-Ifd-_G&lP-|!9v zlni#(Ofn9e)J*g4K{VdQ<^pv%UiDv<$fxcJ{Fc2bVDD^3*(#hOFSk~`akr)tvzMjQ z=f`(*hrv7`Z^f-m<0(65S5Se(ng!4FRvM96(&wCd*{j!rSG&Wzz45P7u zPnQC}7ifNR*!nO-7Z&g2I-~i|_|!dhmOgYHj7z!j8mEs zhaGH2>?F$aSk+e7KDX2Dr&ozD3dZV~wB1|SyzIr^4CD!z_}Wy7H_x48$1(4^4A%Zq zRYR9tnyA0tig)D$F(#ui$jBTB&qW z)+b(c>=Y#T0+@nDYfefw61Wwy1=L=pwxa}l{T-aJJN>*PuwE{^-zi+V56H{9E7Gwm zB)+hQPmKYYb==rowQZ3M7N^k=+hc$TEPgO$-~e(;q@9Jgo;skDO2_3?%dZEG(=;U- z?H9Lxs)TEAzElV@D^=-L+tlaAQ2!w^-`CRv%#%k=F(!_w-iyERA7j0MCmIKH0y%5M z>#faY0p6Fd0&h2ZxWsD(X?M+(Q(b=!)wdQ-vU+~@KU?y>*p1{uhtz5dOLIWna*tXc z?%@g`P@mM+<#_IY{>R6#8fbX3h&Y@rx{sbM`{-`}HnMOpq~l=@o-I48o&KVVllrg{ z(7v4Gh)4knPEAFwR*2jp&_MFrTj|>R-+8J~`yS``p9{*^4+-_I$LYOfBf{1);7q z@Ejj6)cdP*ZT-q^Uc}zH^Towl^o(uolKF^0zO7ia_`(OzeUjg?`hxoD`VKXdg<7*& z1QJzwH2!~Vrc3tIki0WL4B^;M{&HNP0)d|v88t5eup!d~c5M%)8O_jpi}e@l8DrV9 z`hY%(-Jg8bsVZxAZEWxqaDcFvGr>03mSArve_*BUlfmKV5St+Stq>aoj&-A5SR_mG z0vcZRh7#6Oxd{f#(H!s1WVOWR6F?D%JzTA2U5;2drTze5OW8#p_Pa$fUfrL)`?ZR1M&CsF4JVjr zlMuy$d*vA+{|5hXg(}A0x!H%x(-DbfV2F-DO|*c=o=)Rl#Xu3T=~6;MDcL9&OApzr zU4}xwr%%}*|LxlEWr)V@kA0x>v66qrXO&0|^%4f|&A|wX*>-5IE?I>7vNztIC>mmU zpve=i3&nvYyMYJ?l3~&#%8^>7oGR8A)JA3$zYog*Hykuf)jZtyxe+sbXYK% z8t+r|#-om4`+>xvnrS27dbK_54M_^(f8RPdy>UD1M!<1NMi2wkJF+>PYURGm2S$o} z2e`pM*SafE|5m0f?%g9`r}Jpn*OLqNjyl%uii1>UD;E5++fpcbpZj_yc`fPTH$77s)ykZzNoPk3b6U4g5Dh(SNQuxjd!I zS?2V?icp*_;3HZxYeEO?7M#HQ-w^>GoFnreZvjV;a2m`scnJLo@#5Y?SeTGXdX=?zZxa}=h?DrS<4Z+6!40JocDu&9f{x^2oa;7i7Qiuf~OPQ2D zFW+AF3k6Y-&EyK`JssK}$h01-@h&&7<9LzR3ao}ROOjE?-+uS_+c?}Oc?CaV(T_H} zN?Isb8Jj~uuPYhm98%E^1W_LtyG05QN-^BIc&#*$+26rmKg)4)-3%s;>VbgR(jTdCrJD;b7QD<8=mRGiLq`B;G&hGpUm3CRH+l8s$ z!u&T^03)dV&tof{$7*mWqq0#}u@a{5CC0Z)pg3+AY31rN0&;OEP8JP-Cvsm!-N$(X z*1y8~3yIhIF&1o+>tBLHKRj}NdzIr5ixALj7K&7o|93f%od9!agezaeuMzMiF5+We zIQY@FlymJ@JfPvm=qy;Tkbp09m znTi?u@ZkLNLV={oTxZAf;os2MxW>CIc6W47?Ra=lvFaPxQKX=vn9 z4ehF1w0f;A#0&KYyxIAI@{dv2w@0Ud3HpL+;2|x!$9Qj%-l>1Cv}$5Csq>G8pBy=n zHdLBE{yq*q-fsaE2U#`FM>>pDPPj}rTa*};9l2uam)CEE!AtpSOz~1xnaGy-%EihlW09PFU z2@)%>p3WB#aAJ6E@AenlkrK{jicpPQ_3q}tSCobD}#p@?&#w` z77SoFRg!2|wVsYq`rw;*$IC%AhMv5B_CL>imi(_>kBqFl(T76&J_A@@{U3MxKkr2y zgO?2)Sq;oaAPCF9xu84sUks0Xh~V^1tXaQDvh-#zM9ls8B8lWKihIv81%CM$6nej%IIoc>K{svBg0#e6ObiHi<$k@9|NN2*qJbH!7M5S`w!wB$K=ico|jy zxY$)!-X#v3T`9eZC{F3_=GvNj5nT<3eH;OYK7^%v6(Gz*B(!gNy-~0J=05DgrfHUf z9VI(Mb6LyBbnj&2(2D>i?}Id{WGKp@VW{xIQi(?1q}cCR=aoH>`tYv}#j%{T1K%Z` zj`L)y(Ax#and!fBV>*n72h20E<1%~ekfmYQv~-Us3UaRCp1Hm8fR6l*y{3$t*k<#f z29$w|;qY5cW~P7k{ZoIcX5X(;v3v+axcp}G8N7W28A48rLucDppOL98e7oF{udxrB z6+Nko{p9IPSAgSp&%C?;UFfV6XE+8~V!P+{%*xB|C2j+iW=@_HLr&gHHIifumvGK$ zn!(PVbOU%3CwudNkFgmd!+_HR+8J6$miTnQeicUlL3JuYJ!I9>#kGw81jr)s7i z;JsP=QQjP0cwj348UwIQfUZt1y2Y*>t!0!~uep_pcD@J$f){@~Mbl1>*LD_Yk5;C3 z`T%ecXrDiyZZ566=v7#mkf}^tzQ$1pjm#k9xmTXQ>nif2>)BN~B^WzM4Iq^>BhwYUmyY2@*ZiB9IZr7V0w7emy zj3nrENnKyDW)84iLQbd2^-R-~Pi=|05mU%RsKVJ!maPo1l_$a48 ziS(|u>n)u-DRmDHYOJBHJH=3emdJkAg@-OvJv-eoujONytA`MFo$A72It@WauQSt| zV;(q9$Y}5tmOrkeo_>A4quAi`by^8!#=rhSyr$jA+>-<6it)M*C@!j@gkEYQaN6!u zEL-Ez5VmNj*uXN?Tq}~?eP@}SWST%!(kY?1{B1x0;x@Ofmx?}s@WTDG+5=Ic`J(Ta zBUMOFfQ;NyZp4^u+wZcLZy%mKk}~(cJA08ADN-(rlUabjefsX;$J1wQ4qf%fC7?4C z@`wVy;#J_;Y49eE#L>75H;e*D^Tvh3I2q~`oiNW@ z@Z5VXn%%O~7s_1L&X#i;pqU1$lUt4*vMZX`~bwGsd$q>v3&$6`MKPp%&b>rj&<-Ir>Mw zP8Mohm)YYw_K?|Pb*lRf!V6bDpXwS~A+{E4c zxNi{~NdzOR8$(GCrTcTw;U5nIQ3{oj<-$a!-PH?kt| zpWfl-%aR;OaxHdQ3JZ8x_eNn?ry^}$-Bo{%U@4FkJ02Y4n7JTYWWp=WK!oQyDi4*f zz8+FFt8?AA&#HSYlxdfJIy{tSW0){pQzj)>hHkTVl5;tf-P;%Qoj zRJBs>Svrt_^9kYbQaR z2*DNR(5Ke|0*e^m%V1IwsnZXI(x05TN{5fF{5gBOwusYH!-TJkm%HTZ8&oQ*loXh; zpgxVC_-dX-?XJVkxR`fi_hBx+$O}p?;_}5thTKYwfBen7NAl3GvaMP8Uw&R!VxImW}bD#3eV`#qD_%r!LGv~`wt-42~2~`r)RNRi@82GXDLqhBmDoQmhx)V8j8u> zViKmx^20H7%Mb$=TXxo4f?&UDiW%QSG0R|QdW>g^>OHjcaIzz|;CORTKp$ zjjXhToK3bD?@;KJO@tQULpdtU{&l^A*~*MdLGd2&H#t;vT9Fs7s-lybz^l2HS6Q;Y zzX=YK{amw?mtld$BuRBYaUN3&Z6cAp8H0Nz*Qz2JHg=3_ZHQ=X?jN)lFe?KjoDaoM5ZX2e{26&*)9K*cd{~{>X*w)DdK8y-2uh3*=^Dd zLQb*QrSp@tiIv5Y`1vnK5?_yc2W`P2?7CLSj$;Sd*#Yv^OrmfiSC{NbU_0kBD=@PH zOu}idx?t)u%A$oc?9wHJnZ5(%q6Z5y-O7TGhh8=bBs?yIxgL6OuPJ0QhRKNMs04Ec zzPnfNYu9d%bZ@sWdD(97Dh%96o~{p_r*B&Fv?zTWD_&LoQzwrAmFJh&A;1Q?6|>q8 zdj$s!vH}+JCas^q9-7oVEV&EG-C@Q#MDRIUUB6Z=Wyr0FdXUXHO?)7q4VgkJm}Q|$ zdJhyBiDis)HM$mU}7VBmL)!j z%(hXhkPrRl8gR7D-cscjeub*QJEjPippZ$6gKj?Y8r=8H>Q@;yhd0B*-g&Y&R_9GB z2M;d&H3!6BffjE{|AY!C=yp`1k$Qe5R@@DLS@@G>CcLs^JYWs7G!8e>e)&1-Qd8ue zkL>=1##suhuT}YL7MUWI&un^dIPaO;l~jZDTdUI)$iz*cp2o6#wb#o0N?!BkW~=q} zKQZ{XSI0E?G&7d@baMxANev&()XsTh9=^01j-=H>R62cqIbeq73e$qkQ~OV#lABS5 zQ17`YFYoKv7nZ&h^?R$Kfld46wndOnnSS|cF90M?Eb>gaLpv znrsD9;|e3Y9UI-_5_!6-Uiz}R?%!fFqqPs(|JfaoPyKiP)gq%{RixKmOMZVl9|x~i z;A}lqDq`n#J0fBOWqnwd#OV-_#H_!`T{-)d7g6c6 z49LkWo9E+rkMH?emFxG1X^L7z9x+m^vE5A& zF+&VHJ;-|V7QNgx&wSB|B6~v;oC2c|(9bGS3g`4P)i*|?-)1u|6yJp?$VWyKb3_N= z@fj+RRgB3EKC3`bO1W(#3CB)cEqG{D?O^6(@Q{4!J%~u{?i%;U!uOWTttpe9-V&Da zhCn~xCHS7D?^4Tr>lJUUykwDZ&U()fb;M$Q$XNId_J?L;kMjVl-G0bL01!Q3_t8H( zu$<>6Gx$AMU=zXrI%m5dRp3^(WxgnFkel+m^%DD>e^=6TqTF%@{VSP;0#eQz@`mP@ zWiZ~ete4ktaxCbw)z>-WpLA!IqX#SS%AbZPZdjO(J&kd2*ODr0ZjL*7w2BBL^N5oP zoo+dCjFYYBo2~Fur#twx_?LPnx%%=P6u6wYuNJh=8KOot`1oIPu}J^y<3&JYN8xx- zM1*Ed;pSuL>yqU2^&#d|@eb;=V+E@2_dN~x3VK^xC^o?mzB^Z_tMZ zT}k-a{Z}v{h0z#Z3&F2u%Ktq6@DjLF0oy|=j}raNbet?rwo{)q%Cy>N8HKOBaP;xK z>dga<#fl<+h@0KIU*8;4>s8QzP-VA@P5nt)nj1CfP_$=pGAHhv2@c%q5FNt^`i7kD zakiybS7XKHYY*sC-u#>#FA3%6Pml@*P1J@8*jf&;zCNPYf%XISC|5ZA^KG=aJx>ij131LOBsFcPx?|+MW@a z_%bSg+;LBuiR8m%2jWeKFY;C-k?GzrO=St?!R(O}ZDFjjx4TCsBoekZNajhZz4jvh zS5~RLZ3~QW{f{)y<~C25lx9fbCLp5)a-I6#5b~?<6WJyu-29H_0ch{a`%CiAOtzA?X#5JPRf-W1ugdZeb%)r1AiSz z*-HzG)8@YQ8i+OU6@jdH^BX2b#Gu&vceJu%ZyiRjAr`iWE3X#7m8;xW9s~o$`Qp6{ zY+BUOg^%7rc?y3BTxG_r#KN_tWh+%TrdWdAvC^qUxx1*)-lOD;9Ro&pi1N#fI;=|y zw#2V1eH0Lw_hiz0>^txahm+m;N$T5y(HtvlzF3QG<1MvJv!hy7>}+_3IP7_FMZMm``ByWgnJKR$|HNva!2)gq*=g;f`{IJ1G zsf9dr4@&4mkwmRuk*O(U&enKCC^B8S3K%-Sh$jQvVk_d0pC%-~rE+WCT1DwL-r;9> z6k}uS71_sC3TDa%DAr_TSSaUhrStVIx+za}oLCb3k|m~_!|;U75$?L=he0I?fPOt8 zFUqy-I-5?JP+%`bO0ybK25BhdIi|SJBp{)@Chsrg);kO)Vk{nG`k9UMx)i;%Jy)!+ zqA~CsLnUIelGCl}I23l=`Kle}7qiU9#mYF9xeqa)?9X0gUmbnY$0p|T;k4Gn!Oqbb zf=u<|qK8dSzE5b^<5%fLo5PUj$Y?HJ_SG8D1A4Kg{xGwvO@?Cj-)&RELPJ4rwGT?x zA>vvxZCNW)$9pfHEGDRozR7v1TQ1^IDM)eX`_d>- zsfiDd#lUaqMD@NS=jFj_{iDmnbT5LUQpgczw#C(~KFV(>p+zSu$YDI6NHzz=L(1FRgMdxSYi!$DLAzwGCha-UM& zSh-DHvd7^x42x{vCNfg%beb&X=7uF+rG12)nH3-Zwb`K&JWDDqSbz0Si7OdD9cY7pHjn{)wcjp!wuE0@vl8 zCypWFlw2%0_mcwYE$tiPlsqy9CCCs16r(;l2Ax`-CK$~KzLE>02v{Dx7PaM&-gl&* zrC@nZ-de-q%7rk&ci!H0f*<;xD5}vKJZUlHAVuvA4(veYK`#?oS0s7G7*DVW!)H&ITAU1#mnu%u z5>lgcZ#Z~-CtOF6Nh*%8C={g7<^`BZPT$`lru4A@tUO*v$v+T~}~E z5I^%(Tl=89`NL!QcO>$f$-jZB@MF!(+AitLRte_g%)tKqI-gzDgoueuD>uS2 zv=HskJG|^x?^(e#N%z?6Gw5&lYbv`a*VVLiGtz>7x?zcdSrgKPy)` z^rEFRSDnv+i;Y<1XKMwL;hMbNMIJ7q%vlM9EKri1Y{Yh|@1Q~@q@NYrjP76T#BTEcVd@s~e4+{ENelgXQ2wAoAFHlC-BSZct$A9cA|G z&pEc;ovIapv31%a1t5uB&I9ODMVgnQWYibne+JNI3#WgRne>}^r}@5Qp7Dphs^Imb z%D`<8AK_O@$`h-=->rMtKHrLBq^%(41eadd@}eM19JkM0=(49W!8*i(JbSd-wX$MO2hJ$>@z@L23de}1BD{`Y7EU;r-2{wBOZCYty$qrWm>Xhi5^STWIT18 z!4D-Da^ZSz_$vC`uw*XB9NtT>MzfQ-00J-8^7`9qdb0f?fV}2-^&DA5bTXIR*U!mZ z)rl9>{8&hHnd@4-uR`SQlfQ*|t9N)mjlZDA2EYx~O+Mkcz>dx5zdgMp^U!78iathi zR@u6j$>Lc7R?ydYAQeXt^D5*{q3Tp)<}Dui?x*xTaL>7q+slsq<+hJ4D)NV3Q@-ul zsNJ)A4C@-QPwPX@QCGAbY}o~hrNGIg?(xsmbkBDnrTje})w{7* zv)@F}-`*IVI0#zmuSo;U{QsJ-LZnI{Ig0C)tw4S8jGP2uLi0u3S_oGF%%Zl&I^QsS zqxq5HZ9&UIy@T=7g?;^f1jh+$ac^(UIeuULNmP`_5e&jlmC(Qcyovf03j=&m7w6DI z-R@7OyO##0KUnL^y4!`{Qv7+5<{?sFK#KCIBl~dWBc!QB%qM7EiaE6+Nq6G=$7|(AB(z!642$c6!WH(;Hw6YY1kL3$r&6{EHYr~ z@r4DMuSvML-AmzK4~xmzyDoj`*Zd84L~7J$iLs zRyKw_}!+EkY zukrr<{>=A*d!EVP#|zL&z4V$rsi=o>hQoL__VGU#P$}-WvY42M#@ZFzR>{wQ(^gLv z&^u-?KeQ7Z!lwYC?$0odSej=U5(YU%wcN^JhHk? z2*EFbP05&Ly=dAn;Q_4hK&@b1Acc|tSU#DYA^*Z?UNpdTI>B?xe*7Gf3_6qmBMw+r zbbtIcvn-01t8+_or%GYB_EaJq_i+6te2be-Vs#~O<1R$^f4vjP;m=>&@oZSj=@IwA zDg!DyaUnbT7T7__q-6A^if?A&WfiyzayDX3Ok*v;MP2#K@`)@!4s?{@vq0Wdv|UGx zc^yp35TPugW0_>4U&b7;z1ke>#{GJJ(ZXQU5l+r?1745Nj;Q<%NIB5rn6!DTR)54Y zSrhwNJo*eIF`4dE1tt?BFCfx;&wY_h%#PkSKCt56ZJcjhYbTo;Hf*4AicBPa52=)> zW4bv$ST>2G2NTym8KSIO36VpWRT*)jX`ghxMpLX&zH8fGq>ygvb z8iYb;Hv(Tw7i~ByAZ2EYj8ZmBM9-YZcQ_1~0C5nU_B_#gj)_C3W=a+$^aQ4i^?nQG*xS~fH)Te} zK&Gr9i8r3i2_AYXw3Lq?h0gHB7xeZ;KvDdTlLSI{ zUu6cme48NGaQD}qeXU6WVp?i6Wl~JP z1T=|^SS=z-(jF;#^JbzSKx}e-w?5qz?mZy-kQaS#v(F6cLVR?{R*3`Y@_g!yL1Jh) zkt_P&el`@u0C*YD_yO0!6F=W~*cw1YI*BHJj;dRf5X(lue8v~}ZW?G5(F?=Yt+ZO+ zy7y%vQ&eIP))*VIqj0_7O*rH{^la-mLEK{9tjuPUT@tL2Z+EVCPnkUB7r420bFQWG z7ugu$W0j7T9O8glIxdBHF9XW~2nOX)gm-qNN{a_=C=Y&A?8-t{^$IGEyzl?3WC5Yd z21+m31VH16K5r9mm}3b-br`VC_aJ-zZ0nFco+$onYZH3BGdN+iWNO-Kay#?KFve7X)V_DZ5qd)>8y8^C#bb8N)diJ0}kDDZO9;62SlU!EX37+E3o z(XtyDG49mCq}eW*J;#s^6pfZexg~9}=dTOhHusxtn0qW+8TQb9l@Ip1UoVofsi>gl zn?}__{yM>sDn3=T=b1vT-KLFr0(aeNUeX~Q@10%`ZL{0?DTj2K%hgNwAo1VsNCl=q zZVj5Z?8|VE%G@}eq&dA8B3L2KDevjAZgW7c{UC}rN4j4-oT)!2{^vzs)^Et zXgGa-$@x(W*qcX%uEc#ea5XYnn?;rk#L(z26-nVDU^CGQCS;xeLsM)@J04h zEuhq$yksCtm(oKSQ?vR5so?_$hFlx{qS6O6x<6Qj>pXEamwJ3k`%N$llplWsHh6b1h`8~!=04e>PZsGlnnCSY7Uhww@PJ#%K&_8R^c1Sn~0&+fprg~8= z^@5JAMo+%oS_3ESe3mSBF+}0-;>ai@szrD9?ZE`c)*-=y{;U+%<7Kg1!oG)(_ZTrZ$LihYL%o{PG z<`xf8EAKW*tr%o5yFux^gm-4L8bfib9_JrwRHlXfm{X<`95EBIYN17SF06SuUc~lW z?wbrfgzloDGD6vZVwzVhU(4tEyPEuN5(?ZnIHQgQr4IgjwMYi*cuiVk-~AiQZgu@e zENf~<275;ELpNoAFODs1Rhx&`kh$fZ;nW6IO9av6&i4ms;%-;=@)0kGY!fHBeNNy13YjBI+JVO^ebXe;k=>6bs zqlMh--UXlcQ=h4q`Ol2WrN z61<^5`5TkF&8S4Qc`L|#XpmYw|I4}Xn;Hh$GT~$4n>k;$RySu?F1Iw(62~m|lQCcW zGJRdW1!Y~m;3xeyOw?^H#=AkBMI!vr)Z7)FREJch!uvW+v57awmoRHa_G1Tz55XSu z#U{WU&U~|euuD4uvbYA@XquGi4k$r7S;w;77+))*g$3W`)y?LYe$N-SCJewVaWr@9 zIa}Or4&ONd0JD+I6sh!+BOhbCBq6qO!AT7D_Tcx1g4{CtWT!iy-z0WcVg)LYPGp00Yj4 z?IhG+?#otbpbb=43ahkexUNfhPA0jNlZZaG13xf^IRc`7!#hDdUNoUqc%`iY#PDlSMl(fhhHmgBR$D zR-qIZ2j@hPZ8T5@&f}x`Sr9|tjpVc7MUP9X*bF#M4I0mo zC`h&0bVKrZW@+)*h%=B5mW6dOX4YBk2J7owUt3g1?1Ozbezdgzh@uE?a)&N`PUa8d zeB?kk-aNhb1KkfYo&-&F4_Ed)yX=muCsOD6CRMezGFF4V_H71$kSRVx@UQ;<+deq1JkD_hy zrP022IWFOwMzyLnnJXbr=M-_w+PV{WZd)yQ$~;F8|DGlzOBGa8lGm3TWWBvpdo7mV zd%r*=xKn#mV5fR}7|Mt8EK0l~^MHMYM!PHTZxTHti{rKIwTYit2OVb>Z%AQ_4I+_~ z8cy5fypqiXlOew*tgEi={D}_Nu8q9fvF4-;jq922+s@~{ojo1%++H$~s|gUt02&ty zj{!Y!3kGfk)QqD_7xy=~yNhjz@Z+F{K<+lxrl(k5@F^7cZXPZ%E7` z_nK=_j*Ssi#DftdDBsKeLBTAtNj+x2T^6TcTy?*MKPK;cL;5 znRkq^<{%$ZvY{3q8fBAR4O}>ZH=X32{W7om3@pYU*rel>kYLEM;I~CA)$&&MhyOxu z3PNA!$^6a%DqhM&=2J5ndJ!NNdMve;5D~obB68`t@n0;p|5(19a>UAN5qVZ zL2GWnvuiBjf*MGz3`7;P{CVvLDy`B)$ROJ+S)e+1CGukTZs(|U$m2ZINB^^rAubdd z5jArMv2B_*@oRqsbF5kz+Jv)7{5dqTqna}b4$e`dpYNIWo|{2HzOAEzv-O7E|T_mxzOkW zy>ds7^Ke?v{jjN3>dHILA7MY!;H-Cb*9@*V2juHfK-C!(S7=zqdvVY%Rtn?9e?R5zO0 z+_-7XD3B3`^rU*M_pDPb*b%Y6`eCLW)Ht%7jZW;&_U?EG^6_pe6!$Ani@5D?(ecrZ zJ8p0HDHX*;gTGXM*|;Xuivb+c;Nd*3Fy!&L0lN6phS>`x z6Xikz&BT5 ztPl6NWuC2gG%D^|ljFe;^13OYJ8i-uAWu*D#Hl*Q_K;tyzt{h^G}wwCfNXag1ZRL1 zGxO`gXX<+==KN*!E6>y!E$h!|;1`{qk`}wwMfG?C!2pX;=X>rednU6bAT@fxmFHYMQw|ostR^)H~ zAGylQI%I49n&Bm+h$8Ay;0?CoL5T8e!4w0>&k;K;=yqF!Vg9dK@|Att@$)Y~8m6vB z`*=G;8P`&)%lq*6Sfn18MCdpi0ceM7)IiIAv4I=+b^V3hl>r%DQ1twh;&Wiz8m%7= zL%lY6<*KB+IaHTpHy-$7)6}wfUb{Etc>ls4R1e5R;p_crr+EWl22SUjoMi=#X9Zpp z^EInDy+;?|8qS%HH)+EJ>2P&U53*MxHL>#&yZQAV@3=rt4K$FY{=rL6vb%le^*2T3f!a*-UQ70VZ=EaESfPCq!zl4|GC; zIMA;8?MeGdbF08czp@>qqZaZyRXr&-DZpu4gZ? zV1&2Lvc4-J4JWajU&ij(1X?|7NirA4fkiDI6y1BKODG?>Bj~J+NTM3N(=hb zU+xb#&^@<5q&#P414_Ap7oYH=xI{kyE?umpb7kjqjGY6jE_dRnGq<|#rpIl4l;L}J zrAsu`ReHVw@0~#(o0|LAWO?WN!MdV&!rOUI!9y_>#fi0y{$R-a<|p_ic*N?+r+KR% z!CDRhx{Y7vQ~&Oa*n#Rt8W+>`gwIkJSD<;6HfW=#{(9nN4AL}sEcTUTUIe!2F@v=aATVb6az&RaU3LVr{bU>+Fm3K1c zoo#3I7aIz!2Gn&)G>Yv3dOkkRrqvjnTOa|XcIE#+4M!l8lte27z+H*VKzbUW-}Uop zEUT?%jv0zfRWMBV7yX4n<>FF33WVTIgZ%<;QMvSHFNZ_qUBa$Lw`Cf$@V+8Z5`;_<%&|P zrI5?t3>i~hb+W)Ix_Kh7rVSO&)JJYN>z^44vLfCHK)nV)(=ZAld69R?Tr9hzZ{}Qj zN7Gym(y$lF;~&js;#15lmR=I_pRqv_9|O{zz+tum_=n-j>6fXtQ3m%_K&|J&7QBqT z-tA~FfjlLpr|8H1OAFpxAC2p}pth*q{rf$T*ug<<+I!MLg1z*Q+F70qyZtkb5Ofzr=p1_L3pbFaIkJVxS4 z<`tfCbt9e9_FAOh=OLFqe@PSXDp@oR7-UhwRV0krnM{5&J%1LrqfkR1UcPIx!(~!G z+Cj!ox0NbvQdyOD-a`d%2rp?g&>E@kJGNJR3w$|6f2pP2T!u+&jm1f>xBK>+|8kZ9 zBu8Sim40Uh?{-n{_2;fy8IqhE0ZsH4%R4dInX0fKG`3%Mbg!LUCDZ28_-F$=-X~Bz zSl`H5PPd=1rSm#{3H~o0MZB#Wz>rga0P5wbiBry?|2~uK8V~fSAA=F^FTH?J5%#Pq zXl1>8&Z&ak8(a-BtE>H!osG)}AGIhp#(!Z}VxsJ;&dwNQ6xY(Z|Kq#7%1u%il7E-Q zdrAAt8zK2;Fi*L02VFv>5G$^^Q+iRydGzy#bXfa1?BvLf6V7n))uCqQG$rRl!tc?k z{^D8r{wfa(lGltAFhSF}PPFhD|RsJR@s1Ul( zyH0vWm&|;n@H|YW$P_Le;_Rw4Sdzgbmg-9lWDh^kJG=IM)O4dF^IQ0Gv`ghqJ2*lk zX#Sn%uKx#iqvhw4d4UECkit>AlYG*D=?Zk@)2(bf2l(ILqHJH<8*^Z-MOZ zj?&8KKy z`Fr(yRsp+X!67o~KiykH0zl zoLa$=;@cSPTm~qC9u1`D<#%m*cCDms4h5a+$elI0@gMJbR2RDQT({;o`q5)2F2fHY zm$)pt?Ts>Li8*%w^47nfRAul>ypYfXfU{3y{f9n^jrEKNbcK+`H_Uq?yVe0I(~z!* z|9+GwQA!oZAe^Qw)Sid3LZz;8$oZFcU=TzIjYq9cA79r5- zmot9q@k?kz=QwoE z6|w&}Wl(&gx72@or!rM^ES-!#MCSeWBIDJmH22O+GMIzWv%Ln`X0ySC59Ff&xf$!0 zddFBcSvT>~7x88ukwb_3K-Q+;)R>RZY(-VTdaBE4RREoJODDAqru8IJW- zwD1QV9YIE{F=PK^h&+ez&U~3incypJfAkOg%}KkZm>K>AY$VPc{Jet|Pxk8Ob|dZN z2TskjRm&6$^SiSZdvd_z#}0P5;-%g_$%;Xl zm!_yplwHTMm}B=4Z1iP-QC~3$y1Qy;-TY?kFF%uz2x;L?MevC??S*(gxFN&A==|TD zt^^sq1D6F+*m7AwZr~rM{J6=_TpdvrX;vEbzr12fue}x`w z46=gtsult#JH#ijMS2CpQH*QDTCynGc0ec~Q{>3GeWm|7hg|c`!1a1q>n&wnw_WvW z>24a?!^cRyIc_8%#$a-;+V+2^G{@9zvm+}Zw+VnJJ4+pZ=kD=o?0)4(cJmE7NTN@( z)cqDg2DBw0R^Z7iH$GJJ=&%d#wV*pv>sJ931+XnJX_^Q=VZVExOb*H<1huhld58OP zkML8_uw)+mdKte~Pl6_JE4wrR0=5f=V1%G8uX^&8`~*>IwIEyL+<>$j8540GNZNF6vp zsBIcL013Nfl!@zK_lBWli{Ptn;svAa?VLfS6S}LynI2b?g(02o=`TVM!WJ^BKhwRs z)xL_f0z3q=c&<%BDiKnca;4i(8L`FJ#8aycR34ReL}gg?K0We}1GSj|x$kU%a*2I~ zeOKiWP_gn<(7<*g(0cBZM-&2NHr$>fU_A>|t7>O|`351qe18`>te4wu^%nJ)=-pxK zL#8}JnT;UMRj;LVq`5BmObjJ5fK1ikGlA+}8C(q^4#lDqM&o10`Eh(b( zxzwzimr_~*C93@6KMfWQ-KVqmYX~3#As^1<11Lcs0Oat{`Jj^{7&H$Io4KYk`0Gwa zY2)$HKt}yE&B)fyh}c3|%W@=PwLA@7_01{6kBM78rB-z6>z-W`3BXlf(a5_CuvfCKeUx0P-BH*M$9CgG98C+C* zAL4u1DT(UHOR3=nc7^zlx788lCTS0;tX6-26+3FXgBo;iFh>6ASowbaS!vMG!4Mz` zG1?t*Dm_3ks&u|GmBaD_V%` z{e39_zUq6bXruoAk7jxCT&7dNjUnJg_q!^(WSk2=c_m8s;W1;~g$Zyet2br?rCBRD zpbk9XVV^xF=<>3?JUJ5EJvr_QIym%{1VpZuJ0;h!?hQx%LOP|u2K?&WYN-e1;Bokh zeTD4D6<|gB&Bprh4MtvVuae*j_M1gOmfuXjt0-%HYrMwhRyx!rWew>qSpc-Ufp7Rf zZ2fsWRPP@?j!y|uC?!RfLJLVL6xl*V2qAmf_kGJ4qqNJCy(F@4W1ktj$QIcd%NSFZ zEMtsq491M_J-yza@8|b;{J!U}dYE(0ea^Y>`?+1u>r(iWpXL7K4d+(R_8JOX8vvSk zI6hIaY5Ii z_6v$zDI*B;5k^yf_@v3-el-Ni13iwO>A>oPrpUQydGWWr*1^qS)C}KYtRO17%IP8} z5+AnDa728u-^-bZ3r1X(YB3WG!XhHw6UQJbQvG65TLp_-&#V1YGhfSqy2OrhDl7=| zPvk^$tn{CI3rL(RS%9_>5DZyPx^$Z1#xLg&aaMM5#FS6F@Nq>ye|GwEymikh9eG6JQQ1bJaiu4&wgwsx zxY{8q8Bg=NFw~kU)OtrEV;8XyJiC=405>sHpr37LQne-ED)VG&rr8NTH1gJ63ecMV z8K(-aDh#h~a4|}~VgD8;9aI9^XRv@0NFhjnoiP^=pAE71shi!}DDLxvF&Km709WF` z?j1aK$zQ1%yoLEUV3&*Jm#G*BCgcqeR0LGB3k+H~l`ucw8eiEGFB=7FirsP*Q12-R ze7n#%2GNfegt}ZALqi1sppycJLYk{cUR2pDol^`ZAw2>)RKM=``=RC46I?!G@8&27 zI1AqBQuT!gDNhoO=x0r@7_{Wxp;ss7%mJ2A6~hI8T!3t$CRZILTA`SxNU0v2W$<)y zs{l)}JlgY2`O=P3+g4Si!Xu>MkJ>uMEq47E^Dv~EHweAF_a&lh?%4G=fFdW%lask; z2J96cUe(PkQ_xbf^H4h@P7^j8mfv_lb#6UOU8(GQp*jSoN|Fe96%3%67KGssHf)U# zp*(0m03MEoVuG5(Hde9HNza8D+|~pyi-_tadM+jx&ZMxgnz{0|bz}bTHM5u(d2Y#9 zwlb(@Kc}YkK`+VfA3EarSm&;O2m4-R+ZydP?dCF;~oNy%fm_0*~se z8S$NpYX9Ocfr#n8TFJ+2`2=7#+0QpII6(e){Nq>AI(9KZ`TA4y7oBVK32d3T{@uU; zwBy!LpK=YLU8-|kb&DV(ccidn5x`li{1~~ZDPhxCpQ=_-WKonv+!(dl>Qdukwo3vJ zmhsyqXxss_UsAW+!YA`0Mb_hU-9`AcsU$@7tzEZ(lk!#E!e8!=ogV#)F4JUWF0QmJ z%7WXA2B@`8Q?_o^k^fi}j~wA00~6-x`Hz>cmtKOkJ_TGs&}u_biGb%hmyEODax9Jw zFlI$YhO1#wQo~-qnyO{kxC81*^T8l}`oF2yTHYb(R-|M>`pext$Mpy~?L_l%LdpM7 z+Fcg`;eBVmrgd5briA!Tq#iPPt$3#`YYx*st zw7(}TSVs%2+Z)s&rg}B{P-dk-gfFZ*jIbD03UPZ!t6d8+jeGoADYzspXw)EZi)`$% zY+(mTK7A3%R%~5i5pFtABW?R~@Rl!H@blwt z{2B`*sc7g&kr{nV1nnN&=XN-nd=Cgew|qo0qz12#dS1Pr_Bg9JAT=l_YVXNgTz_67 ztZ54hNTt4~uJP6mtH7T&unu%_zl-5jQ&vYNJC^`AlzU3twrqs)Z zA6tk1Kl2e{I7-b;U0z_~s&cca@)p}+VoZDCs3n_|mI0{?oQf6I0cp@z2<2%B3GC`& z!qx*h>{f>?;7UDdNebI7k*P0wj@x|XR#!ED22%}n03ST_WhgEr;DyTi4hVCW+c5}_ zhi^Dd=x;?BM9hGUm-c!u^v_-XTizKG_d^+Z7)ehL z(!LTd+Bx_o8D8E5_>b9>`kH8yC5`*yb=!@R#hV&+ShaK;JLA%;q?I1H(x>{#tEF(` zV_Hhu;g-NA%M_dRBxYo6+yCTFt@HjC5VGqc@uR zV~}=|cq-9@VkB#}&ogQfWufn_GpjGbTZ(K7qm33mD&Rg8r$e%CaK}nDjWKyl zRL8X%&L>%*OnW;b?fB$4Gw*jqKbj)FxbD^HB1vk(hbU8vB`%-#FJ4Hwoe@G#ixv}$ zu>K+|nW85Pd&7lqL`>)bS9a(!SWOWtb$t_4-Vxx1FgpOS!N5gOXo-U|1bw4){Wx{V?0S+yK&Q-SQ9G9VD^CA<>N;4}iuJf%mabmoTN(%C0j)*%eZ*nS> zUej~-=A~Onje^Qbx1tk{x=xg5!5Ul>E##ktZq6lpcDer^EB9mv%xqbtL8It9gA-y4 zZ88S`(liGkY?+P?e1VUCC?XsQMnJHG{IkkyxqCDWwPU1Q38RelEq%4dYYRRa%`H%c2_J)jiM zT+O^m*#cvUl&hWo$R=^}{LwSE^Vw@VQ7bn0y>|ANQ%OzeE+E|7+a0 z1#eQLafC3L^~Nf2+yQKt3^qwfY_MbBR}a&w>anlp7)+w*8wa6cl+-+;qNj*nC3$(R z`?Dl!<&BLyF-94yy#LZhQ{(+I|Kvdx>&JD04Mez#kHTy$6EU1y1L6F$;l-`(ZP@Z~ zZ3n~Q57fDkH()h|qG5!d_9@@!N)$Gm#3NEAsoQqYb91r-4x((C>{Ai0!-sR-(gRHT zUu0((nc5oRVacLeFZGiItZJ(y`Q>^OR~`U#s+g8Ei50R2oZ*U&m$&_v0TUfcD(MPv zZWt7TqGj#61dEUH@XE-Q+uezxXb%heVNW>r zr$r@7T3`~-p8<+>$tLBt8Wy_~ZVZ2}MN{4x$|U^rE^zr0?aXp4tG?iZ=HfU*Z4Z8o?e0 zSkM?ev8u53pBDprcZ`XPUY=DAkt>V9mFPU9=9T8!v1~E^by=Ykyd}%9pJIWoi-UnS zk*7*T%NJlVW(otdW>VtV|T8} z(GD=!dLZ|O5}oUF4!a+2pU{42%{A?rqc?TB%0-o;$sQH+P4s?zv_J$kw5A>Yu%@Xm zNNmof5f{NVabTp#%SO*2=h?=S-)m!Y0qM2h43l+2EH|%*a2mHz0}K|PDZLxAL3LFr zya9s$Urj`{1d0$6Pj0XoqqSU0!On@!`e`(NC8BD33|lr{m=v(YeSz+ZfgX z`Ry59LLn_Pb`11_;7fz5Cf|J3%%ooD8vte8uFWq<&)T1#bL$(Udq&(wYsCitQoNSS zGy0XH!&YqDu&Ci^Hi*jl?TSa22|hDXn7Kx(<$YU5{L5DC_r_CpaB1mzo@|<+JH_v1B)1r<{@frFcI3{f;)s3s>!IMD$ni&8VXb{Y^Ab z;>lS&K>6jH!^sK3Cf#Wvl1PJzAbN|yTO85ey4sgVe$;Xv+2uww!bwdihkOw%C7W{J zqd?6~L5sO2A+N)2KU*VlImEN!^;V@|7Dj;HFd*Nwv6$z%7;CQl3+&>L?~&eY<#3;# zn5q)rRFuqumD*|kl!ZU2YMhPxeam3_ULTKCO@&W)(i1CkZJufVu`5|H6EO#ctd1y5 z-F*MI<|-60gL!kIk!Nt6+GcQlY<9pq)GAQlQJYEMY?>D|{e0bAnP>yMx;q)Vu|*@e z2uWP#)vupX{Wx(Q(46W~te^BxwFam}# zQyu@nrF2-l2((M~OB?IUU#?a@Jo;We5tlp#^?LXeq3x{rrq;nQ-*!hMd9t78YH+Od zV8cwnD05$FYh(-bn`TT#rcIyN0EV;H*M?_feK#wHZsC)^b)Gew1u!X;gw0vVmm2$0#O{(K}sKXUiCFFH4n2I zX-I^78D=?5LFqffHCX}lkdeYC=|$a~$Pz7yGlLGlzdykf9={VjF`+5HrJhJ--@g-r z_lK7T5?=)H;PMDVX@bz_^n-Um=Z>ZOCv4?<#Zq4S-~ zqbz7E1HpIra(U>Vn5{?Ma_+5uA_(uNbUx8k`enF^R{#%kCoxW-(M~kF$2LAC+OEbJ@x9Z>ff9qSB^bYvH-C4s#Bpw^b3j{%HaXmDE0IMb zbp8;zcL?pu{EfU0D1vyp3PqDy?aX8ClUF<@_VT2yBzb3lNHrezZ0OZj7I>L|S9!}P zOsLz)uD!ZoIp@@=azkj}o%HI56`DV<;ic6(M$br^w-PfSumS4pZiMdVLuiAZrC~Nt z@}2k2MVXJ~9g+I9wLY4NtZ&V6iREw zQ=&B~yyH$na=hAv;MmDq7eEqL4IiV7FthUly0FLIy@1O@V!1wqg?(tCwiu==`Wk@P z!+r!M2_Fl0yEvW|qi72}v!c21NqtD@ArC^K@P}>el z3LWqSh|`q}-J&mXsC-S@9W6b96QGgaznjPO5bw+-Zop0r>15STxb#$tQ^-vp`Q=z^+|Ith z%j1ynU#I(hGe=5s-zSiO+ECam|H#2M$(?#0t-xEk56;LX%32jjEgD~;QW=lg`Z}Lm zUOvPB=A%UtPu3WK%hw_o%^lukmu@$e23;1G5%B&guCMu`E+2az^EBA3i*6 zQSZALA{1J5R%&8eG_dSho2ra!HB_w};b@zaWEt6kUhfatIk2Ru`-yvUiQNLvE~cPf zm;XL+Ch7Qq-FYO~ii|oAL4>a_Do}?KNW5)(T6dMD7|FiSX+TbkI@ia+IlTxzWp04N z{&8lAaMr!5^rvm?iDh}a9D!n5r{XW_qa;&hnSE|chOTo2Jmc|Li!-;+ChK^<^T;_N zRgvn|_U%9&E#>S|g*H=yTXD)*lC-N!mXESw*8IlIJ9P`I*7pMLO4j)nMa$eo7Gl(G zzZXPyRHgr7H7-}|#fP(8>=4i+;DTx7%LScu^meb+g-evy8btHe9B5sHKY8PI?gahcI9;!ZH%pvtYWe= z3WKjr|CW_;9a#NUR9ah;21*nQ!qWzF2Ci%$CuAL7b8~6SZnySm+Jv2%Y|k3q#NBdW z4PeT>S`eE2(7?6lPX~6D=@V3``Qt?6i6()@xmQ7sZSO&RvL=TI`bImnA}xu53W?C< z$J)L5Aia7e_ejZd#?`4%L;ZKzRnCgT)9o8z#s}Qd3KU|@c+hEA$Lgce^SSwPz%xeN zIcp>p#pgEvsMrNp7=y6ns53HMJ#zy8rXWYKZ7gnVT9y#H za+o2{29jjLRUX|!Tb&N2<0SmDK&?-~-;SvTGWlNKm4YLlTk@mW#R4 z_jr15uyU{iiiri3xQC)~f}8bRtxb0uzltIfb9!Lqwde#nsXcHt!Vj%mW4!SG8Q@LJ zCEx=sR!?)x3d9JBv|NOI^)CK0WU##THpk55d)3t zazQo5bE)b6=S};+e%T%r(&C6!tvkMne)^H~zKc!k1&EP?ps2{d_i0>e*e1KT9ti_U z#}ZMm|46ODq>8_wTTx_wvpiD%%To?dWgJ*N>=koI;8l4gupdh!B~JPjD2SNMV2p@~ zHtFX#_;33ZQB5dX&bR zYE;)cPZ$r7`~7xiU$uv?mLf(+Ae0bXFkn?E%j1$Zr$2(Ub9jTI2pR&V-yD9~jcZRA|bz zVx;qOVJ30!cEjCQk8CI@?NJec_GA0BwCCg&EvsX3hY!e;ekK&DfA3$Li6BS9ip|$s zSCWUfd>-A4cGAa6>exUfads*{-+!pu8xa1x7U#M)Wz?V?H|2AhR37)y?qH|H|9^xX zSVtIQ-ed#$<(+SedmoAxHwFXu(#aV>(+0Cn7>Ej`-1M9ohK7o6G z-Y~l9f#vz)yIgMKj)!^B_jXD|DGb{qx(;*|`r7MP-*YS|v`(E_PYY0_FjKv!2ZaI2 zksGbBM|KlafZ6$SJg}LKgGeP|#$GY16&e+Q$~;Zdtaf<9GNj-ijVpIYO``bt@^~fA za)ptuz7LWSAzRJMuP}3eS&7K2LaYOMe{{CmCKCb7MMZksV?#)`wi}CC$MD@1; zoNRuZKXhs7=hj+6DUKURLulcw700}basI<961DV8)Lnwt^1DVRcTf@t(#a71r0D19 z9UuTM9Q!um&?m*9lGJV(@JKVl0oghN))X2wqLA~hf!r_cX1#YDTD<5c>$dHLa>12) zUWTZgH{aX}lFg(Yt)pf;MFh`gjv@v>8hdPgsM(slAyN#|sGj#vs;lb6CMYL?Td16u z58kICCPA@RfmA=E?Q6<_5V(N4?D`Kb<+1Gh@$Spn2C{a8XC>hGE*CwbXcc)+9S?k5 z!{nZB3uP2SYdm@e(}~y^c-5=;CS=S7DMr4w0;Jo%7eS4u(h$@|FO=8%5iuK`VL zE*cMtV-R7Hd-`dvJ@Nq+1`Q!*Lla0qS^veCniXUI?u337r+|EQ+@t}caT`JhocF@# zq{F6*WcM3(w#ac_9{5ZsDM-O79YU#n+08Gt_N7ocyx?i7rM zv>MNel%y|70J;mt8*TU)MKw92}zWM`q7W_9hWor@^q_78Mi2(EhtRcqGL2WeD^?p}+r?2MOKMXKZ zc&l;AgHIV)@+3p`6&&l|00L%Wf=oaxKYatJ8NhXY5-)-^^1mY%_J77!1&|#QHmKrM z29}OHwY|bZ`#;usm3!_}_2chX(CPpCQ&^qnR9SP++}D4^9{}_vQG3v&k-kgFIN#Zk z1dxuUO>}nf=4NdGN+y+@FJj|iyJOiMg8!7Hv;IFO z&E^Csm)l~lKm%G1nZ|9fvjHz$C2V!2jx>d@5+QgDP<~}1$=qXvtV<30h zW#+`%{WWOn8PFDSVjf~{OSx|6zTE#!HaE!Y-$!MTAy9LhC|}9CI~)o$BHHSH?>}<< z$AFcpEZI8b=LOx+8Pr` zo|xnP>Uc3xLigYy2>Ue{>q4Cho-GFVOyigkSCia!V?U++mroxnUPRZZQGc@`u6USv zHjKJF^WT&*5uHO9)n4oK09zI0*-D#%)YyHV7_RAeN@>IwzR>a4XdyH&^d?%u%^0P| zb!90DxKaVTjEhDpTCm_n=JP_+@2ovBRVZjF-c0s+`)SeW;yCk2Zv~weVoovvMZuj-1m2^ar__asr$hKFiRMiIwCkl&vv+Q;`{*CcMK~-m}#mLeSO{ zk1%A^^1xsS+Rd3ttjq(|rttbKQr4853}<6H_^a_M?B6*x|7{82bkIx9kVFyI#7&eS zqe22RdiZ^lM-=KZ84j$^0@YlUEF&ouD*~iYyvPJgXSb%En_A&# zEl@8Rw`%pX?4k_Uf1`{|l=7O>CPpGi*BN*CSA$kT?f#D7dU0#MSlpywb4s>$Gyp~Q z-1nn^aHx6{CQ}N_q)b!cI}T!q?lBRtPZMvqtK=3IF!Wo20SQ&1 z|9j7p<~QqpnPW?+fPkL}VK`)RB))>%neN(g zbH)9YIGXM5P})~PC*#i)6mK5vcak5fJzKR+`*0^AY8{ST9ptD7p@a|%}5zv3M793a^W zpO}b2sr1qbAb(vR;HBtl6GL)9_TFg@QC1iSRkAe1_8%v-zpcT+47!K@1kjyEzRIc{ zYdZ3^oL@?zFSoJo)|jBi`HS9znUtJfN&Q3E49Z<>ZpwD6|s?s|_>y-E6#A5$Ymj7eCahchyEdWeaUR0HXvN z?L@+DfZlL(2-0m?yJsoQY9RN{GmB#(efB#`FCC)@x#n;t({|eQwyH7S`)0trlAi~Fi2Mw{;CJEvYcHQQlSG}S>uZJC*BJ-xr zJu*YQ;izB%7N3d9s{1GdN#oD;~oFtY;r0U#>=)>lxTC*_1d{+c&x`AMO=yYAPhpY86ECPqEN2PY} z-xRL59jw>D1Z@vzAi2Y5vq_*6a)}CXdk_^{@l7vwIS^75(zj>0BrI|h8g?H_C~UNf zfGmnZn=cYXc3;M$lGD%)ZaJIV+KWL-H2G@ULN|}B2YtSIv+suB5%JPG#f^|_`RGf{ z>tkuAW49Bd+5Rdj#+YXUb=U|ZLQtLQxlO2QPKHGG;{eY^FC#o|fWyR9u$CNG{q8^j zzl{H$CDdi&MVdLsr*$dn=<6BQ)H_v6i4?eTEbXFnv*SSEq_$37o{6G#Dr=WzQ zXZ?cmPf_EA7#Kl~U)pnJt3zwkXRQ{tw7FSLv`Q>MzKJt%{S<$uob*b+cp<>6ar#Bt z)CnR#BF{M^pdoKUlP_hGaKqiVjHFJ0>u;Dh*LFZ{HkG;(E_%`W)-LdETS}VM+wlc) zdeY=~1N4Xu9|n~$RB@@Moj-cmA`fGxsn0{ST=BL+Gn6SDNk4O0*wwKUTG8Kd_#vLaj^6+$#G@+Bg- zXrEf_972ByJp5l*Cv(G)n{bW6NB=fJBa?fnCYqGFK z?V=T3jP)+L`MsVzaV3j=@vGWJ=Ao}iMmg2ynVU7Y-CY2a_GSu&7w+Z(jX4?zDSz~B zrDONuT=jf+Xlv0;Q-`2Aw-Dxc%*G$!ijAga#hw~~6!zKqw~x6vQ@KSCVZ0`}-P5@t zAz$FdUdDdL^WU25^SYiXrlT|y9`?JrLXn(wAKoh1tny6Art9dKytS!ZipkvG0B=A= zAXoH+wM)7nXxHOuLTLM6-u&va@AfG;^q{CVAzvCVt~C@^x7m1fDcJa$WQfkxlyh-Agt*C8tii-v4c(zwnG4yoM02h%DKpNa_vS z{y-P@dr)MfUbu+4pB%WFQkAB?`gUb#x8R7lqTV;mv9IQ8>Jq<3Dq7Im{chVB!3k?b zL>_q^aV@h7ZhVepVSMRnCOZ^a|4@DOhIS&=+(hzR!oyW;VQWMSdUrsYe!J=e%J}*+ zJxTRb6?}a}IAMFh&jp9%s?t-sFA^dIli);(-j5PY#XOl0p^ss1x)@B~r#>!41Q+NN zo>*+2O&+<`BMGotZD%~iv$NwF{1h=$RSgawK+z#{ehcvcGW+3zj6Rar=Ja2N+XxY5 zl>Ec}VY`cYTeL!B6S>5d;J8=fk%?DUd6o-bZXpiXmhO&9yGr&KuEAODq);|XOwXNO z)xrne?peeJYfy0Ax;eV{`I}(Yud=jj3;KESE6z#g8y`-fnj8xvBI^bp-jmohK359M z$DB}7&9;xci?}_FOj+F9-2QFS-2qKopso$4eDV}mLjE$?KJ?aE$T=+```tPrPxL{t zlXaTFq->F2h%{Ho>YTKUV2= zH6&Cekh;qvf&T^UYy`t;w3@Mjw&`6(`?)=@H(6US^b|jdg?$t!%H+NfM<^Ntf;2(H z6Hp|~JmKZT^S?9rf>a1KYS#0FR&a(7OMCs(C?TPmv)~&L3Ok~!!461Zc&PRkGFn>f+5PivlXsj@q6aJIwBbyL9KB77?l=Zw^=2~rg^Fxh>IC-I?q|^0|Bk|FJIu24| z7kZrsE^6J|t9L2V4V_MUvg#Ee!h_X#oFJG7o9!UH&7s`8p6%yn${lFIql5D<;873x zm=>C;Mnc>beD*ZNn_nPH#9-UUZJLIc2Q1oZEbh|?-pooP#C9YH_a&4lxJU zuODf44eBvA0X1`Vxc7sNLrRZ=><2u5haS`;NZ{4=(LwfUBUiRuodpN3Dv|(|DCy`bM0hXS_JJk zj47g>G7X^B9;R3*K`nqX2JTDy1=lD1xnfK4{0ID^Iss zH8*bxW(wOKgT3Lu%ZvrFA}X*#mpJDn-AM+nT4l zu)dM{*<8U`P{QEcfT-#nhKqxKVU=)r;fDMA*7Y0eI6jvzEDhF(R6#CoR&!RHPxvCM znGC}^^P;fk(Er@aL`>n>inRA09A!}Y%%;0`-%N;OB21T7S={WQUmGW|hXTbAEEgY> zeOEl1WvK9h(B9IQC(t`MIPfTA{ zAd)941R3Cln*eJ^QaAjL$JD+9U65mhEm4HWdulnRqoxa_sc-mZiE5py^LR}{IyJ7$K7^sIV4B1 z0YsUfdqV%70ZhqtbH>~+SIQs|9~gPWRP`*hHTro9$iqx*HWZNbLC753tKc#3>1Bs> z9_!aVpml+<8~S)mR$qThqu>}#9^sqIHun11>T}ED0FfY?l*GaJcsx!FH`)81_p)tN z-;p|LmRL(h!eM%%er;a({c`2TlPR!c1nf>tJ^F& zRgRUh&xLn<7u2S*u+1)mBbyZJ}Co`7rnH*A2PwIVe zquBf|!N4(iZENA9#?Wh*Y>0(QaQf_{P$G$0*Nb- zpOOD(7YIKnB7gO5`vI4MvTvzOu^;}+(1H!((zS$b=S6OzB^Dhk`vY3m|8E$2@=}rz-M2aYN#7u8o?j}+&~*)0t zH7VVnGTE;`?+_A&FslRqtd0Q3c7OU0q>#z&nXN(I(H9ND9oX>52l>*^_tT+V&lA!NnNk9N$oEi&?{v2 zN&3{JIQtNWN9*wZo*l|{B>HiUbbXqP6rLmA1$br}9##{Kb_cGB*Uc2ZT^ z-5HY&elC@;OngfrL4T)aD?J#tx6&-FyuY3-Q~g^M)JK^Z-DU!R<3xV`V>|d3dq_1i z*nQKUAQxJjD87*=<9?Fv?lQKZuP~SJgj+=kfQB4TT*z*%hAmS``$%XBC#zUP*7&Pt zkY{`tCv3$^K|e38x2H_;_u~CXq(6t^44c9nVL}r_p7q6IL7Spud&Uf>YI|m=#g-l50k@$P+VE94%nR}J*PV`I#i-=v=>(jgatxD$B#`(I1 zy$uATZkQ9tNUW*c1w!xjvc5}a3FJw2pyua+Dev|&si~-AQW-QW`(7N>r}$z~ikD=U zW^QR~I-)3&(&rVY$hJO;hht@Mq%sb8m~CHE*$C(DR^0P!%8!V zioc}u#q|C$K5k%(UP=?P!~(yK2dhcL%#sC#Tv07^@q`a^@(D_#B2aDPGJtVQucE)2TXn$;o z30z0T)juqB*X2lWGW--j?-yn2Q4(pTt%Q-qgmAa}oxlT$+R)(=4{Cf5Y(A*S0(50( zeD9yPPTzO)+P!*9=xFL{bRFw6U8^Sr%$+Uz`~G5=@=t}Wqdm5%FoL{uti%Dj+iLYd z;B4FccqX|IyGNl{(Dmt0#k8vx4nSN6cPilUBfaU77!I@uzs-{f8)y$M^4EX2zdPz= zUC#QZ$<=S3<|bJJx~UFc$~Uhn`yJZvG~4-mFT6fSwO@wiZSD7ivpav_u=7B%`D?=KB)Tf5e*U?#&{`rEQLmX_}725 zJ~@J8nV{l(s%l7dPp8?wryySpN#pw4xMAuYR=rEVXmxr0Zqvtz2++cG@W|KbS5WM} z3(Y#X9dubh=ZEx(UofWTBS)IpZM!xRK(8HqTa~1R(83MZk4vb)Ba{zzPx8 zzkHy=d&f!EVJSUuwYlUNxF54xBv|KIY%Izq73YTeG`?$r8bYPH0rIBauyB9{Q%T^jcQ_ z?XfxsGW(063UYJxSYnMJMse=Whbl%w5K`kg){2e@c4@!Df894#f;qe@D)^5+)aCC{ zXms4ubi<1GRKZi=|px=`Mo=j1Ny~P zH9DHC^LE+M49nDMT&ZMkD|ctr_Sg?ix*qRii1dT`$Ujnh4hSeGSFc#7fDH`YB5v$^ zL*=LdzfPmY+~0?>3tclLbZ_~h7tQsJz+c9dwde7RUUZOn*$wQM=3=1i|7WoNr{dme zjC);guSWNx2>0Il!E;cBWwHLc{X$c7&7m4Q+G_+5E%ao0`^|1JE`7>EoSjEN zFefj?rE^=Ea0js=6UgY%g7~)CWnIMjT-@^nOy{61aWG9Mx~O_wke}=b+GM|s)>CnT z0g*O{XMUz27`!B}Y=iSv^KNYCWSD)Gk_9>2&jHJKC5}PH^X&4P5cnfr;9Yi_MRY`= zTA*+zN>HAT5y20^+##(qsx_DiB=$s%#>!Nok&+WoCdUZ zZs+xt?N?H3-F^LlLPDTT9v;!RdJ%V);YEa>rR+{p5Km`pKtb9*{WUM`_{-iKV59@{ zJE|tg2`{j$0N-b9zkg$ixkoDb%oINHB%}QYX!fN7!z$yx;0O`sU!2VBf5rldZ2$?t z)9NIrbaZqY-9HDEbX4YvQ)-&b^J_2un{WmUucVH&mJF1?B_QGM*?y6C=g*{hfi}%N z%7#9R4-xsQ_%5^QVMr&h|5W2vZPSa5U{yx(1Tvdnb0irk+j+7;e6@(RaOQb_h|1Pu zK)S>c>~r^+fWr0D@{n0g0R{7}XM5z|UrH|J|M!SUUmTwVtW_3tSl`a_|J3Ae+_eJ+ ztJvQ6)pZm(De;zD%n~d=n}Ho_ErISdgAY@9`+{LvA)N+Am=dJ4!{kxOZ0ul8k4f$q z#z<#?@wSMFM6rNx)5LdkZ)hq-S?T|t61FFn{{;wNWZM%8(=h-oqheBQhVE6O?M4+r0donE-nJm zIt6U5z{_3|^Kra0*xNJ_<{O|5b~c|(=!w4F4rJoIn^CtM=el0OKTp$qv47c)b1gglVnfcGINm0@UyjGp6Qd%cL zl@+R?dVL?h>TB>R%xee#rdF3g`H*C~fbJ}zpW?qW=Kfoy zGApL{6JC!lXI}p@0%iOMM8fBgtuMnimY!AE36QBHUX^hN$LF?Ze&E09roJXDp^Kai zDwD0>??dGg`1M+;8@yW!;5F=$j=}VZMz1is*b;pActA7Imn_Aih`m^oO2=ULMGDN{ z#$JwS)W+{6$=18Utot8Q2ZC~Yq&$a}YvYiKDSthp$DaG#${^pDe`fTa?+_RHn_7?K zFK_1Y2k^V~{9ZQ+10oMX)m;QOFa8A@;ahm+D?oZ>6(jNJQax#N$VyclNa2Nk?Mm#) zeXv7v%lRA5)Y7r2KMk-X{R2XL9-737KYlCX`xhU)JM!s9$MP4ymc?I#^w>9o(sh(6 zZ+V&VH9<{$heYX3{%gWBRN1U5-TkXtVirj{7k=#w)4e9Rp|HW5{{@tS_HDJ7kEBGf z=Y*cV6(b_~$I0t?s#=)b<+<)$hZyK`UO?3$)u};}Anorv3RSlW*+`fFBB(gwK32Ah zejV1-MumOD2W8@23gXMMe&@?&-kiqJ*y^A*nI z38cx~gd346;|8J}2~o!0wgw#Pz;kSd-U}UdB_PAu7Pu@V^mBpax6dkx5Ph3X>1dIf z-?w*E-;D98SJv54WSe&AfPRUu(iK&$0O4Bp#l2;~je1J0J*sl2NDz6h?|QG{`L(74 zAzMe`Mkilx_%4%L7Q6(J#|$K%>|@0n@aDBPfn-Wb>Gz~D?O-YMGg6-#7Jlr@#t(Bd z(P1$-`lbClXJ}~)6kS)UIzn&wg-Rj?FzONqDk4ugETbLj@tFf2#x;4=8A+*ujt5@= z(Tw%2w4~v$-RS<+{mZud`pe>C9m5CJ4WTyv9~Q}uy?b7u6BLsb^BGWyV&bI{C0JbV zm60iP8P8>aDzg?-b-oEo@atl<)ln`DTDY;Zxv6>qRus;xe|}Ji36W*v^@<+s3_ZE? zDeTw0!(8=l^+>ud&FA65t7}J29*IdN?ho{BLd^5ee~K>Gl*|ssxY5>Dl~*ebU2OUn zI^dgq&*>Q+V^1)J#;14VGgeLg+XfqZU2T3g-o@CE(M7zoZdQSFeIMwT?om`7Td>sw zx{zmDiJG+`Lq_6A`t>Y3+ zN(HBKHRqRl(|#PIdFo4k%)>`0spepq0j5=}Q)g-E(YeA<3jX5S-SnB@xdBjRft9w= zg@$14$PWfV#^zH)LG|!x00et=*?($vK6Y#+OL_)Sdd^1nD!7QLZ>AOPCo263pppN0 z+>vM5gvyIF;RAkcdyZ|M*~0R12*ih238<~Dm>xOaBsJ_SHW4CL=^tj(uyXPLzV*)# ziAR5mg+_sJo^o!Cy!hUAgb5_h$j-?ARoEkHqrb5kDfL!|Y(R7n*)S~2LszOMgF15M z4nq0-;y?_X*8G7MpV7thYT=d(=E|4ooW?8}$T#uxBX>1Fn&~U@yk0;K?p7x7(OgU_ z+HJ^*pJ18F?*}|ag)S=6tA+v-7Gvs4R*V)Z2P+&NUky_}@J={{9*Jrld}f#)L~dSL z4E>xgVL%J|wBWZa@#f@&iSdP^7ImhIb`zA#87X-V`{WTqSk(_szZ;*9VP8n^elp?K zPdD4Q(8WWm4zn!=y*2L=cG8dl2oJV{`?r*@rnQF;`JAOS2vt48OOIkO@HMtG0a$OV8H+ZHc9zQ#}TpondzI$3;%XarwNu z(&4{j#H6&XIP0BKTA{BNU%Zu(DSUxjrynSNW39 zTGN{tS_(CEe{~27Idk*UB-_c(;;4k6?ft~RzI_Rr&s2=(iOA7h64Qu78&&8OV(t3< zA*LEAi6dy~HrLzp=-CBRW;S1gGu=!cg_^Bm-SWRmV$>g9d~%<;nq6Ei&!@KNdY3Y{ z`!cyHF^M$g4xCXj9~>p#Ow9pfO<63 zoKjCg)r1E_t&yr{j@|o54%-V)Z}yMR+c7%ts)#kFbHxt9qE>=U7{$#QyHB1*ItiV; z0>0#PYaB+9zN3+P%{W>|&H$-i6q>a20Th{3vTi0=+6>0t9=Q29IguEC^VdMWVHT+> zOde_V(9opjE_lhq-#EeowQ!G{RT3+#vim9oJu5`ZJ7~0Gw!19zAn?(_#?2e&fZR(= z%6$Ly%2)d1qohLnos1|8XW97rtvHvsK^r*bMf9x{f*4|NJ0nTHzoN3_UH@Pf$J-x1 zWz?fzNSR-rjjxlc6)#KmY}D(w?Zk5b;dpPVU1--i%CZRn5y^R3E4brs%4T{Bz1%ac z_FK%OXXknkmS&svRU&`%Ck_Tx4g`7Ty59cpM+zms%=6WQ(->s;)$t7~sRlHxHl zqKk43$A5he*J;TZyS;XIF%0iPBl3DyTk(>@PL4y@sZI-;ou{^h$ z%%LGsv0bUxILyT|Yb;m0LUo5%yMx5CWY%NCdPVn>S2HCh7JFp#aFwlb-IqPsWbaN0 z<=pfD?c{zv$W)a7rEA(_DW_odi^u1MV&In;PfXEpd+UhAAUZY}Yw4j-sV?iow=sTE zHcSlsC)1`k|LacX5$m^@!80oz`H!RatdfY@@j7MY@Ql}kV6k%^Vw&->KSUUBq;~qH zvhKpcc3b%`XKp^!GJlTZZULv6JroA!|Hq!#GKFIcIu2+2(fOL@(8FQ2&eABM-j&Eg#|Mi;gKsSQgACt#B|Uo)ZfAZe@T2)#-NK3RFORlE z5~YZ3o*$E+?R_56M(n^WQ)i^iLp$pMy$vCc{qJNuOFaa|%b&kdP6l_3{^pPd52jdL zF}Y!=8^C)eFYci(IXUkpvTUX4Na;pr492-V?S+`hkqtP>=1@7M9{kTlZAmT#Y4Rnn z20BhLV0578s&Ig}sqUTf-mYPtnDWbP2*d5b)bd{zG5aclxoyRC_C56E3U7;H$fg4vZ&AEhrmL+$(T z+U4SfPx6NSf-S5BZjrIB;=S~fB$eFYuiCW>9{+k`C4cFT$OtxNMDgF4bM<<|$zlbp>ZtSpSgonTE>+_w3{ z=X5FGNn!ZJEn-p;?F!xCMrTV>1poS~nW!^`KON9Z?EK+4yo>?-`HhabxgIO54!0hAgVn!SuV2fQ` z4F6HdmgP=6((ePg-y*|oaUie4VP_Z{Iv6mk2CkNw(^TGt>on)CYScE_G0qx%O*B?D zj&_1(aj!J4)qt-(61^9goLfUC#cmuPEThN!xuMTdl4H?fo|$_HKaXrP@TYN|d|Li$ zyxXHhbxD^Rc=&9z!!=EYw+0+V;fpJpc3|c=AyS`l!zcOqNdJT`e-Zg^-zXDyzDXmT zTU7V7fNXa+Y{0w4RzcNVC4Z)Fg|V{e(4OGaQHS1vRACRwl#CCGw~cNrwuC9o)GpDl z6m)14>b0VmX{j+{%j#uexpo!nvFNjQ{6f$9`1bd~9iRCjJO2~k>>$Efs^rd~w}Gp7kDzPiiEGA>dD#rQ7MnJ5W-YT_>v ztauYCyp5=2UF^Xo-mI_AII!4Aj6yf<<3Lm!XR)JdiXsjDG9}@vw3m9VD)zb^**VKw zPE6_QL(Lf_J+Vyh^$Zu!!E;Ll%zqC(w;vFt+QDVv6^UX$0)|K_u8jI(PzV48J=iQfJh_^D<-OY?6XOEFd=V;5m(1x(0{LqMKqK{Y9-zij+5ff9ngG6?ImWk3Dd(4jWG^NVrVcou%9R5>bl%a+A zce^miOr_GlxAerjkcc(qhZB%dQR6+kw!xv(7YuGLZmmeH7nTKtBjuZh^{cS-XT#!) z=?Y&{!(YUZtBppl?%=wV_s)n%DH09n^!?D415evD_d#*~gU?Hel<%dFw`Ud8$8dXH~hn$YzxZZ8|lyc1kCwuQWOO$;I$8d_d(XpKn!#ULwn&5H&LdcAQnweGWB>4To&3iY1h`FMM= zO{)@yM{~sD?keUfjuFoXT%Y2Y?mytT!0}c*tY)9^r$Nb*q$B7RhGkY!tq7ifiVLH#H9Aewjyw$601Hl$jw zcnNIdz_1rGCb>^y?OI1>BR>cn*dD@MCcE6|z+N*D6eM!QejlS<}F?ng;| zrd@~DZ}@wB?H-Q#5c}S!sLt%KB;LRhV0OI-L3o$EQ!hDdsncQ$wb2$(tQ@M88rAI3 zT`agp7glx9x2zsk{5?|StKr!KT@$K^YRZFq^TX?h9}zrc#gZl{m#{T0oLN46n3S*G zEi*_zmE1(9Blc3QJG||#+3)Oz)19?q!x=(g`h;A3X@YjJLGsLP%|) z$%jUb{PR=qJyBorQV|it_?i;4j${J2xy4FClD|YW$8q4nD~kRHa;HJa;EGaW0QnYUQl7uQn{96)k`3IQ-z=`oLL(mo*HoNjgw5tVXqzd@#E*jbO43vE?m%fTn-< z>1y48WN+*G{IvSFq@e!s9nhRJT4-I7QT+khJf_BJ`kH;16#QigGA>Vh3!Y^>Eo#3t zKat2o|1J%;EFtJ?_Lcb{4g@oeKFv6>|F(*d2`ktITn#JMO2x;Dbsm^GMvBGgA=hAw7V#p?3T_VzGm~~?JRjDW8n^F<(KZfV z*-LAu4%o0fRPY{$82P)d-bG$u4wvz1_MKt4m~xXBvNdlWe^Nm^RbH4!{?3TbyYSr7 z9s2+kXT`K8yTmwEe*ET00DraZkQ?hEm#o%Tv?Glk@>_}jAiHnN|ISpXO{~AQvk=_} z%^939%OEd(9~QMltP8X+G|`J;CUx&)+74w z?B}!i5-$>>aC<6}VR>F#mw^LboiMO36380)if_!5;~&#e!hQs})!f;V(Nv65Ek<7L z{^L=IS@lm<4m3I-EK9Rzk9cyBMyTxSpV?&(D{k5JdxGW7dLrtyMcwR?hwpD`2un%k z`b>+k<*;T%u%cW>8r_#6aP9PtT+?gywrmdw*$I$T#2w`gY{*E}aE4!1R;siX5Zv8) zB6KFU_#eUh7E2_%!va0uJCPs0dJ>^hTe>GD)nal=%>4GKD%%Lx9Fs7I})--+*!(Atn2-PRBd7)Ms9uO>@e{LX!|Zswo$f#iBaZ zEL8yfTOs)9PeEGJ+A|I=`gy2-iC!DoMbF#uuqmSplD!ufC17`(1YhH@@2nvwjKP{b zb`9rs`~b=WSWqbAZF8cua>-!Bj4{f&8DDgf0@WmP5R0$SH;#^GhHg!cnWE|>V{6DF zBKGnV7--p;uM&{BrsRc7*Xe;5&Dnx;F8>667{ANy2$J$MUVX! zu>|D59HS;($8kWx$Z6y&VRJCy0Ia$4jOiPv)G!UQ`bZf0yX+2o%~OLsz6~MvZDoH` zq9XXK%#HhZ9$Rrxl$FZfbsVWBadVNT=asP*b#LS^v#Zzawl?nKyg0rZkQA3fFa%`q zlR6l)%V@`>aL^urMOO|PZbB&U>Qfh6pI4D{dAkeMzK^t;h#2-+L#|G?w;28-E$m^_ zO2>IZAJC6xFXeliO`5QfTFveaxWZCnHJzPPuXK2oYdNJFTg+IP^|YVh&IktrH1o6E ztt*T9`%P;WF9$4w#sgg}>`d>0o$XWcjWtTWLv=>H4RfohGNXb<<`VAwLPG^ci#~yz zBmEBzrOJeuMZV=^ZG0@K&(fMe3dZJEM8>W#c@$wCb4fY73IuYX;U^o0iz6@vTh*Iv zsrY2P)h?T=OL&U9Fpi*yt68~Nh+UCI&M#49GiIc6=cr9T+TNz;aJ(8TyJYy9vqs*< zf1?%1Pi-k}-VP6;$Z_%dZ{am{QLD+uB?uHyfo;UQ23R0n=QI2hMfmbN3>lQzdS^)17F`ALv{PM-^fb_rZ(?fy3gxQbpn(w|obN0qB>WOm5CVi1{4D zrKsy7(V2H+G`V`J4Lv+ysr0h@KXDcBl7j7H zd%^4+Ej_1#dcAs^Wft<5-^Z@R!8>Jr_XRhe@E#k#ohqE&_tczcU8TufF1|pxY zVx@poPL7WA^8U_TPVe{?ZK?vc{{$K5xeQ62Xr7XUqu4DZ$+XJ)^%3n-#eO&YGOsfF zeOmC1A$&yDgOOL6;mdHP-yi1hQ$@_D1=v(y284%o-pZrA%bma9xbMSe9A*$`P`pnX zq+EqIFvTY6J`-j=zsRgGi})M&G)0lW_#*#xO0N85(Mu!8D2g6f2*ln`1=ZM;%Oh^1 zj3xR0>BnePUkqbqyjKr48|N_;y=T+;kA<&}W%iuKz@A!E*rszKpD*|KOT;TymkbT_ zXS|U63y{x)R)_Dc7@G?4I(_kycaTKn%yT`DaPZ>CAGB&_RM_`r|3F&m;MHUtzm;7^ z7xCHKOtqK&hW%>=?iev3q;6l^eK8UGq3BX1 z^Cwv0tL?GDg_|p_$d_4uZ3fzYDLU=ykLn}O&)x6!BKX#!9YzqfM{LeB9VDo*$F~WD zo7|+!bMuEL2WoZf^_?70|7$WQGzz)q;yVibUMR$hgg*3|`$B?dSN961uKz9qy^4UP zMyI5UftyCGiK3H(Lj%KVt=m4SeHJK@qF4QxXw?+Etr0mK z!Kg2N@3n#?xX;HV@4rMNARE&p8^JS&*Q_ZER6TW#-3V%S2#*jUU$XtD>9EZdZu^T--1&uCDq=hxTk!{ zzBg+WEB1;-VlxZ!`(H&+qi>AM zXL?TaoSyh6`E?C;hjfS>y~pmOb45X>(};k~tHIhNt7w0L>2awOs)mEh2k$|Ey9zS1} zyu6qY}jar6q~BIno&?V8dt$ zL-TySaPUb1BkXJ6Np6IRD%g1=cpy;8wJ^Up0h(hqIHpuvLEcuY!L0f!OPRlwp4wHA zL516N+}vT2FM?f)`*RaZaF1on`}2hk*=SoupxbRiJNV+{YxiA2(QZwF<`v&|JQ>T)uLdQl{?J!^Hi3n)ZG-D;J6^T4^gOaeREy>MRVwNMxv(_mzy@TVYV7CAv?AQ!V%=qI=^$6ezq&FtlYe3w@># zyiB)d7a}RReMsS7R^FXdKwD@fCZ6zBXeNa!q{$>f2o}yNQap>qs$i7#tqJ~9$CXc2 zA6^RF06(^PY&mPeWo}_s{7wAsR#YQ1QBQ@?X4UuwD;ipSOV__`<$8h`Nc=}W0ST&( zj445y8S{cGci%HNwh4SlT2iLbz;yv#M!L~B1B;&+@(9dRPgvQCL+U#Xsn(B4*7u5>opji1z4t|QSbK4CqqSFJ_oXG)o)`n z#DWx>!3P!9qJK<|Qt)nr?1WI0=8nnUork>WVf&h*`Mc@+^w=Z8!%mlPIyZSM!hWF{ z;3eBerRx|^QidR=8#NMhWZ&*LaaZqYE3_Y(ov{i&A zo#xzXU3{kAi1Uz!)Lp-|@EP3`@=&`2fJfiHTKz3F`xd`2dVb+vrN1cPgbyrJ4-kc8 zi27kiTh!;B6Yy%usLI`$c4Z!Da&9Sh3Gs01!|AY8^lMm@s&nqP?!&Yr95A5!zJULaI zg7RtKEpaG6`uTe`9<%M8aacv?(e1gps~_rrFak=b$bD*G@eST6ZNs+alH{t`EV zMF9B}IafGn(yZ6Amm}s>Ku%;jAw6&@0_}RzAz^(YjXw13B$YKWZuG8UT2|i71a9sDiZV1 z9wL_(HQH*S+p@gSA_sY}`~IMi5vh%n27V2+1NBg=Pk%-^al zYWb8|&ZDBN#l~K3o5Z*2|H;{^&zrI54X+Oz{IPU3u+eXYot@Qaxs(08*@3QkrSOnn z+e|VOe*43rJ&FG}ekfFJXb8#o25qrNB3N1oTl91+A+&NTlctb&$`t0_@Y4;i*dEeF zu{vCaJ|!SMKRo3KE34oa_;LgQZP=|3@uQNamT>XR9n1H``eHW-(!4$;@S^Rubf_%% zjj=8O$uWMAO#1-;pk`NNx4anAI!Vs!s>v-)@XHvSNLrU4gDw3;Tl~S?E>MGfaNc0z zH-KVydDlNw99_g%)NlYaO0dMM?nC0z3$;md7o!9~kp^d?@~zKA3D|ptV8``a#m=+} zo#a;7Q2JQFmx#0w5)VGgu=}iMws;qELuZ>Ms_aCeosZr9Ax(y?*&bB6Q$9$(Ewy`5~MtQqS<7e2*U!R@|(71K~?GwQ>W}PYaWijR3 z#j)ImgPN3Iz&lpiVe7_g?VW!fbT&TA{QWt`si!5_>yq<5vC;#7r85PA1CKQUw7U2) z?t{1G9R-Sj829PTBAl}-x`$@IY-!Kisye6sA)Od#8e# zGZYAX4JFWg3Q>FZ*y`4yAe>8l%H{al{#_fIl)FtN5K|Kxcqu`XwHPr+p1^zZ5L08vH)K@bN_AIVm%)Jc=eIN ztCEW+JfcpZn4_FL_AOgA0=~-`W-TmU=+rU~M_zqj@l2UZ7Flu4mRRU110H|MTdD<% zk1z?X{dE#6hCt>Vq^(6go+|_&@>Dktw z887P>l|%{HumSP?f3I=fH^B2debKqdeopW{$bw5ND&@4`eUnRCQR5OQ*lz}y!vT1& zeF_sT3yN%07c^>XRzMpm6u7*+^*2j!+=?s`Je0QgW4xyOGALg%bm{YH3{o@ee-D9y ze^6V91o*!u_`^ADrGb2=yoj-t*->?PSJ$;OCqN**4RHmw6C$@4rR{5$_yK^l)F$6# zVGI$5Z;s)=AP$__=WYkwSR@V-R(XI$0m?7Jd9{~IKsY%;`43XiUM+-gwWmO3u>j*- zllxfr2~a-9JhythhRWbzNK-%d08=copqZCXF_`!by5hXXZrz$-W#N{o4Lsj;(&PlK zjo)dkMDDykC=%z58$WHj(qfOQEpe%Ypk}z`Dv#(~|8>fK>S3GAEs)ylqUQox(Z!Sx z0I6W}pE2W}%OG}ivjhaUf%k?cDgl@)pmDpwzF>S{g@`DkM%UBa8S4Vnpcb!a{2j}9 z5TwyT=uBjid2N&75VYHjmM_qcGgdjP4>GZ#weflYgNX$ua?ea=Z9?1349zb-;0;Cc{5>Z#Qx5X02cvzzHS}O|Z!{j`%1%Lyn7NX@nZ9gLf7L-R}yNyTu0OdbqE zQc}<&sB+_icgGs0b~c{d*CR#v7v=|WvRioyC=wcMx%mt8Nh{~6x3&3B!E&u!#nI~i z-$?cb7QpM43-quCMP4_XDHulum)4dX{m^-v*eZM`^0G(W!5>p@S-(?-03=`9m0(Rl zp531NrYd%lDt7Id%>UORpvZ;4(pos}Ce*KCbCp+Z%Mf1cn{s-s1z~NDX!OC)a7sM9 zoCeAdki6=PRF*Hz_@2va2?7mfZm$w@XZj_t21Qt#^Ko|4nwy9gG{KK&j|*^;Ry$p_ zAzh8{I!R{M3?R*XCFg@}mcpX&lCH^sF+=E(M04#8ajTcIAQJ_y3#wz)9R<49CqOCE zi&(CNyZ3ITCTb3)J&d`)+ikY{SLczv2R)R@k9qPJ0I3JgSG&C(gj|R>gHL>b!ytzk zh{IWs9$}#{p}t0C`Ej}(_wfjmwwG&Ere=&({B*3%RX9;JxxaD@&XFbwKsIs0a_}%< zY~cKk2cd)aG$>l-T`NDz&1I@UAd47X$Lc0UAN)6ALuOz>Icpy5y6i-d?gW8%dT*3F~ml*C$_e^<5t+Jgs1V}$dAd< zSOH^1`Fz@xvXj@N2kKAWW?AHSG!{eMOYrPIMh`@H9Qs*{#Y@QfxBwR#IU`T;@<^EV zomokDh~aa_t1g7_sCXsUo(7pDzs&pb+bLizg}Fr1~Sn|q3_)*(-l+QaBws_)U}4>{yE&O!FbYX zJ^$P7bpO$GLBJXVzJcwfEVCzrfczp?AK%X*t*bMNmCr~k(^G#^p33xprtZ~dNcUH~ zoBYcM>wIiJ1pQIFXcA*Ic}i4??lZR{T1hunV?q&UEWqT^OJUn=fb+|=;F#Oc3ZyECF zus|YT8j@cEs9Da}n!dLuGgW2FrAT_KWf0H!8zEwEa#TBY0pF}Br7T^kX;TC6;|%|5 zbtvBta>ovz-d%RU+OS!Io+Z4#AG6_{b1cOchZtTL^h{8eZP0*A&~h=LX=+=x3MIZN zk~|F=%F%iu#TDr}))dbAm{| zd$d`@Ztn45yy^$tmG}Q#=H-c;D$zWbwY7TIRKX)}$LmY&_gmnO27nCD7zAQ}a6s77 z;L$u-HnlZwx`N8Q3KXO?^$wlm!fAVAA7QIyxf=f(tK&T$1X>aLs{~$emhj*CP|G*v zW?!yXX_H?9W+w!s*7;$lOS?r_ZuYCCX~e(Vo0&Xv_E}e9zkKBuxB7a_+--ukA7a9L z;LsML+!;?3`{jS!X3F#f3_z3FN>B4U4?ZO~dk)QF0`V_{ELWa}5^^>LKms=x(_M2W z@1`QW-P*n37AbkT;R|m!-PZ3o|1sbRU#oK{cRAh?oyI>7Xqi$D<8~cbOqBQVh0njY zxu@h{f9AF^nxU7-8!)#Xk@eB$xM|-3pKd`lZ@|_M zr74l#%Rcgd-!v7Wp-2k=2&T`no&X)iZTF2Cd$KR4$7A?X231{g(LKYgi5MfY(m@dm zpIHOLRbVDZIp`qs@n{l4&^Z)sT>@<@hIAf{gp*K{UJc&?bEFWoWRjJHbV@VpInA3InjkEn0mi-qrvG0N&Uf-;7Q_a%ZzfVZ$17 z2=~+FJGZsiRQ*8mcNL0=(k0N!l|{rLQ_KZ-_QkkC{@|ZWUqnzAUFC-ja%(7mmE#DZJCtrU=C3>7}3v8Kz z1)Z-cqeZ~U$$MmUmow_OZYZ&nTnQD^IDCq!bPFxKoT!u0^7xsp^uf!eqt3+6 z$AVfBP&nm1fOc{UI2$L0?Bcb zZ6a;c3q9Di0yfsTjgyNDQZ*8Fu79MOiz_T~^Ws6RTExF%ziqw}OuXBDT7>zX-&`ca z2sF^T*6H>4kXgp8dt?X5{vTK~rLbx5GfIUuu|Up!tLkgB=8j>N##B(yW|wj$T7^0# zxxVt}Aa;9el8`rLF4gtVw0)gNYSsSlyyiK309F#^1yoo691K>i;~++GD_;OL=~h(9 z>lV8-uVW0Wz;PIWy4@1v5f@ZGE*y4v90kN@$-Lgc-mtHPa7}yrFMW{nISTi*dhUGo zcsW#7cTrZB_Bv6@&e)@n#{vAnJ-VQonvJF^1%4-0+Oly^=87zw62KF<(K%c zJI2>Ujs*tKT$vt*bp1N|*I6$BRU&e_TTLB6z2H?0dNbNxOpK8Qwv_AV(%~0r2uw;B zocd_&&-X$Z=ReOijRdcxwuHYXyx(f@m=}v!Fp5W~PObet1a4>*VxT;}|mp`SvKVECY zmm23SH4ES7Yq;peWb5)%+t zfmRX+0Mbo}cY`7Op-2qql_21o^q0dD?V3rQh-d&B>+Sc^V0tPAzji6jW9IeETsM7y zl)Pj(gAD_G8&oWPl%QCUaCh1MRAb_gRP$m*FRM_I!yrCq&{IF!# zV%qWhpp>s4&$3mHNw)v|^z39$=JsbN}%dG!z*ypcpWff zbpSo@OWDQQ_W`isTprA9$pnp~4^)hvKN7kNF4LK>4J z5)m!80p}Z&a_kdFGV{tWgtSw)4glvI=-T&>jiUF`X01hpB(EaI?ong^M(E+zUrCl_ z?gF$BfsL)?th7G?VBl9)C_o~)x^_+yp&U7|{DSwfi6(-+q$09~(nUt-G* zgE&B)Bd_0;05`8;8cKm6RiskX_}F0%y|=MH`{pzQNZ@%pe;!wS=B;2jg;eK{R>m52 zt|0&GHXA>KKy@CX5x9614Qg%P^*^RqphBu^zZ=&CbwqF@3If+V9IelR)M$I%6+Spq zRq8Qh`!8;J@2i-!mS-nV|Ez}iK-2TWJgiRwbHCto)E(Un@Xzn1qYitIsgi1&mHw+t zQnMSc^`9*>4O)Dm-2*(*)5R~^>)q!NmY#rOj`<)w+4v%U{$KSv80(+osYZ3JofJrT z2TW&Fz(!+3ylPbq?@XaT(3KjEv?*PKW0W^+vEn*Zt}ItBG0O2M%>`(a19!e-K0v4b zF4cZR?0f2y`S|r_-Q@1f?XN(El-g&lcs|E@;o&p-z*Q9cd0{1PniNKhMkTlGNOk;3 zX#ITxvO62&AOSqi+vzeMpGM%!D5C0YG&pld_VzNz;d zACh@@M{?iG4gp;CeYMR&KLV_eWuAIxsZ6jE)-D`0yu}3MUqIumsKcK5y){*pIv9WW z-O6&>OFo!aK>GlIM$#T984DnLgYqNV5tz!Qpf5k`_P!(=V=~Wu==-aHxWj{;s;LND z=!%q4%SrMwI|dkFu<}+q;|P?V_sb2fOpjV`p7I{?vmGV>eqI$gR&q)m7~o24yX&`F zHm$^j4b{Vb!JwzeY-=9T)7{4_{lAx54v;p!d`)=g7Ndqzd?ugp=2s8`-vFvk>XC)PF}g%NUs z*BSxdKLld)*>nIfYVRp%k02oNvZ?@DqWuiKWjY)%uWp;aYn#1+gcc~jY+Q%*tpTmM zjBEe%Q&V2$A|C^g#`-}|Kk6ePv_L}8ENF8bl|QUMj4$Z@dSLh2AoP4h{}?Flkj9`j7kJmU&5h$RfF^>Ems;fZ9wKn(E&Q$d#t(xWwT4O+WajN!MN{j^xxc&+J&4=pfG09)nNspN4J7_;|KV1Z^r=< z;IY+ZjN_Ubh7qCbOc&marm_jY&^}f+Z$A1?UST7iHR7?fJ$%ANl@`!>Ci3oak)Pg% z6{=%6B4W}yOD5W!ex#m$DYB>+AYaibaPz)OvfsiPx zK?kCxKO^lr3j&Yl{o!9{6s~kT*t;?O0FChOdC8i%f#u>pdz|GokvO)OJu$pKrM%NU zTJdY1hVt&0k44~8NhA65$osyW4j_7E$t(x0BEEduJR>#_5R}J7U0ZL)4GwcF{k*V_ zkx&8@C~~EdG#$K75j9`K2IHZG?7%cz6>poyE{C3%BT#tvv5(_1hC(2+=z|q|pI<^A zwli=|N^N9cIqodXHl4z1HcB61;%R(!ly@f5VtPcIA6g@2#|9LR~*%%=FEa^D`vS8mgR!(q=~}@t%P2 zJjTCeNJD@9j9c4j;>VR;V$xov?5uZAJtGG(Y~@!at8-FpkQn`e+c z$K3O2z^<-sPNzPnlIlJ)@upBv#4CKj{;uZSar7rk?gqH4jqv)W7a%IH{r-1Be;&F{ zYVknXa~Y0E`&!acM4U_f`p4%%4f7XfrsRCud>b!-BGuuId(!Q&uW>_!=%;u0YRKfFLvl=Y#5O0xDuQk2R)k)*i6h zb1gIVnm#Dr;$Ho9Tu1b|^?75}COc)=qneq{D(n%JPG}1fIS*uL)vC4*chFM+2hMsg z!DX_$m)@v}K#Vm{$-&>%?5#g~*bvVR{P0*e7|O+(6~1IC=mYi-Y}>9qF4LF}^;ChR zx6!T#QbUnZ`w0@Zt%C|{5mR`gJ80#iVa_f<-~iwj#d&Q-F*du+ zcDpt9Q!A{r6NBBb!*ZTDnO!`pPS&t^DJa>na*_wSIf8n)` zYZ|EDgvCS{m-HY Date: Wed, 10 Apr 2024 23:01:27 +0800 Subject: [PATCH 5/8] md readme --- eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/README.md b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/README.md index 28ee71eb4..ae0bb93df 100644 --- a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/README.md +++ b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/README.md @@ -6,7 +6,7 @@ eBPF_proc_image 工具的框架图: -

+
## 二、安装工具 @@ -73,6 +73,6 @@ tools文件夹中的eBPF程序是按照进程生命周期中数据的类型分 基于 Prometheus 和 Grafana 的可视化平台框架图: -
+
具体可视化操作可以参考:[进程画像可视化指南](docs/proc_image_vis_guide.md) \ No newline at end of file From aac200f01f09f46a51fcfedcaf22ecdfdf0c6daa Mon Sep 17 00:00:00 2001 From: zhangzihengya Date: Wed, 10 Apr 2024 23:02:40 +0800 Subject: [PATCH 6/8] md readme --- eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/README.md b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/README.md index ae0bb93df..4626ce028 100644 --- a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/README.md +++ b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/README.md @@ -75,4 +75,4 @@ tools文件夹中的eBPF程序是按照进程生命周期中数据的类型分
-具体可视化操作可以参考:[进程画像可视化指南](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 From 349b80020d797862268d605cd850ce2e14f47ed2 Mon Sep 17 00:00:00 2001 From: zhangzihengya Date: Fri, 12 Apr 2024 21:35:53 +0800 Subject: [PATCH 7/8] md detail --- eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/controller.c | 1 + 1 file changed, 1 insertion(+) diff --git a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/controller.c b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/controller.c index 121a8fdb1..1476b181b 100644 --- a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/controller.c +++ b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/controller.c @@ -166,6 +166,7 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state) } env.syscalls = syscalls; env.enable_syscall = true; + break; case 'S': env.enable_schedule = true; break; From 61e319cb8a4835e9872d283d812e84b4f3abc4bb Mon Sep 17 00:00:00 2001 From: zhangzihengya Date: Tue, 23 Apr 2024 19:35:29 +0800 Subject: [PATCH 8/8] md proc_image_vis_guide.md --- .../eBPF_proc_image/docs/proc_image_vis_guide.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/docs/proc_image_vis_guide.md b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/docs/proc_image_vis_guide.md index b43b75b16..2ed10bd7e 100644 --- a/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/docs/proc_image_vis_guide.md +++ b/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/docs/proc_image_vis_guide.md @@ -105,7 +105,10 @@ TIME READ/s WRITE/s FSYNC/s OPEN/s CREATE/s - 执行如下指令开始采集数据以及相关处理: ``` - ./data-visual collect /home/zhang/lmp/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/proc_image -r -p 16279 + // 终端1:挂载eBPF内核态函数,但是处于失活状态(不进行数据的采集) + ./data-visual collect /home/zhang/lmp/eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/proc_image -r + // 终端2:激活eBPF内核态函数 + ./controller -a -r -p 16279 ``` - 个人喜欢在主机上进行可视化设置,这样方便快捷,所以在主机上打开网址http://192.168.109.150:8090/metrics (其中192.168.109.150是虚拟机网络接口的IPv4地址),可以看到暴露在http网页中的数据: