加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

linux-kernel – 谁在BPF中创建地图

发布时间:2020-12-13 23:53:34 所属栏目:Linux 来源:网络整理
导读:在阅读了man bpf和其他一些文档来源之后,我的印象是地图只能由用户进程创建.但是下面的小程序似乎神奇地创建了bpf map: struct bpf_map_def SEC("maps") my_map = { .type = BPF_MAP_TYPE_ARRAY,.key_size = sizeof(u32),.value_size = sizeof(long),.max_e
在阅读了man bpf和其他一些文档来源之后,我的印象是地图只能由用户进程创建.但是下面的小程序似乎神奇地创建了bpf map:

struct bpf_map_def SEC("maps") my_map = {
        .type = BPF_MAP_TYPE_ARRAY,.key_size = sizeof(u32),.value_size = sizeof(long),.max_entries = 10,};

SEC("sockops")
int my_prog(struct bpf_sock_ops *skops)
{
   u32 key = 1;
   long *value;
   ...

   value = bpf_map_lookup_elem(&my_map,&key);
   ...
   return 1;
}

所以我用内核的工具/ bpf / bpftool加载程序,并验证程序是否已加载:

$bpftool prog show
1: sock_ops  name my_prog  tag f3a3583cdd82ae8d
        loaded_at Jan 02/18:46  uid 0
        xlated 728B  not jited  memlock 4096B

$bpftool map show
1: array  name my_map  flags 0x0
        key 4B  value 8B  max_entries 10  memlock 4096B

当然地图是空的.但是,从程序中删除bpf_map_lookup_elem会导致不创建映射.

UPDATE
我用strace调试它,发现在两种情况下,即使用bpf_map_lookup_elem而没有它,bpftool会调用bpf(BPF_MAP_CREATE,…),它显然成功了.然后,如果省略bpf_map_lookup_elem,我会在bpftool map show上进行操作,并且bpf(BPF_MAP_GET_NEXT_ID,..)会立即返回ENOENT,并且它永远不会转储地图.所以显然有些东西没有完成地图创建.

所以我想知道这是否是预期的行为?

谢谢.

解决方法

正如antiduh所解释的,并且通过你的strace检查确认,bpftool是在这种情况下创建地图的用户空间程序.它从libbpf(在tools / lib / bpf /下)调用函数bpf_prog_load(),最终执行系统调用.然后程序被固定在所需位置(在bpf虚拟文件系统安装点下),以便在bpftool返回时不会卸载它.地图未固定.

关于地图创建,魔术位也发生在libbpf中.当调用bpf_prog_load()时,libbpf将接收目标文件的名称作为参数. bpftool不会要求加载此特定程序或该特定地图;相反,它提供了目标文件,libbpf必须处理它.因此libbpf中的函数解析此ELF目标文件,并最终找到与地图和程序相对应的许多部分.然后它尝试加载第一个程序.

加载此程序包括以下步骤:

CHECK_ERR(bpf_object__create_maps(obj),err,out);
CHECK_ERR(bpf_object__relocate(obj),out);
CHECK_ERR(bpf_object__load_progs(obj),out);

换句话说:首先创建我们在目标文件中找到的所有地图.然后执行映射重定位(即将映射索引关联到eBPF指令),并最后加载程序指令.

所以关于你的问题:在两种情况下,无论有没有bpf_map_lookup_elem(),地图都是用bpf(BPF_MAP_CREATE,…)系统调用创建的.之后,重新定位发生,并且程序指令适于在需要时指向新创建的地图.然后,一旦完成所有步骤并加载程序,bpftool退出.应该固定eBPF程序,并且仍然在内核中加载.据我所知,如果它确实使用了map(如果使用了bpf_map_lookup_elem()),那么映射仍然被加载的程序引用,并保存在内核中.另一方面,如果程序不使用地图,那么没有什么可以阻止它们了,因此当bpftool返回时,当bpftool保存的文件描述符关闭时,地图会被销毁.

所以最后,当bpftool完成后,如果程序使用了地图,你就会在内核中加载一个地图,但如果程序没有依赖它就没有地图.在我看来,听起来像预期的行为;但如果你用bpftool遇到奇怪的事情,请以某种方式ping,我是那个从事该工具的人之一.最后一个通用观察:即使没有程序使用它们,地图也可以固定并保留在内核中,如果需要保留它们.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读