lyft|入门即享受!coolbpf 硬核提升 BPF 开发效率( 四 )


3.3 libbpf CORE
前面提到 libbpf 开发 , 成为当前最主流的开发方式 , 但是需要为每个内核版本都开发特定的二进制程序 , 不能达到同一个 BPF 程序在不同内核版本上安全运行 。 由于不同内核版本数据的内存布局不同 , 就需要支持CORE(CompileOnce、Runeverywhere) , 提到 CORE 我们要先来了解一下 BTF 。
BTF(BPF Type Format)是一种类似于 DWARF 的格式 , 专用于描述程序中数据类型 。 其主要存在于两个地方:
一是 vmlinux 镜像内 。
二是用户编写的 BPF 程序内 。
二者存在着一定的差异 。 第一个差异是:BPF 程序内除了存在 .btf 段外 , 还存在.btf.ext 段 , 专用于记录 BPF 程序内使用的数据类型的情况 。 第二个差异是:vmlinux 镜像内的 BTF 程序由原存在于该镜像内的 dwarf 信息简化而来 , 而 BPF 程序内的 BTF 段由 CLANG 编译器生成 , 需要在编译时指定 --target bpf 。 利用 BPF 程序里的 BTF 段和存放在每个系统上的 BTF 文件 , 我们将这些信息进行重定位 , 就能确定每个数据结构的偏移 , 达到 CORE 的目的 。
关键组件:
BTF: 描述内核镜像 , 获取内核及BPF程序类型和代码的关键信息(http://pylcc.openanolis.cn/) Clang 释放 bpf 程序重定位信息到 .btf 段 Libbpf CO-RE 根据 .btf 段重定位 bpf 程序 目前在 libbpf CO-RE 中需要进行重定位的信息主要有三类:
1)结构体相关重定位 , 这部分和 BTF 息息相关;
Clang 通过 __builtin_preserve_access_index() 记录成员偏移量
u64 inode = task-mm-exe_file-f_inode-i_ino;u64 inode = BPF_CORE_READ(task mm exe_file f_inode i_ino); 2)map fd、全局变量、extern 等重定位 , 这部分主要依赖于 ELF 重定位机制 。 通过查找 ELF 重定位段收集重定位信息 , 更新相应指令的 imm 字段 。
skel-rodata-my_cfg.feature_enabled = true;skel-rodata-my_cfg.pid_to_filter = 123;extern u32 LINUX_KERNEL_VERSION __kconfig;extern u32 CONFIG_HZ __kconfig; 3)子函数重定位 , 也是依赖于 ELF 重定位机制 。 但是目的不一样 , 子函数重定位是为了将 eBPF 程序调用的子函数同主函数放在同一块连续的内存中 , 便于一起加载到内核 。 例如将所有子程序拷贝到主程序所在区域 ,always_inline 函数 。
libbpf CORE 开发步骤:
1)生成带所有内核类型的头文件 vmlinux.h
bpftoolbtf dump file vmlinux format cvmlinux.h 2)使用 Clang (版本 10 或更新版本)将BPF程序的源代码编译为 .o 对象文件;
3)从编译好的 BPF 对象文件中生成BPF skeleton 头文件 bpftool gen 命令生成;
4)在用户空间代码中包含生成的 BPF skeleton 头文件;
5)编译用户空间代码 , 这样会嵌入 BPF 对象代码 , 后续就不用发布单独的文件 。
6)生成的 BPF skeleton 使用如下步骤加载、绑定、销毁:
name__open() – 创建并打开 BPF 应用 , 之后可以设置 skel-rodata 变量 。
name__load() – 初始化 , 加载和校验BPF 应用部分 。
name__attach() – 附加所有可以自动附加的BPF程序 (可选 , 可以直接使用 libbpf API 作更多控制) 。
name__destroy() – 分离所有的 BPF 程序并使用其使用的所有资源 。
四、 coolbpf 享受式开发 前面我们已经对 BPF 有了一个认识 , 到此已经入门了 , 同时也学习了 BPF 的高阶知识:libbpf 的 CORE , 它也是未来的一个方向 , 但是我们也看到这里面 , 还需要写一堆代码:open、load、attach 等等 。 我们能否把这一切进行简化呢?能不能享受式的进行开发 。 别急 , 先来看看常用的开发方式:
4.1 BPF 开发常用方案对比
1)原生 libbpf , 无 CO-RE (内核 samples/bpf 示例)
优势:资源占用量低