一直想学习一下 ebpf 这个东东,最近买了本《Linux 内核观测技术 BPF》,准 备系统的研究一下。
原以为有了书之后学起来就相当轻松了,可以我发现书上的第一个例子就编译不 过。
书上只给了部分的源码,还需要去下载配套的 github 项目,这也没啥关系,不过下 载后编译也是编译不过。
编译不过的报错也不过是 types.h 头文件找不到,解决了头文件找不到的问题 后发现又有新的问题。
网上搜索了下发现基本上都是在介绍 ebpf xxx,没有看到一篇讲如何上手 ebpf, 只能自己搞搞喽,在这里记录下遇到的问题。
ebpf 程序的编译依赖 llvm 与 clang,需要安装这两个程序。debian like 系 统可以执行如下命令进行安装:
sudo apt-get install clang llvm
如果你要使用 python 作为 BCC 工具的前端来编写代码,你可能会遇到如下报 错信息:
ImportError: No module named bcc
可以执行如下命令安装之:
sudo apt-get install python-bpfcc
linux-observability-with-bpf
项目中能够找到《Linux内核观测技术 BPF》一 书中的配套代码,它的 git 项目地址如下:
https://github.com/bpftools/linux-observability-with-bpf.git
直接使用 git 进行克隆即可,克隆完成后进入到源码目录中,发现它有如下的 目录结构:
LICENSE README.md Vagrantfile code img
在直接使用 code
目录前,一定要先阅读 README.md
!一定要先阅读 README.md
!
README.md
文件中描述了使用这个项目需要预先执行的步骤,具体过程如下:
debian like 系统中可以执行如下命令:
$ sudo apt update
$ sudo apt install build-essential git make libelf-dev clang strace tar
$ bpfcc-tools linux-headers-$(uname -r) gcc-multilib llvm
首先执行 uname -r
查看内核版本信息,然后下载相应的内核源码,这里需要注 意的是内核版本不能过低,至少要是 5.0.0 的内核。
进入到内核源码的 tools/lib/bpf
目录中,编译并安装
进入到项目源码的 code/chapter-x
中执行 make
注意这一步可能需要根据实际情况修改 Makefile
中的路径配置。
我使用的是 debian 10 系统,它使用的内核版本是 4.19,要运行一些 ebpf 的例子 至少需要 5.0.0 的内核版本,这样我需要升级个内核先。
我已经预先克隆了内核的 git 仓库,这样我只需要检出 v5.0 版本的内核代码 就行了。
执行如下命令来完成:
$ git checkout -b v5.0 v5.0
这里的两个 v5.0
,第一个 v5.0
表示的是新创建的分支名,第二个 v5.0
表示 的是项目的 tag
名称。
内核 config
仍然使用我之前裁剪过的 config
文件,其下载地址如下:
https://download.csdn.net/download/Longyu_wlz/12900957
直接拷贝为 .config
后,然后执行 make oldconfig
,然后继续执行 make -j
,发现需要重新设定其它的内核选项,一路 Enter 选择使用默认值。
编译完成后执行如下命令安装内核及内核模块:
$ sudo make modules_install
$ sudo make install
make install
的时候会自动生成 initrd
并更新引导。
重启系统,在 grub
中选择使用 5.0
版本的内核引导系统,进入系统后,执 行 uname -a
查看内核信息,确定使用的是 5.0
版本的内核。相关操作记录 如下:
$ linux-git $ uname -a
Linux debian-10 5.0.0+ #9 SMP Sun Nov 15 22:05:48 CST 2020 x86_64 GNU/Linux
libbpf.so
源码位于内核源码树的 tools/lib/bpf
目录中,直接进入到这个目 录中编译即可。
编译过程记录如下:
$ make
Auto-detecting system features:
... libelf: [ on ]
... bpf: [ on ]
CC libbpf.o
CC bpf.o
CC nlattr.o
CC btf.o
CC libbpf_errno.o
CC str_error.o
CC netlink.o
CC bpf_prog_linfo.o
LD libbpf-in.o
LINK libbpf.a
LINK libbpf.so
LINK test_libbpf
编译完成后会生成 libbpf.so
文件,执行 sudo make install
安装此动态库。在我的系统中,它被安装到了 /usr/local/lib64
目录中,这个目录并不会被动 态库链接器搜索,这样直接运行使用了这个动态库的 ebpf
程序就会有如下报 错:
error while loading shared libraries: libbpf.so: cannot open shared object file: No such file or directory
解决方法如下:
在 /etc/ld.so.conf
中添加 /usr/local/lib64
这一行,运行 sudo ldconfig
重新生成动态库配置信息 成功执行的示例信息如下:
$ ld.so.conf.d $ sudo ldconfig -v 2>/dev/null | grep libbpf
libbpf.so -> libbpf.so
完成上面的配置过程后就可以编译 hello world ebpf
程序了,它位于项目源码 的 code/chapter-2/hello_world
中,其源码如下:
#include <linux/bpf.h>
#define SEC(NAME) __attribute__((section(NAME), used))
static int (*bpf_trace_printk)(const char *fmt, int fmt_size,
...) = (void *)BPF_FUNC_trace_printk;
SEC("tracepoint/syscalls/sys_enter_execve")
int bpf_prog(void *ctx) {
char msg[] = "Hello, BPF World!";
bpf_trace_printk(msg, sizeof(msg));
return 0;
}
char _license[] SEC("license") = "GPL";
这个程序,声明监控调用 execve
的事件,每监控到一个事件就调用 bpf_trace_printk
来打印 Hello, BPF World! 字符串,其细 节我就不进一步描述了,感兴趣的读者可以阅读《Linux内核观测技术BPF》的第 二章。
在编译之前还需要修改下 Makefile 中的内核源码路径,它默认是在 /kernel-src
目录下的,需要根据实际情况修改为真实的路径。
我执行如下 sed 命令将 Makefile 中的内核源码路径修改为我系统中的真实路 径:
$ sed -i 's;/kernel-src;/home/longyu/linux-git;' ./Makefile
修改完 Makefile 后直接执行 make 编译即可,相关过程记录如下:
$ make
clang -O2 -target bpf -c bpf_program.c -I/home/longyu/linux-git/tools/testing/selftests/bpf -o bpf_program.o
clang -o monitor-exec -lelf -I/home/longyu/linux-git/samples/bpf -I/home/longyu/linux-git/tools/lib -I/home/longyu/linux-git/tools/perf -I/home/longyu/linux-git/tools/include -L/usr/local/lib64 -lbpf \
/home/longyu/linux-git/samples/bpf/bpf_load.c loader.c
编译完成后会生成一个 monitor-exec
程序,需要以 root
权限来运行。使用普 通用户执行将会报如下错误信息:
$ ./monitor-exec
bpf_load_program() err=1
The kernel didn't load the BPF program
使用 root 用户执行后过一会就会打印 Hello,BPF World!,示例信息如下;
$ sudo ./monitor-exec
sogou-qimpanel-31885 [004] .... 11022.245597: 0: Hello, BPF World!
sh-31886 [005] .... 11022.247254: 0: Hello, BPF World!
sogou-qimpanel-31887 [005] .... 11022.249711: 0: Hello, BPF World!
sh-31889 [004] .... 11022.251231: 0: Hello, BPF World!
sh-31891 [007] .... 11022.251429: 0: Hello, BPF World!
这个程序使用了内核的 tracepoint
来监控执行 execve
的事件,当此事件发生 后,它会打印出 Hello,xxx
的信息,这个 execve
事件代表了一个新进程的执 行,我们在上面的示例中看到的第一列就是程序名与其 pid
号。
这个 hello world 程序的编译过程分为两个步骤:
使用 clang
编译 loader.c
生成加载第一步生成的机器码的程序 loader.c
函数的源码如下所示:
#include "bpf_load.h"
#include <stdio.h>
int main(int argc, char **argv) {
if (load_bpf_file("bpf_program.o") != 0) {
printf("The kernel didn't load the BPF program\n");
return -1;
}
read_trace_pipe();
return 0;
}
上述代码其实只调用了 load_bpf_file
来加载第一步编译生成的 ebpf
程序, load_bpf_file
是 libbpf.so
中提供的接口。
使用 strace 跟踪 hello world ebpf 程序能够看到如下关键的系统调用:
bpf(BPF_PROG_LOAD, {prog_type=BPF_PROG_TYPE_TRACEPOINT, insn_cnt=14, insns=0xd04c80, license="GPL", log_level=0, log_size=0, log_buf=NULL, kern_version=KERNEL_VERSION(0, 0, 0), prog_flags=0, prog_name="", prog_ifindex=0, expected_attach_type=BPF_CGROUP_INET_INGRESS}, 112) = 4
其实 bpf
系统调用就是用户态程序与内核中的 ebpf
虚拟机交互的接口,libbpf.so
中提供的 api 实际上是对 bpf 系统调用的封装,可以想到 load_bpf_file
其实就是 指定 BPF_PROG_LOAD
等参数调用 bpf 系统调用来是实现的。
一开始我并没有下载该书的配套源码,直接按照书中的描述编译 hello world 程序,命令行信息如下:
$ clang -O2 -target bpf -c hello.c -o bpf_program.o
结果就报了 asm/types.h cannot find
的错误,整了一下发现它使用的是我系 统中 /usr/include/
目录中的内核头文件,看来应该就是个版本问题。
我想应该可以通过安装内核头文件来解决这个问题。
首先在内核源码树根目录中执行 make help
中找到如下内容:
headers_install - Install sanitised kernel headers to INSTALL_HDR_PATH
(default: ./usr)
可以看到它默认是使用 ./usr 目录,可以通过设定 INSTALL_HDR_PATH 来指定 其它安装目录。
我执行如下命令将这些头文件安装到指定目录中,示例过程如下:
$ make INSTALL_HDR_PATH="/home/longyu/ebpf/" headers_install
INSTALL include/asm-generic (36 files)
INSTALL include/drm (26 files)
......
安装后 ls
查看,确定 asm/types.h
存在,相关信息如下:
$ ls /home/longyu/ebpf/include/asm/types.h
/home/longyu/ebpf/include/asm/types.h
执行 clang -O2 -target bpf -I /home/longyu/ebpf/include -c bpf_program.c -o bpf_program.o
后成功编译。
我觉得这个问题不应该遇到,但是确实遇到了,书里面也没有相关的描述信息, 不得不吐槽这本书的内容,这些最为基本的东西为啥不能写的清楚一些?也不差 那几页么?
第二、三章内容看描述还行,但是一尝试编译就会遇到问题,还是有点垃圾欧。
内核源码树的 tools/bpf
这个目录中存放了了 ebpf
的汇 编,反汇编,调试程序源码。
在编译的过程中我遇到了如下几个问题:
报错信息如下:
/home/longyu/linux-git/tools/bpf/bpf_jit_disasm.c:23:10: fatal error: bfd.h: 没有那个文件或目录
#include <bfd.h>
^~~~~~~
解决方案如下:
$ apt-get install binutils-dev
报错信息如下:
/home/longyu/linux-git/tools/bpf/bpf_dbg.c:43:10: fatal error: readline/readline.h: 没有那个文件或目录
#include <readline/readline.h>
解决方案如下:
$ sudo apt-get install libreadline-dev
安装了这几个开发包后能够成功编译,编译生成的文件信息如下:
bpf_asm bpf_dbg bpf_jit_disasm bpftool/bpftool
这几个程序目前还没有用起来,后面用起来了在描述吧。
内核源码树中 tools/testing/selftests/bpf
目录中中放了 ebpf
功能的相关测试 用例程序,在编译时遇到了如下问题:
test_verifier.c:28:10: fatal error: sys/capability.h: 没有那个文件或目录
#include <sys/capability.h>
可以通过执行如下命令解决:
$ sudo apt-get install libcap-dev
这个目录中的测试用例程序可以作为编写 ebpf 程序的参考,这要比文档资料更 有价值。
samples/bpf
目录中也有一些 ebpf demo 程序,也是很好的参考资料。
内核源码树中,除了上面说过的源码资料外,还有几个目录中有一些文档资料。
tools/bpf/bpftool/Documentation
中有 bpftool
命令的资料 Documentation/bpf
中有 bpf
的一些描述资料
纸上得来终觉浅,绝知此事要躬行。书上的知识一定要经过实践的检验才能确定 它是否正确,学习从来都不只是阅读与记忆这么简单!
本文由哈喽比特于2年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/FCZkT6qaRFlzLkcFcS1hmA
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。