eBPF 例子
介绍
What Is eBPF? 是一本非好的入门书.
Learning eBPF 是同一个作者的另外一本进阶书.
key notes:
- eBPF 程序分为用户态程序和内核态程序. 内核态使用C或Rust编写,然后clang编译成eBPF 字节码,当内核遇到某种event之后,就会执行这些内核态的eBPF程序, 然后生成数据, 放到一些eBPF程序定义的Map中. 用户态程序主要用来加载eBPF程序并且获取内核态写入Map的数据, 然后整理分析展现这些数据.
- 内核态的程序编写成代码, 然后编译成字节码, 然后提交给内核, 然后eBPF虚拟机验证(Verify)这些代码,如果安全, 则加载运行这些代码, 等待事件处罚, 执行Action,写入接口文件.
- eBPF 为什么需要一个虚拟机? 运行时动态编译, 验证, 不是预先编译链接. 它不是通用型, 而是特定场景.
- eBPF
bpf_trace_printk()
到/sys/kernel/debug/tracing/trace_pipe
. - eBPF Map 是内核态和用户态共享数据的渠道. 用户态写入配置, 内核态保存中间结果, 最终输出.
各种类型的 BPF Map: https://elixir.bootlin.com/linux/v5.15.86/source/include/uapi/linux/bpf.h#L878
Linux Kernel 关于BPF Map的文档: https://docs.kernel.org/bpf/maps.html - eBPF 程序不允许使用其它函数, 除了helper 函数, 所以要
__always_inline
.
bpftrace
经典的 one liner 的例子: https://github.com/iovisor/bpftrace/blob/master/docs/tutorial_one_liners.md
教程: https://github.com/iovisor/bpftrace/blob/master/docs/reference_guide.md
内置变量: comm, pid, tid, args(所有参数: args.filename)
内置函数: str() 把指针的值变成string.
probe 详细信息, 包括参数: sudo bpftrace -vvl kfunc:vmlinux:tcp_set_state
列出所有的 tracepoint:
sudo bpftrace -l