mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-24 00:43:24 +00:00
feat(ebpf):[WIP] add eBPF support (#948)
* feat(kprobe): Add basic kprobe support for x86_64 * feat: add ebpf support (#912) - 实现bpf()一部分命令,包括几种基本map,相关的helper函数 - 实现部分perf相关的数据结构 - 暂时为文件实现简单mmap - 实现一个使用kprobe统计syscall 调用次数的ebpf程序 对eBPF支持程度(基本): - 简单的eBPF程序(没有指定特殊的Map) - 使用内核已经实现的Map的eBPF程序 - 可以和kprobe配合使用 - 内核Map相关的接口定义已经实现,添加新的Map较为简单 不支持的功能: - 区分不同的eBPF程序类型(Network/Cgroup)并限定可调用的helper函数集 - 与内核其它跟踪机制配合(tracepoint) - 其它helper和Map todo - [ ] 修改mmap,需要讨论,因为这个和块缓存层相关 - [x] 添加文档 - [x] 修复可能的错误 - [x] 增加rbpf版本信息 * feat: add /sys/devices/system/cpu/possible file * feat: add /sys/devices/system/cpu/online
This commit is contained in:
60
user/apps/test_ebpf/src/main.rs
Normal file
60
user/apps/test_ebpf/src/main.rs
Normal file
@ -0,0 +1,60 @@
|
||||
use aya::maps::HashMap;
|
||||
use aya::programs::KProbe;
|
||||
use aya::{include_bytes_aligned, Ebpf};
|
||||
use aya_log::EbpfLogger;
|
||||
use log::{info, warn};
|
||||
use std::error::Error;
|
||||
use tokio::task::yield_now;
|
||||
use tokio::{signal, time};
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
async fn main() -> Result<(), Box<dyn Error>> {
|
||||
env_logger::builder()
|
||||
.filter_level(log::LevelFilter::Warn)
|
||||
.format_timestamp(None)
|
||||
.init();
|
||||
|
||||
let mut bpf = Ebpf::load(include_bytes_aligned!(
|
||||
"../syscall_ebpf/target/bpfel-unknown-none/release/syscall_ebpf"
|
||||
))?;
|
||||
|
||||
// create a async task to read the log
|
||||
if let Err(e) = EbpfLogger::init(&mut bpf) {
|
||||
// This can happen if you remove all log statements from your eBPF program.
|
||||
warn!("failed to initialize eBPF logger: {}", e);
|
||||
}
|
||||
|
||||
let program: &mut KProbe = bpf.program_mut("syscall_ebpf").unwrap().try_into()?;
|
||||
program.load()?;
|
||||
program.attach("dragonos_kernel::syscall::Syscall::handle", 0)?;
|
||||
|
||||
info!("attacch the kprobe to dragonos_kernel::syscall::Syscall::handle");
|
||||
|
||||
// print the value of the blocklist per 5 seconds
|
||||
tokio::spawn(async move {
|
||||
let blocklist: HashMap<_, u32, u32> =
|
||||
HashMap::try_from(bpf.map("SYSCALL_LIST").unwrap()).unwrap();
|
||||
let mut now = time::Instant::now();
|
||||
loop {
|
||||
let new_now = time::Instant::now();
|
||||
let duration = new_now.duration_since(now);
|
||||
if duration.as_secs() >= 5 {
|
||||
println!("------------SYSCALL_LIST----------------");
|
||||
let iter = blocklist.iter();
|
||||
for item in iter {
|
||||
if let Ok((key, value)) = item {
|
||||
println!("syscall: {:?}, count: {:?}", key, value);
|
||||
}
|
||||
}
|
||||
println!("----------------------------------------");
|
||||
now = new_now;
|
||||
}
|
||||
yield_now().await;
|
||||
}
|
||||
});
|
||||
|
||||
info!("Waiting for Ctrl-C...");
|
||||
signal::ctrl_c().await?;
|
||||
info!("Exiting...");
|
||||
Ok(())
|
||||
}
|
Reference in New Issue
Block a user