Linux kernel BPF:地图的所有者
这是我的后续问题,因为我的新问题与该线程没有直接关系 所以,在我看来,创建BPF映射的地方必须只有一个点,要么是BPF程序,要么是加载BPF的用户程序,等等 BPF程序必须知道编译时要使用的映射类型,因此我们需要:Linux kernel BPF:地图的所有者,linux-kernel,bpf,Linux Kernel,Bpf,这是我的后续问题,因为我的新问题与该线程没有直接关系 所以,在我看来,创建BPF映射的地方必须只有一个点,要么是BPF程序,要么是加载BPF的用户程序,等等 BPF程序必须知道编译时要使用的映射类型,因此我们需要: struct bpf_map_def SEC("maps") my_map = { ... }; 因此,这意味着一个用户程序,例如bpftool,将启动在bpf ELF部分中找到的映射的创建,如线程中所示 另一方面,用户应用程序需要在地图中添加/删除条目。要实现这一点,它必须知道m
struct bpf_map_def SEC("maps") my_map = {
...
};
因此,这意味着一个用户程序,例如bpftool
,将启动在bpf ELF部分中找到的映射的创建,如线程中所示
另一方面,用户应用程序需要在地图中添加/删除条目。要实现这一点,它必须知道map的ID
,以便使用bpf\u map\u get\u fd\u by\u ID()
从libbpf
获取map的fd。之后,我们可以享受bpf\u map\u update\u elem()
和类似的API
另一方面,如果我们在BPF程序中声明了一个映射节,并且使用了映射API,那么映射将保留在内核中,并将被分配ID
因此,在本例中,我们将有两个具有两个不同ID的映射:一个是由bpftool
中的bpf\u prog\u load()
创建的,另一个是由用户应用程序的bpf\u create\u map()
创建的(假设应用程序继续运行,例如更新映射,并且不返回shell)
一定有办法绕过这个模棱两可的问题吗?我不能完全确定我是否理解你的问题,让我试着重新表述一下
- 使用
加载eBPF程序,该程序将创建程序所需的所有贴图bpftool
是一个用户空间应用程序,最终使用bpftool
syscall创建地图bpf(bpf\u MAP\u CREATE,…)
- 您还有另一个用户空间应用程序
,它可以与这些映射进行交互,可能是通过使用libbpf(最终执行foobar
syscalls)来查找、更新或删除映射中的元素bpf(bpf_-MAP_*,…)
- 据我所知,第二个应用程序
也尝试创建地图。因此,由foobar
创建的映射与由bpftool
创建的映射之间存在冲突foobar
foobar
中删除对bpf\u create\u map()
的调用,或者用bpftool
以外的东西加载程序。通常,工作流包含eBPF对象文件中描述的映射,并由加载程序的同一应用程序创建,加载前这就是bpftool
所做的。然后,应用程序拥有映射的文件描述符并可以处理它
或者,可以将映射固定在BPF虚拟文件系统(/sys/fs/BPF/
)下,以便其他应用程序可以检索文件描述符,也可以访问此映射。这是通过系统调用bpf(bpf_OBJ_GET,…)完成的(至少在我的系统上,目前还没有在手册页上记录)
如果我是正确的,那么在加载新的eBPF程序时,使用固定贴图也可以允许重用已经存在的贴图。我相信,如果所描述的映射存在并且已经被钉住(请参见文件lib/bpf.c
,但代码并不容易阅读),那么来自包iproute2的tc
打算这样做。这通常在重新定位时执行
最近添加了映射id,主要用于调试或内省,但在您的情况下,它们可能会提供另一种将文件描述符检索到映射的方法,如您在bpf\u map\u get\u fd\u by\u id()中所述。虽然你必须首先找到一种方法来获取ID
希望这有帮助