This commit is contained in:
yunwei37
2023-07-23 18:54:29 +00:00
parent 196da3bea8
commit 03732d2a1a
4 changed files with 38 additions and 38 deletions

View File

@@ -170,7 +170,7 @@
<p>eBPF (Extended Berkeley Packet Filter) 是 Linux 内核上的一个强大的网络和性能分析工具。它允许开发者在内核运行时动态加载、更新和运行用户定义的代码。</p>
<p>本文是 eBPF 入门开发实践教程的第三篇,在 eBPF 中使用 fentry 捕获 unlink 系统调用。</p>
<h2 id="fentry"><a class="header" href="#fentry">Fentry</a></h2>
<p>fentryfunction entry和fexitfunction exit是eBPF扩展的伯克利包过滤器中的两种探针类型用于在Linux内核函数的入口和退出处进行跟踪。它们允许开发者在内核函数执行的特定阶段收集信息、修改参数或观察返回值。这种跟踪和监控功能在性能分析、故障排查和安全分析等场景中非常有用。</p>
<p>fentryfunction entry fexitfunction exit eBPF扩展的伯克利包过滤器中的两种探针类型用于在 Linux 内核函数的入口和退出处进行跟踪。它们允许开发者在内核函数执行的特定阶段收集信息、修改参数或观察返回值。这种跟踪和监控功能在性能分析、故障排查和安全分析等场景中非常有用。</p>
<p>与 kprobes 相比fentry 和 fexit 程序有更高的性能和可用性。在这个例子中,我们可以直接访问函数的指针参数,就像在普通的 C 代码中一样而不需要使用各种读取帮助程序。fexit 和 kretprobe 程序最大的区别在于fexit 程序可以访问函数的输入参数和返回值,而 kretprobe 只能访问返回值。从 5.5 内核开始fentry 和 fexit 对 eBPF 程序可用。</p>
<pre><code class="language-c">#include &quot;vmlinux.h&quot;
#include &lt;bpf/bpf_helpers.h&gt;
@@ -181,32 +181,32 @@ char LICENSE[] SEC(&quot;license&quot;) = &quot;Dual BSD/GPL&quot;;
SEC(&quot;fentry/do_unlinkat&quot;)
int BPF_PROG(do_unlinkat, int dfd, struct filename *name)
{
pid_t pid;
pid_t pid;
pid = bpf_get_current_pid_tgid() &gt;&gt; 32;
bpf_printk(&quot;fentry: pid = %d, filename = %s\n&quot;, pid, name-&gt;name);
return 0;
pid = bpf_get_current_pid_tgid() &gt;&gt; 32;
bpf_printk(&quot;fentry: pid = %d, filename = %s\n&quot;, pid, name-&gt;name);
return 0;
}
SEC(&quot;fexit/do_unlinkat&quot;)
int BPF_PROG(do_unlinkat_exit, int dfd, struct filename *name, long ret)
{
pid_t pid;
pid_t pid;
pid = bpf_get_current_pid_tgid() &gt;&gt; 32;
bpf_printk(&quot;fexit: pid = %d, filename = %s, ret = %ld\n&quot;, pid, name-&gt;name, ret);
return 0;
pid = bpf_get_current_pid_tgid() &gt;&gt; 32;
bpf_printk(&quot;fexit: pid = %d, filename = %s, ret = %ld\n&quot;, pid, name-&gt;name, ret);
return 0;
}
</code></pre>
<p>这段程序是用C语言编写的eBPF扩展的伯克利包过滤器程序它使用BPFfentryfexit探针来跟踪Linux内核函数do_unlinkat。在这个教程中我们将以这段程序作为示例让您学会如何在eBPF中使用fentry监测捕获unlink系统调用。</p>
<p>这段程序是用 C 语言编写的 eBPF扩展的伯克利包过滤器程序它使用 BPFfentryfexit 探针来跟踪 Linux 内核函数 <code>do_unlinkat</code>。在这个教程中,我们将以这段程序作为示例,让您学会如何在 eBPF 中使用 fentry 监测捕获 unlink 系统调用。</p>
<p>程序包含以下部分:</p>
<ol>
<li>包含头文件包括vmlinux.h用于访问内核数据结构、bpf/bpf_helpers.h包含eBPF帮助函数、bpf/bpf_tracing.h用于eBPF跟踪相关功能</li>
<li>定义许可证:这里定义了一个名为LICENSE的字符数组,包含许可证信息&quot;Dual BSD/GPL&quot;</li>
<li>定义fentry探针我们定义了一个名为BPF_PROG(do_unlinkat)fentry探针该探针在do_unlinkat函数的入口处被触发。这个探针获取当前进程的PID进程ID并将其与文件名一起打印到内核日志。</li>
<li>定义fexit探针我们还定义了一个名为BPF_PROG(do_unlinkat_exit)fexit探针该探针在do_unlinkat函数的退出处被触发。与fentry探针类似这个探针也会获取当前进程的PID并将其与文件名和返回值一起打印到内核日志。</li>
<li>包含头文件:包括 vmlinux.h用于访问内核数据结构、bpf/bpf_helpers.h包含eBPF帮助函数、bpf/bpf_tracing.h用于eBPF跟踪相关功能</li>
<li>定义许可证:这里定义了一个名为 <code>LICENSE</code> 的字符数组,包含许可证信息Dual BSD/GPL</li>
<li>定义 fentry 探针:我们定义了一个名为 <code>BPF_PROG(do_unlinkat)</code>fentry 探针,该探针在 <code>do_unlinkat</code> 函数的入口处被触发。这个探针获取当前进程的 PID进程ID并将其与文件名一起打印到内核日志。</li>
<li>定义 fexit 探针:我们还定义了一个名为 <code>BPF_PROG(do_unlinkat_exit)</code>fexit 探针,该探针在 <code>do_unlinkat</code> 函数的退出处被触发。与 fentry 探针类似,这个探针也会获取当前进程的 PID 并将其与文件名和返回值一起打印到内核日志。</li>
</ol>
<p>通过这个示例您可以学习如何在eBPF中使用fentryfexit探针来监控和捕获内核函数调用例如在本教程中的unlink系统调用。</p>
<p>通过这个示例,您可以学习如何在 eBPF 中使用 fentryfexit 探针来监控和捕获内核函数调用,例如在本教程中的 unlink 系统调用。</p>
<p>eunomia-bpf 是一个结合 Wasm 的开源 eBPF 动态加载运行时和开发工具链,它的目的是简化 eBPF 程序的开发、构建、分发、运行。可以参考 <a href="https://github.com/eunomia-bpf/eunomia-bpf">https://github.com/eunomia-bpf/eunomia-bpf</a> 下载和安装 ecc 编译工具链和 ecli 运行时。我们使用 eunomia-bpf 编译运行这个例子。</p>
<p>编译运行上述代码:</p>
<pre><code class="language-console">$ ecc fentry-link.bpf.c
@@ -221,7 +221,7 @@ rm test_file
touch test_file2
rm test_file2
</code></pre>
<p>运行这段程序后,可以通过查看 /sys/kernel/debug/tracing/trace_pipe 文件来查看 eBPF 程序的输出:</p>
<p>运行这段程序后,可以通过查看 <code>/sys/kernel/debug/tracing/trace_pipe</code> 文件来查看 eBPF 程序的输出:</p>
<pre><code class="language-console">$ sudo cat /sys/kernel/debug/tracing/trace_pipe
rm-9290 [004] d..2 4637.798698: bpf_trace_printk: fentry: pid = 9290, filename = test_file
rm-9290 [004] d..2 4637.798843: bpf_trace_printk: fexit: pid = 9290, filename = test_file, ret = 0
@@ -229,8 +229,8 @@ rm test_file2
rm-9290 [004] d..2 4637.798843: bpf_trace_printk: fexit: pid = 9290, filename = test_file2, ret = 0
</code></pre>
<h2 id="总结"><a class="header" href="#总结">总结</a></h2>
<p>这段程序是一个 eBPF 程序,通过使用 fentry 和 fexit 捕获 do_unlinkat 和 do_unlinkat_exit 函数,并通过使用 bpf_get_current_pid_tgid 和 bpf_printk 函数获取调用 do_unlinkat 的进程 ID、文件名和返回值并在内核日志中打印出来。</p>
<p>编译这个程序可以使用 ecc 工具,运行时可以使用 ecli 命令,并通过查看 /sys/kernel/debug/tracing/trace_pipe 文件查看 eBPF 程序的输出。更多的例子和详细的开发指南,请参考 eunomia-bpf 的官方文档:<a href="https://github.com/eunomia-bpf/eunomia-bpf">https://github.com/eunomia-bpf/eunomia-bpf</a></p>
<p>这段程序是一个 eBPF 程序,通过使用 fentry 和 fexit 捕获 <code>do_unlinkat</code><code>do_unlinkat_exit</code> 函数,并通过使用 <code>bpf_get_current_pid_tgid</code><code>bpf_printk</code> 函数获取调用 do_unlinkat 的进程 ID、文件名和返回值并在内核日志中打印出来。</p>
<p>编译这个程序可以使用 ecc 工具,运行时可以使用 ecli 命令,并通过查看 <code>/sys/kernel/debug/tracing/trace_pipe</code> 文件查看 eBPF 程序的输出。更多的例子和详细的开发指南,请参考 eunomia-bpf 的官方文档:<a href="https://github.com/eunomia-bpf/eunomia-bpf">https://github.com/eunomia-bpf/eunomia-bpf</a></p>
<p>如果您希望学习更多关于 eBPF 的知识和实践,可以访问我们的教程代码仓库 <a href="https://github.com/eunomia-bpf/bpf-developer-tutorial">https://github.com/eunomia-bpf/bpf-developer-tutorial</a> 以获取更多示例和完整的教程。</p>
</main>

View File

@@ -555,7 +555,7 @@ rm test2
<p>eBPF (Extended Berkeley Packet Filter) 是 Linux 内核上的一个强大的网络和性能分析工具。它允许开发者在内核运行时动态加载、更新和运行用户定义的代码。</p>
<p>本文是 eBPF 入门开发实践教程的第三篇,在 eBPF 中使用 fentry 捕获 unlink 系统调用。</p>
<h2 id="fentry"><a class="header" href="#fentry">Fentry</a></h2>
<p>fentryfunction entry和fexitfunction exit是eBPF扩展的伯克利包过滤器中的两种探针类型用于在Linux内核函数的入口和退出处进行跟踪。它们允许开发者在内核函数执行的特定阶段收集信息、修改参数或观察返回值。这种跟踪和监控功能在性能分析、故障排查和安全分析等场景中非常有用。</p>
<p>fentryfunction entry fexitfunction exit eBPF扩展的伯克利包过滤器中的两种探针类型用于在 Linux 内核函数的入口和退出处进行跟踪。它们允许开发者在内核函数执行的特定阶段收集信息、修改参数或观察返回值。这种跟踪和监控功能在性能分析、故障排查和安全分析等场景中非常有用。</p>
<p>与 kprobes 相比fentry 和 fexit 程序有更高的性能和可用性。在这个例子中,我们可以直接访问函数的指针参数,就像在普通的 C 代码中一样而不需要使用各种读取帮助程序。fexit 和 kretprobe 程序最大的区别在于fexit 程序可以访问函数的输入参数和返回值,而 kretprobe 只能访问返回值。从 5.5 内核开始fentry 和 fexit 对 eBPF 程序可用。</p>
<pre><code class="language-c">#include &quot;vmlinux.h&quot;
#include &lt;bpf/bpf_helpers.h&gt;
@@ -566,32 +566,32 @@ char LICENSE[] SEC(&quot;license&quot;) = &quot;Dual BSD/GPL&quot;;
SEC(&quot;fentry/do_unlinkat&quot;)
int BPF_PROG(do_unlinkat, int dfd, struct filename *name)
{
pid_t pid;
pid_t pid;
pid = bpf_get_current_pid_tgid() &gt;&gt; 32;
bpf_printk(&quot;fentry: pid = %d, filename = %s\n&quot;, pid, name-&gt;name);
return 0;
pid = bpf_get_current_pid_tgid() &gt;&gt; 32;
bpf_printk(&quot;fentry: pid = %d, filename = %s\n&quot;, pid, name-&gt;name);
return 0;
}
SEC(&quot;fexit/do_unlinkat&quot;)
int BPF_PROG(do_unlinkat_exit, int dfd, struct filename *name, long ret)
{
pid_t pid;
pid_t pid;
pid = bpf_get_current_pid_tgid() &gt;&gt; 32;
bpf_printk(&quot;fexit: pid = %d, filename = %s, ret = %ld\n&quot;, pid, name-&gt;name, ret);
return 0;
pid = bpf_get_current_pid_tgid() &gt;&gt; 32;
bpf_printk(&quot;fexit: pid = %d, filename = %s, ret = %ld\n&quot;, pid, name-&gt;name, ret);
return 0;
}
</code></pre>
<p>这段程序是用C语言编写的eBPF扩展的伯克利包过滤器程序它使用BPFfentryfexit探针来跟踪Linux内核函数do_unlinkat。在这个教程中我们将以这段程序作为示例让您学会如何在eBPF中使用fentry监测捕获unlink系统调用。</p>
<p>这段程序是用 C 语言编写的 eBPF扩展的伯克利包过滤器程序它使用 BPFfentryfexit 探针来跟踪 Linux 内核函数 <code>do_unlinkat</code>。在这个教程中,我们将以这段程序作为示例,让您学会如何在 eBPF 中使用 fentry 监测捕获 unlink 系统调用。</p>
<p>程序包含以下部分:</p>
<ol>
<li>包含头文件包括vmlinux.h用于访问内核数据结构、bpf/bpf_helpers.h包含eBPF帮助函数、bpf/bpf_tracing.h用于eBPF跟踪相关功能</li>
<li>定义许可证:这里定义了一个名为LICENSE的字符数组,包含许可证信息&quot;Dual BSD/GPL&quot;</li>
<li>定义fentry探针我们定义了一个名为BPF_PROG(do_unlinkat)fentry探针该探针在do_unlinkat函数的入口处被触发。这个探针获取当前进程的PID进程ID并将其与文件名一起打印到内核日志。</li>
<li>定义fexit探针我们还定义了一个名为BPF_PROG(do_unlinkat_exit)fexit探针该探针在do_unlinkat函数的退出处被触发。与fentry探针类似这个探针也会获取当前进程的PID并将其与文件名和返回值一起打印到内核日志。</li>
<li>包含头文件:包括 vmlinux.h用于访问内核数据结构、bpf/bpf_helpers.h包含eBPF帮助函数、bpf/bpf_tracing.h用于eBPF跟踪相关功能</li>
<li>定义许可证:这里定义了一个名为 <code>LICENSE</code> 的字符数组,包含许可证信息Dual BSD/GPL</li>
<li>定义 fentry 探针:我们定义了一个名为 <code>BPF_PROG(do_unlinkat)</code>fentry 探针,该探针在 <code>do_unlinkat</code> 函数的入口处被触发。这个探针获取当前进程的 PID进程ID并将其与文件名一起打印到内核日志。</li>
<li>定义 fexit 探针:我们还定义了一个名为 <code>BPF_PROG(do_unlinkat_exit)</code>fexit 探针,该探针在 <code>do_unlinkat</code> 函数的退出处被触发。与 fentry 探针类似,这个探针也会获取当前进程的 PID 并将其与文件名和返回值一起打印到内核日志。</li>
</ol>
<p>通过这个示例您可以学习如何在eBPF中使用fentryfexit探针来监控和捕获内核函数调用例如在本教程中的unlink系统调用。</p>
<p>通过这个示例,您可以学习如何在 eBPF 中使用 fentryfexit 探针来监控和捕获内核函数调用,例如在本教程中的 unlink 系统调用。</p>
<p>eunomia-bpf 是一个结合 Wasm 的开源 eBPF 动态加载运行时和开发工具链,它的目的是简化 eBPF 程序的开发、构建、分发、运行。可以参考 <a href="https://github.com/eunomia-bpf/eunomia-bpf">https://github.com/eunomia-bpf/eunomia-bpf</a> 下载和安装 ecc 编译工具链和 ecli 运行时。我们使用 eunomia-bpf 编译运行这个例子。</p>
<p>编译运行上述代码:</p>
<pre><code class="language-console">$ ecc fentry-link.bpf.c
@@ -606,7 +606,7 @@ rm test_file
touch test_file2
rm test_file2
</code></pre>
<p>运行这段程序后,可以通过查看 /sys/kernel/debug/tracing/trace_pipe 文件来查看 eBPF 程序的输出:</p>
<p>运行这段程序后,可以通过查看 <code>/sys/kernel/debug/tracing/trace_pipe</code> 文件来查看 eBPF 程序的输出:</p>
<pre><code class="language-console">$ sudo cat /sys/kernel/debug/tracing/trace_pipe
rm-9290 [004] d..2 4637.798698: bpf_trace_printk: fentry: pid = 9290, filename = test_file
rm-9290 [004] d..2 4637.798843: bpf_trace_printk: fexit: pid = 9290, filename = test_file, ret = 0
@@ -614,8 +614,8 @@ rm test_file2
rm-9290 [004] d..2 4637.798843: bpf_trace_printk: fexit: pid = 9290, filename = test_file2, ret = 0
</code></pre>
<h2 id="总结-2"><a class="header" href="#总结-2">总结</a></h2>
<p>这段程序是一个 eBPF 程序,通过使用 fentry 和 fexit 捕获 do_unlinkat 和 do_unlinkat_exit 函数,并通过使用 bpf_get_current_pid_tgid 和 bpf_printk 函数获取调用 do_unlinkat 的进程 ID、文件名和返回值并在内核日志中打印出来。</p>
<p>编译这个程序可以使用 ecc 工具,运行时可以使用 ecli 命令,并通过查看 /sys/kernel/debug/tracing/trace_pipe 文件查看 eBPF 程序的输出。更多的例子和详细的开发指南,请参考 eunomia-bpf 的官方文档:<a href="https://github.com/eunomia-bpf/eunomia-bpf">https://github.com/eunomia-bpf/eunomia-bpf</a></p>
<p>这段程序是一个 eBPF 程序,通过使用 fentry 和 fexit 捕获 <code>do_unlinkat</code><code>do_unlinkat_exit</code> 函数,并通过使用 <code>bpf_get_current_pid_tgid</code><code>bpf_printk</code> 函数获取调用 do_unlinkat 的进程 ID、文件名和返回值并在内核日志中打印出来。</p>
<p>编译这个程序可以使用 ecc 工具,运行时可以使用 ecli 命令,并通过查看 <code>/sys/kernel/debug/tracing/trace_pipe</code> 文件查看 eBPF 程序的输出。更多的例子和详细的开发指南,请参考 eunomia-bpf 的官方文档:<a href="https://github.com/eunomia-bpf/eunomia-bpf">https://github.com/eunomia-bpf/eunomia-bpf</a></p>
<p>如果您希望学习更多关于 eBPF 的知识和实践,可以访问我们的教程代码仓库 <a href="https://github.com/eunomia-bpf/bpf-developer-tutorial">https://github.com/eunomia-bpf/bpf-developer-tutorial</a> 以获取更多示例和完整的教程。</p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="ebpf-入门开发实践教程四在-ebpf-中捕获进程打开文件的系统调用集合使用全局变量过滤进程-pid"><a class="header" href="#ebpf-入门开发实践教程四在-ebpf-中捕获进程打开文件的系统调用集合使用全局变量过滤进程-pid">eBPF 入门开发实践教程四:在 eBPF 中捕获进程打开文件的系统调用集合,使用全局变量过滤进程 pid</a></h1>
<p>eBPFExtended Berkeley Packet Filter是一种内核执行环境它可以让用户在内核中运行一些安全的、高效的程序。它通常用于网络过滤、性能分析、安全监控等场景。eBPF 之所以强大,是因为它能够在内核运行时捕获和修改数据包或者系统调用,从而实现对操作系统行为的监控和调整。</p>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long