如何实现支持结构体数组的eBPF动态嵌套哈希映射?
eBPF HASH_OF_MAPS动态添加内层结构体映射的解决方案
问题背景
已实现基于HASH_OF_MAPS的嵌套映射方案:BPF侧定义外层哈希映射和内层数组映射模板,用户态通过bpf_map_create创建内层映射后,用bpf_map_update_elem将其添加到外层映射,该方案在存储整数数组时可正常运行。但当修改内层映射的value为自定义结构体时,加载程序出现错误:
libbpf: map 'outer_hash.inner': can't determine value size for type [37]: -22.
修改后的内层映射定义:
struct inner_array { __uint(type, BPF_MAP_TYPE_ARRAY); __type(key, __u32); __type(value, struct test); __uint(max_entries, 4); };
解决方法
问题根源是libbpf无法自动推导自定义结构体的字节大小,需在内层映射模板中显式指定value的大小,具体步骤如下:
- 确保结构体定义可见:在BPF程序中明确定义
struct test,且该定义需出现在内层映射模板之前,保证libbpf能获取到结构体的完整结构。 - 显式指定value_size:在内层映射模板中添加
__uint(value_size, sizeof(struct test))参数,直接告知libbpf结构体的字节长度。
修改后的完整BPF侧代码示例:
// 先定义自定义结构体 struct test { __u32 id; __u64 timestamp; char name[16]; }; struct inner_array { __uint(type, BPF_MAP_TYPE_ARRAY); __type(key, __u32); __type(value, struct test); __uint(value_size, sizeof(struct test)); // 显式指定value大小 __uint(max_entries, 4); }; struct { __uint(type, BPF_MAP_TYPE_HASH_OF_MAPS); __uint(max_entries, 10); __type(key, __u32); __array(values, struct inner_array); } outer_hash SEC(".maps");
- 用户态创建内层映射匹配参数:用户态调用
bpf_map_create时,需确保创建的内层映射参数与BPF侧模板完全一致:- 映射类型为
BPF_MAP_TYPE_ARRAY - key大小为
sizeof(__u32) - value大小为
sizeof(struct test) - max_entries设为4
- 映射类型为
这样创建的内层映射即可正常通过bpf_map_update_elem添加到外层HASH_OF_MAPS中,同时支持存储自定义结构体数据。
内容的提问来源于stack exchange,提问作者pedro_m
相关产品推荐
相关产品推荐

