【问题标题】:BPF: owner of a mapBPF:地图的所有者
【发布时间】:2018-06-15 18:17:34
【问题描述】:

这是who creates map in BPF 的后续,因为我的新问题与该线程没有直接关系。

所以,在我看来,必须有一个来创建 BPF 映射,要么是 bpf 程序,要么是加载 bpf 等的用户程序。

BPF 程序必须在编译时知道它要使用的映射类型,所以我们需要:

struct bpf_map_def SEC("maps") my_map = {
...
};

因此这意味着用户程序(例如 bpftool)将启动在 bpf ELF 部分中找到的映射的创建,如 who creates map in BPF 线程中所示。

另一方面,用户应用程序将需要在地图中添加/删除条目。为此,它必须知道 map 的 ID 才能从 libbpf 获取带有 bpf_map_get_fd_by_id() 的 map 的 fd。之后我们就可以享受bpf_map_update_elem()和类似的API了。

另一方面,如果我们在 BPF 程序中声明了一个 map 部分并且确实使用了 map API,则 map(s) 将保留在内核中并分配 ID。

因此,在这种情况下,我们将有两个具有两个不同 ID 的映射:一个作为来自 bpftoolbpf_prog_load() 创建的结果,另一个来自用户应用程序的 bpf_create_map()(假设应用程序继续正在运行,例如更新地图,并且不返回到 shell)。

一定有办法绕过这种歧义?

【问题讨论】:

    标签: linux-kernel bpf


    【解决方案1】:

    我不完全确定我理解你的问题,让我试着改写一下。

    • 您使用bpftool 加载一个eBPF 程序,它会创建程序所需的所有映射。 bpftool 用户空间应用程序,并最终使用 bpf(BPF_MAP_CREATE, …) 系统调用创建地图。
    • 您有另一个用户空间应用程序 foobar 与这些映射交互,可能通过使用 libbpf(最终执行 bpf(BPF_MAP_*, …) 系统调用)从映射中查找、更新或删除元素。
    • 据我了解,第二个应用程序foobar 尝试创建地图。因此,bpftool 创建的地图与foobar 创建的地图之间存在冲突。

    如果正确,解决方案很“简单”:不要创建两次地图。

    这意味着您应该从您的其他应用程序foobar 中删除对bpf_create_map() 的调用,或者使用bpftool 以外的其他内容加载您的程序。通常,工作流包括在 eBPF 对象文件中描述映射,并在加载之前由加载程序的同一应用程序创建——这就是 bpftool 所做的。然后应用程序拥有地图的文件描述符并可以对其进行处理。

    另外,可以将映射固定在 BPF 虚拟文件系统 (/sys/fs/bpf/) 下,以便另一个应用程序可以检索文件描述符,并访问此映射。这是通过系统调用 bpf(BPF_OBJ_GET, …) 完成的(目前还没有记录在手册页上,至少在我的系统上是这样)。

    如果我是正确的,使用固定地图还可以让人们在加载新的 eBPF 程序时重用已经存在的地图。我相信 iproute2 包中的tc 打算这样做,如果描述的地图存在并且已经固定(参见文件lib/bpf.c,但代码并不容易阅读)。这通常会在重定位时执行。

    最近添加了地图 ID,主要用于调试或自省,但它们可能会提供另一种方法来将文件描述符检索到地图中,正如您在 bpf_map_get_fd_by_id() 中描述的那样。尽管您必须首先找到一种方法来获取 ID。

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-12
      • 1970-01-01
      • 2018-11-29
      • 1970-01-01
      • 2015-04-11
      • 1970-01-01
      • 2018-10-31
      • 1970-01-01
      相关资源
      最近更新 更多