BPF:地图的所有者

时间:2018-01-05 22:12:20

标签: linux-kernel bpf

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

所以,在我看来,必须有一个 point ,其中创建了BPF地图,无论是bpf程序还是加载bpf等的用户程序。

BPF程序必须知道它将在编译时使用的地图类型,因此我们需要:

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

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

另一方面,用户应用程序需要在地图中添加/删除条目。要做到这一点,必须知道地图的ID,以便从bpf_map_get_fd_by_id()获取libbpf获取地图的fd。之后,我们可以享受bpf_map_update_elem()和类似的API。

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

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

必须有办法绕过这种歧义吗?

1 个答案:

答案 0 :(得分:3)

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

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

如果这是正确的,解决方案是“简单的”:创建地图两次。

这意味着您应该从其他应用bpf_create_map()中删除对foobar的来电,或者使用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的方法。

希望这有帮助!