11个版本
0.2.7 | 2022年9月9日 |
---|---|
0.2.6 | 2022年9月8日 |
0.2.5 | 2022年8月3日 |
0.2.4 | 2022年5月2日 |
0.1.3 | 2022年1月20日 |
在 Unix APIs 中排名第 278
每月下载量 354
在 tbm 中使用
225KB
5K SLoC
oxidebpf
oxidebpf
是一个用于管理eBPF程序的宽松许可Rust库。
动机
oxidebpf
的动机是创建一个宽松许可的Rust库,用于管理尽可能多环境中运行的长运行eBPF程序。为此,需要打破一些预先设定的模式,即如何开发和部署eBPF应用程序。我们希望能够轻松部署一个在尽可能多的发行版上工作的eBPF解决方案;而不强迫用户必须具备工具链。用户通常只希望有一个产品来完成事情 - 而不需要大量额外的设置或维护。这个库帮助我们实现了这一目标 - 并且我们正在公开分享它。
最初这个库满足了我们的当前eBPF需求,所以它不是一个完整的eBPF实现。我们非常欢迎贡献,并且随着时间的推移,我们将逐渐增加功能列表。
目标
我们希望 oxidebpf
能够满足以下目标。
- 宽松许可,无GPL依赖。
- 支持自定义CO-RE eBPF
- 在Linux 4.4+上运行eBPF程序
- 纯Rust编写,或者尽可能接近纯Rust。
- 最小依赖,只引入实现所需功能的最小依赖集合。
要求
提供了一套Linux环境用于构建和测试,依赖项列在其 bootstrap.sh
脚本中。通常,你可能需要
$ sudo apt-get install build-essential clang llvm libclang-dev linux-tools-oem \
linux-tools-(kernel version)-generic
此外,您还需要安装货运软件。推荐使用cargo-with
软件包进行调试和测试。它允许您在测试期间通过运行以下命令来跟踪BPF调用:cargo with "strace -vfe bpf" -- test
。
入门指南
以下是一些快速入门步骤。
- 如果您想使用perfmaps,请在您的
Cargo.toml
中添加oxidebpf
,同时也要添加crossbeam-channel
。 - 使用
ProgramBlueprint
来加载您的编译后的eBPF对象文件,其中包含映射和程序。 - 为每个要加载的程序创建一个
Program
,并设置选项。 - 使用您的程序创建一个
ProgramVersion
。您可以创建多个ProgramVersion
,代表不同的程序集。例如,针对不同内核版本设计的程序。 - 创建一个
ProgramGroup
。 - 将您的
ProgramVersions
和ProgramBlueprint
提供给ProgramGroup
,并告诉它开始加载。它将按顺序尝试加载每个ProgramVersion
,直到在当前内核上成功加载。如果无法加载任何程序版本,它将返回一个错误,该错误由每个ProgramVersion
的底层错误组成。
let program = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("test")
.join(format!("test_program_{}", std::env::consts::ARCH));
let program_blueprint =
ProgramBlueprint::new(&std::fs::read(program).expect("Could not open file"), None)
.expect("Could not open test object file");
let mut program_group = ProgramGroup::new();
let (tx, rx) = crossbeam_channel::bounded(1024);
program_group.load(
program_blueprint,
vec![ProgramVersion::new(vec![
Program::new(
"test_program_map_update",
vec!["do_mount"],
)
.syscall(true),
Program::new("test_program", vec!["do_mount"]).syscall(true),
])],
|| (tx, PerfBufferSize::Total(4096))),
).expect("Could not load programs");
// read from rx any events from a perfmap in the loaded program version
注意:这期望在您的项目的test
子目录中存在一个test_program_[arch]
二进制文件,其中[arch]
是您的系统的架构。
构建
项目包含几个Vagrantfile,用于构建和测试库。
$ cd vagrant/ubuntu_20.04
$ vagrant up
$ vagrant ssh
$ cd oxidebpf
$ cargo build
如果您想本地构建,请检查bootstrap.sh
文件,以找到与您的系统最相似的Vagrantfile。此文件将包含用于分发版的构建和测试依赖项。
测试
- 从
test/
目录中运行docker-compose run -rm test-builder
以构建BPF测试应用程序。有关RHEL构建的附加选项,请参阅test/README.md
。 - 使用
cargo test
运行测试。要跟踪发生的BPF系统调用,请使用带有cargo with "strace -fe bpf" -- test
(取决于cargo-with
,默认由vagrant bootstrap包含)的测试运行测试。
注意:某些测试可能需要root权限才能通过。其他测试需要单线程上下文才能通过。为了测试一致性,请尝试运行:sudo -E /path/to/your/.cargo/bin/cargo test -- --test-threads=1
。为了方便,您可以将其别名为alias scargo="sudo -E $HOME/.cargo/bin/cargo"
,并使用scargo test --test-threads=1
运行测试。
功能
指标
oxidebpf
拥有一个(默认禁用)的功能,称为 metrics
。启用后,它将使用 metrics crate 来传播与 ebpf maps 相关的内部指标。以下是 metrics
,oxidebpf
目前报告的内容
-
perfmap.unread_size_pct
:表示 perfmap 缓冲区中有多少尚未读取的直方图。这将在轮询 perf map 文件描述符后立即发出,但在读取之前。这仅在 epoll 期间唤醒的 perfmap 中发出,如果一个 perfmap 永远得不到数据,则不会通过此指标报告。报告地图名称和 cpu 作为标签。还会为该指标发出一个describe_histogram!
,以告知报告者这是一个百分比单位。这可以用来设置直方图桶。 -
perfmap.buffer_size_kb
:表示为 perfmap 缓冲区的数据部分分配多少内存(以 KB 为单位)。请注意,始终为元数据分配一个额外的页面。这将在创建地图之前立即发出。地图名称作为标签报告。 -
perfmap.num_buffers
:表示为 perfmap 分配多少缓冲区。这也是 oxidebpf 检测到的在线 cpu 数量。这将在创建 perf map 之前立即发出。地图名称作为标签报告。 -
perfmap.channel.full
:表示尝试通过为 perfmap 提供的用户通道发送丢弃的消息,但失败次数(因为通道已满)。地图名称作为标签报告。
在此阶段,添加或删除指标不会被考虑为破坏性更改,但随着我们稳定最有用的指标,我们可能会重新考虑此决定。
依赖项
~6–16MB
~179K SLoC