我是BPF开发领域的新手,需要在我的BPF程序中使用kprobes,这样我就可以正确地检测和收集试图通过网络发送数据包的进程的PID。我想把这个BPF程序和我的用户空间程序一起部署,而我的用户空间程序运行在不同的linux版本和发行版上--虽然都是比较新的版本。
我知道kprobe机制不是官方稳定的,但我的程序在实践中出现故障的可能性有多大?我正在钩住一些功能,比如 tcp_connect
和 ip4_datagram_connect
. 我以为这些函数在不同的内核版本之间不会有太大的变化,所以应该可以安全地依赖它们?还是我理解错了什么?
我是否可以发布一个依赖这些特殊的(tcpudp)kprobes的应用程序,而不用太担心兼容性和稳定性?
答案真的是 取决于函数 你想追踪,但有 无从得知. 这个函数的原型可能从Linux 2.x开始就没有任何变化,在下一个版本中就消失了。
在实践中,我发现,例如,函数 bcc trace与kprobes都相当稳定。只有少数bcc的工具需要修改来处理自创建以来的新内核版本。这也是因为工具的编写者们小心翼翼地使用了更多的 "中心 "函数,这些函数不太可能发生变化。
从快速看,我认为你举的两个函数。tcp_connect
和 ip4_datagram_connect
,是这样的 "核心 "功能。首先,它们都是在符号表中导出的。
补充一下pchaigno的答案:bcc对于可移植性也很好,因为BPF程序是在bcc的运行时编译的,就在被加载到内核之前(所以你肯定会使用当前运行的内核的函数定义)。
要想在没有bcc的情况下工作,但又能保证跟踪程序的可移植性,我建议看看CO-RE机制(一次性编译,随时随地运行)中详细描述。本博文. CO-RE特别要求内核在构建时要有BTF调试信息。这些信息在加载程序时被用来确保程序与内核的正确接口。
CO-RE并不能完全消除内核变化破坏BPF kprobes的风险,但是可以解决一些函数或结构定义的变化。