聊聊对 BPF 程序至关重要的 vmlinux.h文件

本文介绍vmlinux.h在eBPF程序中的作用及其如何帮助开发者理解Linux内核数据结构。通过使用vmlinux.h,eBPF程序能够准确地读取和解析内核中的数据类型。此外,还介绍了如何利用libbpf实现跨内核版本的兼容性。

1.1 前言

eBPF 是一项令人兴奋的强大技术,其允许开发者在 Linux 内核的核心处添加自定义代码功能,并且我们还可以通过编写简单的 C 或 Go 程序与加载到内核中的 eBPF 程序交互,用于加载或读取数据。运行在内核中的 BPF 程序可以检查所附加进程(或内核模块)的内存数据。为此,eBPF 程序需要确切了解处理涉及的数据结构类型,这可以通过  #include "vmlinux.h" 实现。在本中,我将详细介绍 vmlinux.h 是什么以及为什么你在编写 eBPF 程序开始就应该使用它。

1.2 vmlinux.h 概述

确切说,vmlinux.h 是使用工具生成的代码文件。它包含了系统运行 Linux 内核源代码中使用的所有类型定义。当我们编译 Linux 内核时,会输出一个称作 vmlinux  的文件组件,其是一个 ELF[1] 的二进制文件,包含了编译好的可启动内核。vmlinux  文件通常也会被打包在主要的 Linux 发行版中。

内核中的 bpftool 工具其中功能之一就是读取 vmlinux 文件并生成对应的 vmlinux.h 头文件。vmlinux.h  会包含运行内核中所使用的每一个类型定义,因此该文件的比较大。

生成 vmlinux.h  文件的命令如下:

$ bpftool btf dump file /sys/kernel/btf/vmlinux format c > vmlinux.h

包含该 vmlinux.h,就意味着我们的程序可以使用内核中使用的所有数据类型定义,因此 BPF 程序在读取相关的内存时,就可以映射成对应的类型结构按照字段进行读取。

例如,Linux 中的 task_struct[2] 结构用于表示进程,如果 BPF 程序需要检查 task_struct 结构的值,那么首先就需要知道该结构的具体类型定义。

874bc4ba7529c11f73e99bf596ca900e.png
vmlinux.h diagram

1.3 CORE 一处编译,到处运行

由于 vmlinux.h 文件是由当前运行内核生成的,如果你试图将编译好的 eBPF 程序在另一台运行不同内核版本的机器上运行,可能会面临崩溃的窘境。这主要是因为在不同的版本中,对应数据类型的定义可能会在 Linux 源代码中发生变化。

但是,通过使用 libbpf 库提供的功能可以实现 "CO:RE"(一次编译,到处运行)。libbpf 库定义了部分宏(比如 BPF_CORE_READ),其可分析 eBPF 程序试图访问 vmlinux.h 中定义的类型中的哪些字段。如果访问的字段在当前内核定义的结构中发生了移动,宏 / 辅助函数会协助自动找到对应字段【译者注:对于可能消失的字段,也提供了对应的辅助函数 bpf_core_field_exists】。因此,我们可以使用当前内核中生成的 vmlinux.h 头文件来编译 eBPF 程序,然后在不同的内核上运行它【译者注:需要运行的内核也支持 BTF 内核编译选项】。

1.4 总结

通过生成包含所有 Linux 内核类型的 vmlinux. h 头文件,我们可以在编写 eBPF 程序时对内核类型相关的头文件依赖。在下一篇文章中,我将使用 vmlinux.h 的便利性、libpf 的灵活性和 Go 的安全性来编写 eBPF 程序,-- 敬请期待!【译者注:下一篇参见这里[3]

该文章首次出现在 Grant Seltzer 的博客[4]上。

原文地址:https://blog.aquasec.com/vmlinux.h-ebpf-programs

作者:Grant Seltzer

时间:2021 年 4 月 30 号

参考资料

[1]

ELF: https://en.wikipedia.org/wiki/Executable_and_Linkable_Format

[2]

task_struct: https://elixir.bootlin.com/linux/latest/source/include/linux/sched.h#L649

[3]

这里: https://www.grant.pizza/blog/libbpf-beginners-part-one/

[4]

博客: https://www.grant.pizza/blog/vmlinux-header/

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值