mirror of
https://github.com/eunomia-bpf/bpf-developer-tutorial.git
synced 2026-02-04 02:34:16 +08:00
Deploying to gh-pages from @ eunomia-bpf/bpf-developer-tutorial@c120bb4912 🚀
This commit is contained in:
@@ -192,7 +192,7 @@
|
||||
</ul>
|
||||
<p>下面,我们将通过一段代码示例,详细展示如何利用 user ring buffer,实现从用户态向内核传送数据,并以 kernel ring buffer 相应地从内核态向用户态传送数据。</p>
|
||||
<h2 id="一实现在用户态和内核态间使用-ring-buffer-传送数据"><a class="header" href="#一实现在用户态和内核态间使用-ring-buffer-传送数据">一、实现:在用户态和内核态间使用 ring buffer 传送数据</a></h2>
|
||||
<p>借助新的 BPF MAP,我们可以实现在用户态和内核态间通过环形缓冲区传送数据。在这个示例中,我们将详细说明如何在用户空间创建一个 "用户环形缓冲区" (user ring buffer) 并向其写入数据,然后在内核空间中通过 <code>bpf_user_ringbuf_drain</code> 函数来消费这些数据。同时,我们也会使用 "内核环形缓冲区" (kernel ring buffer) 来从内核空间反馈数据到用户空间。为此,我们需要在用户空间和内核空间分别创建并操作这两个环形缓冲区。</p>
|
||||
<p>借助新的 BPF MAP,我们可以实现在用户态和内核态间通过环形缓冲区传送数据。在这个示例中,我们将详细说明如何在用户空间创建一个 "用户环形缓冲区" (user ring buffer) 并向其写入数据,然后在内核空间中通过 <code>bpf_user_ringbuf_drain</code> 函数来消费这些数据。同时,我们也会使用 "内核环形缓冲区" (kernel ring buffer) 来从内核空间反馈数据到用户空间。为此,我们需要在用户空间和内核空间分别创建并操作这两个环形缓冲区。</p>
|
||||
<p>完整的代码可以在 <a href="https://github.com/eunomia-bpf/bpf-developer-tutorial/tree/main/src/35-user-ringbuf">https://github.com/eunomia-bpf/bpf-developer-tutorial/tree/main/src/35-user-ringbuf</a> 中找到。</p>
|
||||
<h3 id="创建环形缓冲区"><a class="header" href="#创建环形缓冲区">创建环形缓冲区</a></h3>
|
||||
<p>在内核空间,我们创建了一个类型为 <code>BPF_MAP_TYPE_USER_RINGBUF</code> 的 <code>user_ringbuf</code>,以及一个类型为 <code>BPF_MAP_TYPE_RINGBUF</code> 的 <code>kernel_ringbuf</code>。在用户空间,我们创建了一个 <code>struct ring_buffer_user</code> 结构体的实例,并通过 <code>ring_buffer_user__new</code> 函数和对应的操作来管理这个用户环形缓冲区。</p>
|
||||
@@ -201,7 +201,7 @@
|
||||
if (!rb)
|
||||
{
|
||||
err = -1;
|
||||
fprintf(stderr, "Failed to create ring buffer\n");
|
||||
fprintf(stderr, "Failed to create ring buffer\n");
|
||||
goto cleanup;
|
||||
}
|
||||
user_ringbuf = user_ring_buffer__new(bpf_map__fd(skel->maps.user_ringbuf), NULL);
|
||||
@@ -211,25 +211,25 @@
|
||||
<pre><code class="language-c">// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */
|
||||
|
||||
#include "vmlinux.h"
|
||||
#include "vmlinux.h"
|
||||
#include <bpf/bpf_helpers.h>
|
||||
#include <bpf/bpf_tracing.h>
|
||||
#include <bpf/bpf_core_read.h>
|
||||
#include "user_ringbuf.h"
|
||||
#include "user_ringbuf.h"
|
||||
|
||||
char _license[] SEC("license") = "GPL";
|
||||
char _license[] SEC("license") = "GPL";
|
||||
|
||||
struct
|
||||
{
|
||||
__uint(type, BPF_MAP_TYPE_USER_RINGBUF);
|
||||
__uint(max_entries, 256 * 1024);
|
||||
} user_ringbuf SEC(".maps");
|
||||
} user_ringbuf SEC(".maps");
|
||||
|
||||
struct
|
||||
{
|
||||
__uint(type, BPF_MAP_TYPE_RINGBUF);
|
||||
__uint(max_entries, 256 * 1024);
|
||||
} kernel_ringbuf SEC(".maps");
|
||||
} kernel_ringbuf SEC(".maps");
|
||||
|
||||
int read = 0;
|
||||
|
||||
@@ -255,7 +255,7 @@ do_nothing_cb(struct bpf_dynptr *dynptr, void *context)
|
||||
return 0;
|
||||
}
|
||||
|
||||
SEC("tracepoint/syscalls/sys_exit_kill")
|
||||
SEC("tracepoint/syscalls/sys_exit_kill")
|
||||
int kill_exit(struct trace_event_raw_sys_exit *ctx)
|
||||
{
|
||||
long num_samples;
|
||||
@@ -282,9 +282,9 @@ int kill_exit(struct trace_event_raw_sys_exit *ctx)
|
||||
}
|
||||
|
||||
entry->i = getpid();
|
||||
strcpy(entry->comm, "hello");
|
||||
strcpy(entry->comm, "hello");
|
||||
|
||||
int read = snprintf(entry->comm, sizeof(entry->comm), "%u", i);
|
||||
int read = snprintf(entry->comm, sizeof(entry->comm), "%u", i);
|
||||
if (read <= 0)
|
||||
{
|
||||
/* Assert on the error path to avoid spamming logs with
|
||||
@@ -308,8 +308,8 @@ done:
|
||||
<pre><code class="language-c"> write_samples(user_ringbuf);
|
||||
|
||||
/* Process events */
|
||||
printf("%-8s %-5s %-16s %-7s %-7s %s\n",
|
||||
"TIME", "EVENT", "COMM", "PID", "PPID", "FILENAME/EXIT CODE");
|
||||
printf("%-8s %-5s %-16s %-7s %-7s %s\n",
|
||||
"TIME", "EVENT", "COMM", "PID", "PPID", "FILENAME/EXIT CODE");
|
||||
while (!exiting)
|
||||
{
|
||||
err = ring_buffer__poll(rb, 100 /* timeout, ms */);
|
||||
@@ -321,7 +321,7 @@ done:
|
||||
}
|
||||
if (err < 0)
|
||||
{
|
||||
printf("Error polling perf buffer: %d\n", err);
|
||||
printf("Error polling perf buffer: %d\n", err);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user