与网络相关的 kprobes 在实践中有多不稳定?
How unstable are networking-related kprobes in practice?
我是 BPF 开发领域的新手,需要在我的 BPF 程序中使用 kprobes,以便我可以正确检测和收集试图通过网络发送数据包的进程的 PID。我想用我的用户空间应用程序部署这个 BPF 程序,我的用户空间应用程序运行在各种 linux 版本和发行版上——尽管都是相对较新的。
我知道 kprobe 机制并不稳定,但我的程序在实践中出错的可能性有多大?我挂钩 tcp_connect
和 ip4_datagram_connect
等函数。我原以为这些函数在内核版本之间不会有太大变化,所以或多或少地依赖它们应该是安全的?还是我有什么误解?
我可以发布依赖于这些特定 (tcp/udp) kprobe 的应用程序而不必过多担心兼容性或稳定性吗?
答案确实取决于您要跟踪的函数,无法确定。自 Linux 2.x 以来,该函数的原型可能根本没有改变,并在下一个版本中消失。
在实践中,我发现例如使用 kprobes 的函数 bcc trace 相当 stable。只有少数 bcc 工具需要更改才能处理自创建以来发布的新内核版本。这也是因为工具编写者小心使用了更多 "central" 不太可能更改的功能。
快速浏览一下,我认为您引用的两个函数 tcp_connect
和 ip4_datagram_connect
就是这样的 "central" 函数。一方面,它们都以符号 table.
导出
补充 pchaigno 的回答:bcc 也非常适合可移植性,因为 BPF 程序是在 bcc 的运行时编译的,就在加载到内核之前(所以你一定要使用当前 运行 的函数定义内核)。
要在没有 bcc 的情况下工作,但在跟踪程序的可移植性方面有相同类型的保证,我建议查看 CO-RE 机制(Compile-Once,运行-Everywhere) 在 this blog post 中有详细描述。 CO-RE 特别要求内核已使用 BTF 调试信息构建。加载程序时使用此信息以确保它与内核正确连接。
CO-RE 并未完全消除内核更改破坏 BPF kprobes 的风险,但会解决函数或结构定义中的一些更改。
我是 BPF 开发领域的新手,需要在我的 BPF 程序中使用 kprobes,以便我可以正确检测和收集试图通过网络发送数据包的进程的 PID。我想用我的用户空间应用程序部署这个 BPF 程序,我的用户空间应用程序运行在各种 linux 版本和发行版上——尽管都是相对较新的。
我知道 kprobe 机制并不稳定,但我的程序在实践中出错的可能性有多大?我挂钩 tcp_connect
和 ip4_datagram_connect
等函数。我原以为这些函数在内核版本之间不会有太大变化,所以或多或少地依赖它们应该是安全的?还是我有什么误解?
我可以发布依赖于这些特定 (tcp/udp) kprobe 的应用程序而不必过多担心兼容性或稳定性吗?
答案确实取决于您要跟踪的函数,无法确定。自 Linux 2.x 以来,该函数的原型可能根本没有改变,并在下一个版本中消失。
在实践中,我发现例如使用 kprobes 的函数 bcc trace 相当 stable。只有少数 bcc 工具需要更改才能处理自创建以来发布的新内核版本。这也是因为工具编写者小心使用了更多 "central" 不太可能更改的功能。
快速浏览一下,我认为您引用的两个函数 tcp_connect
和 ip4_datagram_connect
就是这样的 "central" 函数。一方面,它们都以符号 table.
补充 pchaigno 的回答:bcc 也非常适合可移植性,因为 BPF 程序是在 bcc 的运行时编译的,就在加载到内核之前(所以你一定要使用当前 运行 的函数定义内核)。
要在没有 bcc 的情况下工作,但在跟踪程序的可移植性方面有相同类型的保证,我建议查看 CO-RE 机制(Compile-Once,运行-Everywhere) 在 this blog post 中有详细描述。 CO-RE 特别要求内核已使用 BTF 调试信息构建。加载程序时使用此信息以确保它与内核正确连接。
CO-RE 并未完全消除内核更改破坏 BPF kprobes 的风险,但会解决函数或结构定义中的一些更改。