入门工具eBPFbcc(工具入门方法定义代码)「ebpm工具」

很多想学习eBFP的同学,总是想一上来就开始写eBPF,这个有点难度,主要原因是eBPF涉及到很多的系统调用和内核struct定义,比如用于进程管理的stask struct 以及网络处理的 skb struct
所以这里更建议大家从bcc 开始入门
bcc里面集成了eBPF常用的工具集,可以帮助我们快速的构建一个eBPF程序
所谓的工具集就说bcc给我提供了很多工具方法,参见 https://github.com/iovisor/bcc/blob/master/docs/reference_guide.md
截图里面只是部分常用的方法,主要分为几个大类,比如 events里面主要是eBPF执行的挂载点, Data里面提供很多方法帮助我们获取当前进程id、命令等、output里面主要是用于用户态数据交互
我们可以从一个bcc 官方提供的demo看一下 do_sys_openat2 这个系统调用被那个进程执行了
先看下面代码struct data_t { u32 pid; u64 ts; char comm[TASK_COMM_LEN];};BPF_PERF_OUTPUT(events);int hello(struct pt_regs ctx) { struct data_t data = {};// 获取pid data.pid = bpf_get_current_pid_tgid(); // 获取系统启动时间 data.ts = bpf_ktime_get_ns(); // 获取执行命令 bpf_get_current_comm(&data.comm, sizeof(data.comm));// 提交性能事件 events.perf_submit(ctx, &data, sizeof(data)); return 0;}上面的C代码,乍一看有点难,我逐一分解一下就简单了,首先定义了一个结构体,包含了三个字段,pid、启动时间、命令
然后通过 BPF_PERF_OUTPUT 创建一个BPF表,这个表就是用于和用户态通信的
上面的代码会运行在内核态,把数据写到这个表,待会我们会写一个用户态程序从这个表读数据
我们先通过 bcc 加载这个C写的eBPF程序
其中hello.c 就是上面C代码,fn_name就说上面定义的hello 方法
from bcc import BPF# 1) load BPF programb = BPF(src_file="hello.c")b.attach_kprobe(event="do_sys_openat2", fn_name="hello")通过 attach_kprobe 挂载到 系统调用 do_sys_openat2 上
紧接着通过用户态程序poll 这个event,并打印出来
start = 0def print_event(cpu, data, size): global start event = b["events"].event(data) if start == 0: start = event.ts time_s = (float(event.ts - start)) / 1000000000 print("%-18.9f %-16s %-6d" % (time_s, event.comm, event.pid))// 定义回调方法 print_eventb["events"].open_perf_buffer(print_event)while 1: try: b.perf_buffer_poll() except KeyboardInterrupt: exit()最后,我们执行这个Python脚本叫可以轻松的发行到底是谁调用了do_sys_openat2
入门工具eBPFbcc(工具入门方法定义代码)
(图片来源网络,侵删)

联系我们

在线咨询:点击这里给我发消息