目录
CO-RE
引入
思路
介绍
使用
CO-RE
引入
因为ebpf需要深入内核,但内核中的数据结构很可能在不同版本中定义不同(尤其是结构体,可能会增加某个字段)
但我们在访问结构体时,比如一般通过指针+偏移量来拿到特定变量的首地址
- 如果定义变化,偏移量就会变化,就会需要多份ebpf代码
- 这样就会增加维护成本,每推出一个新的内核版本,就要根据更新的内容来重新编写代码,太麻烦了
- 所以就需要引入BTF机制以及相关的技术
思路
其实我们可以自己想想,如何可以实现不同内核版本的兼容性
- 其实也就是数据结构定义会不同嘛
- 那我们就可以不预先规定如何拿取内核中的数据结构
- 而是在程序加载时,再拿到内核数据结构的定义
- 因为代码的编写,肯定是使用的当前版本的结构,然后需要时,在定义中查找就行
如何查找呢?
- 还记得我们的动态库吗,他是在程序运行时动态确定函数地址
- 首先在编译时会确定该函数在文件内的偏移量,在程序需要时,加载进内存中,然后动态拿到基地址,内存基地址+偏移量,就可以定位函数的具体位置了(当然,实际情况比这里复杂的多得多,看的我头都大了还没咋看懂)
- 总之,我们可以借鉴这个原理,在ebpf程序加载时,将结构定义文件加载进内存中,当程序需要用到某个数据结构时直接访问具体定义,然后计算某个字段的偏移量
介绍
首先是要拿到当前版本的内核数据结构定义:
其次,编译器要支持这样动态计算偏移量的行为:
最后就是实际的重定位操作了:
使用
总得来说,当我们需要使用 CO-RE 功能时:
- 要在内核层的eBPF程序里包含"vmlinux.h"头文件,否则就是不使用
- 需要内核打开 CONFIG_DEBUG_INFO_BTF 配置选项