BPF 库文档

BPF lib documentation

我用 BPF 库创建了一个应用程序(https://github.com/libbpf/libbpf). Unfortunately it does not have documentation or at least I have not found it yet. Only thing I have found is this https://libbpf.readthedocs.io/en/latest/api.html,但它没有我需要的一切。

我想知道,void *ctx 是做什么用的,这个函数中的ring_buffer_opts是什么

LIBBPF_API struct ring_buffer *
ring_buffer__new(int map_fd, ring_buffer_sample_fn sample_cb, void *ctx, const struct ring_buffer_opts *opts);

这里我想知道 void *ctx 的作用是什么。

typedef int (*ring_buffer_sample_fn)(void *ctx, void *data, size_t size);

比起文档,我更喜欢link,但我为一切感到高兴。

您已找到项目的 GitHub 镜像(“原始”源位于 Linux 内核存储库中)和 official API documentation。后者是从源代码生成的,特别是从 src/libbpf.h 中的注释生成的。可能是文档不完整 up-to-date,似乎 HTML-rendered 文档中目前缺少一些功能的描述。

然而,并不是所有的功能都被记录下来,环形缓冲区API在这方面没有太多帮助你。所以我能建议的最好的方法是查看代码和现有示例。内核存储库中至少有两个使用 ring_buffer__new() 的自测:ringbuf.c and ringbuf_multi.c.

第一个(ringbuf.c)这样称呼它:

    ringbuf = ring_buffer__new(skel->maps.ringbuf.map_fd,
                   process_sample, NULL, NULL);

它传递一个指向名为 process_sample 的函数的指针作为第二个参数,NULL 作为 ctx 作为第三个参数,NULL 以及选项.

回调函数process_samplering_buffer__poll()ring_buffer__consume()on each sample to “process” them根据用户需要调用。在此示例中,回调仅适用于样本中的 data,打印一行内容取决于这是检索到的第一个样本还是第二个样本。回调不需要“上下文”:这就是为什么 ctx 参数,它由 ring_buffer__new() 存储,然后在每次运行时作为第一个参数传递给回调函数,是 NULL在这种情况下。

对于第二个例子 (ringbuf_multi.c),我们得到 ctx:

    ringbuf = ring_buffer__new(bpf_map__fd(skel->maps.ringbuf1),
                   process_sample, (void *)(long)1, NULL);
    [...]
    
    err = ring_buffer__add(ringbuf, bpf_map__fd(skel->maps.ringbuf2),
                  process_sample, (void *)(long)2);

回调函数再次命名为 process_sample,但它是不同的(它与示例的其余部分在同一文件中定义)。我们还传递了一个上下文,1,然后我们添加了一个额外的环形缓冲区,具有不同的上下文,2.如果您查看在其下执行的检查以及 process_sample 的定义方式,它应该可以让您很好地了解 ctx 的工作原理:它是一些您可以传递给的通用上下文每个单独的环形缓冲区,以便您可以根据样本属于哪个环形缓冲区以不同的方式处理您的样本。

至于struct ring_buffer_opts *选项,在例子中总是在NULL,他们似乎是unused for now. The code in ring_buffer__new() does not use them