当前位置: 首页 > news >正文

eBPF 动态 Map

BPF 动态 Map是 eBPF 中支持运行时动态创建、销毁、调整大小的 Map 类型,区别于传统静态 Map(编译时固定大小、固定键值类型)。

它是 Linux 5.10+ 内核引入的核心能力,彻底解决了传统 eBPF Map 「静态不灵活、资源浪费、无法动态扩容」的痛点,广泛用于云原生、网络观测、安全监控等场景。

  • 动态创建 / 销毁:无需在 BPF 程序编译时定义,可在用户态用bpf_map_create()随时创建、关闭销毁
  • 动态调整大小:支持运行时扩容 / 缩容(部分类型)
  • 动态类型:键值大小、Map 最大元素数都可在运行时指定
  • 内核版本要求Linux 5.10+,主流发行版(CentOS 8+/Ubuntu 20.04+)已支持

动态 Map vs 传统静态 Map

特性传统静态 MapBPF 动态 Map
创建时机编译时固定定义运行时动态创建
大小 / 键值类型编译时写死运行时自由指定
生命周期随 BPF 程序 / 挂载点独立生命周期,手动管理
内核依赖全版本支持Linux 5.10+
共享能力可共享但不灵活天然支持多程序 / 进程共享

支持的动态 Map 类型

所有标准 BPF Map 都支持动态创建,最常用:

  1. BPF_MAP_TYPE_HASH:哈希表(最常用)
  2. BPF_MAP_TYPE_ARRAY:数组 Map
  3. BPF_MAP_TYPE_PERCPU_HASH / PERCPU_ARRAY:Per-CPU 高性能 Map
  4. BPF_MAP_TYPE_RINGBUF:高性能环形缓冲区(观测数据上报)

动态 Map 核心 API(用户态 C 语言)

动态 Map 完全通过用户态系统调用创建 / 操作,BPF 程序通过文件描述符 (fd)访问。

1. 创建动态 Map

#include <bpf/bpf.h> #include <bpf/libbpf.h> // 核心函数:动态创建 Map int bpf_map_create(enum bpf_map_type map_type, const char *map_name, // Map 名称(调试用) __u32 key_size, // 键大小(字节) __u32 value_size, // 值大小(字节) __u32 max_entries, // 最大元素数 const struct bpf_map_create_attr *attr);
  • 返回值:Map 文件描述符(fd),后续所有操作都用这个 fd
  • 关闭:close(fd)会自动销毁 Map(无引用时)

2. 操作动态 Map

// 增/改 int bpf_map_update_elem(int fd, const void *key, const void *value, __u64 flags); // 查 int bpf_map_lookup_elem(int fd, const void *key, void *value); // 删 int bpf_map_delete_elem(int fd, const void *key);

完整可运行示例

场景:用户态动态创建 HASH Map,BPF 程序读取 Map 数据

1. BPF 程序(内核态,dyn_map.bpf.c)

BPF 程序不定义 Map,只通过外部 fd引用动态 Map:

// 用 extern 声明外部动态 Map(核心!) struct { __uint(type, BPF_MAP_TYPE_HASH); __type(key, __u32); __type(value, __u64); } dyn_map SEC(".maps"); // 跟踪点:读取动态 Map 数据 SEC("tracepoint/syscalls/sys_enter_open") int trace_enter_open(struct trace_event_raw_sys_enter* ctx) { __u32 key = 100; __u64 *val; // 从动态 Map 中查找值 val = bpf_map_lookup_elem(&dyn_map, &key); if (val) { bpf_printk("dyn map value: %llu\n", *val); } return 0; } char LICENSE[] SEC("license") = "GPL";

2. 用户态程序(加载 BPF + 创建动态 Map,dyn_map.c)

#include <stdio.h> #include <stdlib.h> #include <libbpf/libbpf.h> #include "dyn_map.skel.h" int main() { struct dyn_map_bpf *skel; int map_fd, err; __u32 key = 100; __u64 value = 9988; // 1. 加载 BPF 骨架程序 skel = dyn_map_bpf__open_and_load(); if (!skel) { fprintf(stderr, "加载 BPF 失败\n"); return 1; } // 2. 动态创建 HASH Map(运行时指定参数!) map_fd = bpf_map_create( BPF_MAP_TYPE_HASH, // Map 类型 "my_dynamic_map", // 名称 sizeof(__u32), // 键大小 sizeof(__u64), // 值大小 1024, // 最大元素数 NULL // 扩展属性 ); if (map_fd < 0) { perror("创建动态 Map 失败"); return 1; } printf("动态 Map 创建成功,fd=%d\n", map_fd); // 3. 向动态 Map 写入数据 bpf_map_update_elem(map_fd, &key, &value, BPF_ANY); // 4. 将动态 Map 绑定到 BPF 程序(替换 extern Map) skel->maps.dyn_map = bpf_map__from_fd(map_fd); // 5. 附加跟踪点 err = dyn_map_bpf__attach(skel); if (err) { fprintf(stderr, "附加失败\n"); return 1; } printf("运行中... 按 Ctrl+C 退出\n"); pause(); // 清理 dyn_map_bpf__destroy(skel); close(map_fd); return 0; }

BPF 程序中动态创建 Map(进阶)

内核 5.18+ 支持:BPF 程序内部动态创建 Map

使用bpf_map_new()/bpf_map_put()实现内核态动态 Map:

// 内核态动态创建 Map struct bpf_map *map = bpf_map_new( BPF_MAP_TYPE_HASH, sizeof(__u32), sizeof(__u64), 128, 0 ); // 使用完释放 bpf_map_put(map);

适用场景:BPF 程序按需创建临时 Map,用完即销毁。

动态 Map 高级特性

1. Map 共享

动态 Map 天生支持共享:

  • 多个 BPF 程序可绑定同一个 Map fd
  • 多进程可通过bpf_map_get_fd_by_id()根据 Map ID 共享

2. 内核态 / 用户态双向操作

  • 用户态:创建、增删改查
  • 内核态:查找、更新、删除
  • 完美解耦「资源管理」和「数据处理」

3. 持久化与命名

  • 支持BPF FS 命名/sys/fs/bpf/my_map,重启前持久化
  • 支持bpf_map_get_fd_by_name()按名获取

使用限制与注意事项

  1. 内核版本:最低Linux 5.10,动态创建全类型;5.18+ 支持内核态创建
  2. 权限:需要CAP_BPFCAP_PERFMON权限(root 运行)
  3. 资源限制:受/proc/sys/kernel/bpf_*系统参数限制
  4. 生命周期:最后一个 fd 关闭后,Map 自动销毁

总结

  1. 动态 Map = 运行时创建 + 灵活配置 + 独立生命周期,彻底替代静态 Map
  2. 核心用法:用户态用bpf_map_create()创建 → 绑定到 BPF 程序 → 双向操作
  3. 适用场景:动态观测、多程序共享数据、按需分配内存、云原生可观测性
  4. 依赖:Linux 5.10+、libbpf 1.0+
http://www.jsqmd.com/news/490126/

相关文章:

  • “龙虾“创始人怒斥抄袭?腾讯回怼~
  • FFXIV动画智能跳过插件:技术原理与环境适配指南
  • Arduino 入门手册:基于ESP32-S3R8N8的智能硬件开发实战指南
  • 2026年活动房生产商选购指南,活动房生产商哪个口碑好,如何选择 - 工业品牌热点
  • Phi-3-mini-128k-instruct企业落地:低成本构建内部AI赋能平台
  • DataX限速配置实战:如何正确设置channel的bps值避免报错
  • 2026年固生堂能用医保吗?医保使用要点详解 - 品牌排行榜
  • Phi-3-vision-128k-instruct保姆级教程:多模态模型Web端调用全流程
  • 4. MSPM0 SysTick滴答定时器实现毫秒级精确延时与LED闪烁实战
  • 从示波器波形看懂BJT放大电路:实测共射/共集/共基电路差异
  • OpenCore Legacy Patcher实战指南:让老款Mac焕新 macOS 体验
  • 从零开始:MT7620 OpenWrt固件全机型编译指南
  • 大型组合滑梯厂家怎么选?2026年实用指南来了,滑梯源头厂家分析分析赋能企业生产效率提升与成本优化 - 品牌推荐师
  • 【节点】[SampleReflectedCubemap节点]原理解析与实际应用
  • 2026年泉州AI搜索营销公司推荐:4家主流服务商深度测评与选型指南 - 小白条111
  • 第9、10课时_预习
  • 如何使用无障碍技术实现自动化脚本?
  • Phi-3-vision-128k-instruct效果实测:手写公式识别+数学题分步解答演示
  • ArcGIS实战:二维点线数据的三维可视化转换技巧
  • 本地商家小红书:搜索流量 vs 推荐流量,打法完全不同 - Redbook_CD
  • 从编译到封装:基于GmSSL 3.x的SM2 C++实战指南
  • Z-Image Atelier 与物联网结合:为STM32项目生成产品外观与UI界面概念图
  • 看2026上海靠谱宠物牙科医院分析,选对不踩坑,宠物骨科专家/腹腔镜绝育/宠物皮肤科/狗狗体检,宠物牙科医院哪家最好 - 品牌推荐师
  • Notepad++函数列表快捷键F8设置全攻略(附冲突解决技巧)
  • 2026看中医去哪里?这份就医指南请收好 - 品牌排行榜
  • Qwen3-14b_int4_awq从零开始:Linux环境部署vLLM+Chainlit全流程图文详解
  • 从入门到实战:TypeScript 全栈开发核心指南
  • 2026四川资质代办优质机构推荐榜 高通过率优先 - 优质品牌商家
  • Gemma-3 Pixel Studio快速部署:无需conda环境,纯pip+Streamlit启动方案
  • 利用天地图底图快速构建专业研究区位图(附实战技巧与数据)