mirror of https://github.com/aya-rs/aya
aya/aya-bpf: implement btf tracepoint programs
parent
c4b6970774
commit
6539cbb555
@ -0,0 +1,103 @@
|
|||||||
|
//! BTF-enabled raw tracepoints.
|
||||||
|
use std::os::unix::io::RawFd;
|
||||||
|
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
generated::{bpf_attach_type::BPF_TRACE_RAW_TP, bpf_prog_type::BPF_PROG_TYPE_TRACING},
|
||||||
|
obj::btf::{Btf, BtfError, BtfKind},
|
||||||
|
programs::{load_program, FdLink, LinkRef, ProgramData, ProgramError},
|
||||||
|
sys::bpf_raw_tracepoint_open,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Marks a function as a [BTF-enabled raw tracepoint][1] eBPF program that can be attached at
|
||||||
|
/// a pre-defined kernel trace point.
|
||||||
|
///
|
||||||
|
/// The kernel provides a set of pre-defined trace points that eBPF programs can
|
||||||
|
/// be attached to. See `/sys/kernel/debug/tracing/events` for a list of which
|
||||||
|
/// events can be traced.
|
||||||
|
///
|
||||||
|
/// # Minimum kernel version
|
||||||
|
///
|
||||||
|
/// The minimum kernel version required to use this feature is 5.5.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// # #[derive(thiserror::Error, Debug)]
|
||||||
|
/// # enum Error {
|
||||||
|
/// # #[error(transparent)]
|
||||||
|
/// # BtfTracePointError(#[from] aya::programs::BtfTracePointError),
|
||||||
|
/// # #[error(transparent)]
|
||||||
|
/// # BtfError(#[from] aya::BtfError),
|
||||||
|
/// # #[error(transparent)]
|
||||||
|
/// # Program(#[from] aya::programs::ProgramError),
|
||||||
|
/// # #[error(transparent)]
|
||||||
|
/// # Bpf(#[from] aya::BpfError),
|
||||||
|
/// # }
|
||||||
|
/// # let mut bpf = Bpf::load_file("ebpf_programs.o")?;
|
||||||
|
/// use aya::{Bpf, programs::BtfTracePoint, BtfError, Btf};
|
||||||
|
/// use std::convert::TryInto;
|
||||||
|
///
|
||||||
|
/// let btf = Btf::from_sys_fs()?;
|
||||||
|
/// let program: &mut BtfTracePoint = bpf.program_mut("sched_process_fork")?.try_into()?;
|
||||||
|
/// program.load("sched_process_fork", &btf)?;
|
||||||
|
/// program.attach()?;
|
||||||
|
/// # Ok::<(), Error>(())
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// [1]: https://github.com/torvalds/linux/commit/9e15db66136a14cde3f35691f1d839d950118826
|
||||||
|
#[derive(Debug)]
|
||||||
|
#[doc(alias = "BPF_TRACE_RAW_TP")]
|
||||||
|
#[doc(alias = "BPF_PROG_TYPE_TRACING")]
|
||||||
|
pub struct BtfTracePoint {
|
||||||
|
pub(crate) data: ProgramData,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Error type returned when loading LSM programs.
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum BtfTracePointError {
|
||||||
|
/// An error occured while working with BTF.
|
||||||
|
#[error(transparent)]
|
||||||
|
Btf(#[from] BtfError),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BtfTracePoint {
|
||||||
|
/// Loads the program inside the kernel.
|
||||||
|
///
|
||||||
|
/// See also [`Program::load`](crate::programs::Program::load).
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `tracepoint` - full name of the tracepoint that we should attach to
|
||||||
|
/// * `btf` - btf information for the target system
|
||||||
|
pub fn load(&mut self, tracepoint: &str, btf: &Btf) -> Result<(), ProgramError> {
|
||||||
|
self.data.expected_attach_type = Some(BPF_TRACE_RAW_TP);
|
||||||
|
let type_name = format!("btf_trace_{}", tracepoint);
|
||||||
|
self.data.attach_btf_id = Some(
|
||||||
|
btf.id_by_type_name_kind(type_name.as_str(), BtfKind::Typedef)
|
||||||
|
.map_err(BtfTracePointError::from)?,
|
||||||
|
);
|
||||||
|
load_program(BPF_PROG_TYPE_TRACING, &mut self.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the name of the program.
|
||||||
|
pub fn name(&self) -> String {
|
||||||
|
self.data.name.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Attaches the program.
|
||||||
|
pub fn attach(&mut self) -> Result<LinkRef, ProgramError> {
|
||||||
|
let prog_fd = self.data.fd_or_err()?;
|
||||||
|
|
||||||
|
// BTF programs specify their attach name at program load time
|
||||||
|
let pfd = bpf_raw_tracepoint_open(None, prog_fd).map_err(|(_code, io_error)| {
|
||||||
|
ProgramError::SyscallError {
|
||||||
|
call: "bpf_raw_tracepoint_open".to_owned(),
|
||||||
|
io_error,
|
||||||
|
}
|
||||||
|
})? as RawFd;
|
||||||
|
|
||||||
|
Ok(self.data.link(FdLink { fd: Some(pfd) }))
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
use core::ffi::c_void;
|
||||||
|
|
||||||
|
use crate::BpfContext;
|
||||||
|
|
||||||
|
pub struct BtfTracePointContext {
|
||||||
|
ctx: *mut c_void,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BtfTracePointContext {
|
||||||
|
pub fn new(ctx: *mut c_void) -> BtfTracePointContext {
|
||||||
|
BtfTracePointContext { ctx }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BpfContext for BtfTracePointContext {
|
||||||
|
fn as_ptr(&self) -> *mut c_void {
|
||||||
|
self.ctx
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue