这是对who creates map in BPF的跟进,因为我的新问题与这个线程没有直接关系。
所以,在我看来,必须有一个点创建BPF映射,要么是bpf程序,要么是加载bpf等的用户程序。
BPF程序必须知道它将在编译时使用的映射类型,因此我们需要:
struct bpf_map_def SEC("maps") my_map = {
...
};因此,这意味着用户程序,例如bpftool,将开始创建在bpf部分中找到的映射,如who creates map in BPF线程中所示。
另一方面,用户应用程序需要在地图中添加/删除条目。要做到这一点,它必须知道映射的ID,以便从bpf_map_get_fd_by_id()从libbpf获得地图的fd。之后,我们可以享受bpf_map_update_elem()和类似的API。
另一方面,如果我们在BPF程序中声明了map部分,并且使用了map API,则映射将保留在内核中并分配ID。
因此,在本例中,我们将有两个具有两个不同in的映射:一个是bpf_prog_load()从bpftool创建的,另一个是用户应用程序的bpf_create_map()创建的(假设应用程序继续运行,例如更新映射,不返回shell)。
一定有办法避开这种模棱两可?
发布于 2018-01-05 23:12:08
我不能完全理解你的问题,让我试着换个说法。
bpftool加载一个bpftool程序,该程序创建程序所需的所有映射。bpftool是一个用户空间应用程序,最终使用bpf(BPF_MAP_CREATE, …) syscall创建映射。foobar,可能通过使用libbpf (最终执行bpf(BPF_MAP_*, …)系统)从映射中查找、更新或删除元素。foobar也试图创建映射。因此,bpftool创建的映射与foobar创建的映射之间存在冲突。如果这是正确的,解决方案是“简单”:不要创建两次地图。
这意味着您应该从其他应用程序的bpf_create_map()中删除对foobar的调用,或者用bpftool以外的东西加载程序。通常,工作流包括在eBPF对象文件中描述映射,并由加载程序的同一个应用程序创建,就在加载之前--这就是bpftool所做的。然后,应用程序拥有映射的文件描述符,并可以处理它。
或者,可以将映射固定在BPF虚拟文件系统(/sys/fs/bpf/)下,以便另一个应用程序可以检索文件描述符,并访问此映射。这是在syscall bpf(BPF_OBJ_GET, …)上完成的(至少在我的系统上)。
如果我是对的,使用固定映射也可以允许在加载新的eBPF程序时重用已经存在的映射。我相信来自package iproute2的iproute2打算这样做,如果所描述的映射已经存在并且已经被固定住了(请参阅文件lib/bpf.c,但是代码不太容易阅读)。这通常在重新部署时执行。
最近添加了映射in,主要用于调试或内省,但它们可能提供另一种方法来检索映射的文件描述符,就像您用bpf_map_get_fd_by_id()描述的那样。不过,首先您必须找到一种获取ID的方法。
希望这能有所帮助!
https://stackoverflow.com/questions/48122009
复制相似问题