正如 antiduh 所解释的,并与您确认strace
检查,bpftool
在本例中是创建映射的用户空间程序。它调用函数bpf_prog_load()
来自 libbpf(在tools/lib/bpf/
),最终执行系统调用。然后将程序固定在所需位置(在bpf
虚拟文件系统挂载点),以便 bpftool 返回时不会卸载它。地图未固定。
关于地图创建,神奇的部分也发生在 libbpf 中。什么时候bpf_prog_load()
被调用时,libbpf 接收目标文件的名称作为参数。bpftool
不要求加载this具体计划或that具体地图;相反,它提供目标文件,而 libbpf 必须处理它。于是libbpf中的函数解析这个ELF目标文件,最终找到一些对应于地图和程序的节。然后它尝试加载第一个程序。
加载该程序包括以下步骤:
CHECK_ERR(bpf_object__create_maps(obj), err, out);
CHECK_ERR(bpf_object__relocate(obj), err, out);
CHECK_ERR(bpf_object__load_progs(obj), err, out);
换句话说:首先创建我们在目标文件中找到的所有映射。然后执行映射重定位(即将映射索引与eBPF指令相关联),最后加载程序指令。
所以关于你的问题:在这两种情况下,有和没有bpf_map_lookup_elem()
,地图是用bpf(BPF_MAP_CREATE, ...)
系统调用。之后,会发生重定位,并且程序指令会根据需要进行调整以指向新创建的地图。然后,一旦完成所有步骤并加载程序,bpftool
退出。 eBPF 程序应该被固定,并且仍然加载到内核中。据我了解,如果does使用地图(如果bpf_map_lookup_elem()
被使用),那么映射仍然被加载的程序引用,并保存在内核中。另一方面,如果程序not使用映射,那么就没有什么可以阻止它们,因此当文件描述符持有时映射会被销毁bpftool
都关闭,当bpftool
返回。
所以最后,当bpftool
完成后,如果程序使用它,则在内核中加载了一个映射,但如果没有程序依赖它,则没有映射。在我看来,这听起来像是预期的行为;但如果您遇到奇怪的事情,请以某种方式进行 pingbpftool
,我是从事该实用程序工作的人员之一。最后一项一般观察:如果需要保留映射,即使没有程序使用它们,映射也可以固定并保留在内核中。