uprobe: bundle attach location+cookie via UProbeAttachPoint

This follows the #1417 review discussion: by bundling location
+ cookie into a UProbeAttachPoint we get a more idiomatic Into<_>
entry point, keep the one-to-one relationship enforced by the type
system, and make it easier to extend attach with multi-location
support without introducing parallel arrays or a brand new API.
pull/1421/head
swananan 3 days ago
parent 0780eef640
commit ee9d35a200

@ -1117,7 +1117,7 @@ impl Ebpf {
///
/// let program: &mut UProbe = bpf.program_mut("SSL_read").unwrap().try_into()?;
/// program.load()?;
/// program.attach("SSL_read", "libssl", None, None)?;
/// program.attach("SSL_read", "libssl", None)?;
/// # Ok::<(), aya::EbpfError>(())
/// ```
pub fn program_mut(&mut self, name: &str) -> Option<&mut Program> {

@ -50,6 +50,7 @@ pub struct UProbe {
/// The location in the target object file to which the uprobe is to be
/// attached.
#[derive(Debug, Clone)]
pub enum UProbeAttachLocation<'a> {
/// The location of the target function in the target object file.
Symbol(&'a str),
@ -72,6 +73,43 @@ impl From<u64> for UProbeAttachLocation<'static> {
}
}
/// Describes a single attachment point along with its optional cookie.
#[derive(Debug, Clone)]
pub struct UProbeAttachPoint<'a> {
/// The actual target location.
pub location: UProbeAttachLocation<'a>,
/// Optional cookie available via `bpf_get_attach_cookie()`.
pub cookie: Option<u64>,
}
impl<'a> UProbeAttachPoint<'a> {
/// Creates a new attach point from the given location.
pub fn new<L: Into<UProbeAttachLocation<'a>>>(location: L) -> Self {
Self {
location: location.into(),
cookie: None,
}
}
/// Sets the cookie for this attach point.
pub fn with_cookie(mut self, cookie: u64) -> Self {
self.cookie = Some(cookie);
self
}
}
impl<'a, L: Into<UProbeAttachLocation<'a>>> From<L> for UProbeAttachPoint<'a> {
fn from(location: L) -> Self {
Self::new(location)
}
}
impl<'a, L: Into<UProbeAttachLocation<'a>>> From<(L, u64)> for UProbeAttachPoint<'a> {
fn from((location, cookie): (L, u64)) -> Self {
Self::new(location).with_cookie(cookie)
}
}
impl UProbe {
/// The type of the program according to the kernel.
pub const PROGRAM_TYPE: ProgramType = ProgramType::KProbe;
@ -90,9 +128,9 @@ impl UProbe {
/// Attaches the program.
///
/// Attaches the uprobe to the function `fn_name` defined in the `target`.
/// If `offset` is non-zero, it is added to the address of the target
/// function. If `pid` is not `None`, the program executes only when the
/// target function is executed by the given `pid`.
/// If the attach point specifies an offset, it is added to the address of
/// the target function. If `pid` is not `None`, the program executes only
/// when the target function is executed by the given `pid`.
///
/// The `target` argument can be an absolute path to a binary or library, or
/// a library name (eg: `"libc"`).
@ -104,17 +142,19 @@ impl UProbe {
/// The returned value can be used to detach, see [UProbe::detach].
///
/// The cookie is supported since kernel 5.15, and it is made available to
/// the eBPF program via the `bpf_get_attach_cookie()` helper.
pub fn attach<'loc, T: AsRef<Path>, Loc: Into<UProbeAttachLocation<'loc>>>(
/// the eBPF program via the `bpf_get_attach_cookie()` helper. The `point`
/// argument may be just a location (no cookie), a [`UProbeAttachPoint`], or
/// a `(location, cookie)` tuple; the latter two set the cookie explicitly.
pub fn attach<'loc, T: AsRef<Path>, Point: Into<UProbeAttachPoint<'loc>>>(
&mut self,
location: Loc,
point: Point,
target: T,
pid: Option<u32>,
cookie: Option<u64>,
) -> Result<UProbeLinkId, ProgramError> {
let UProbeAttachPoint { location, cookie } = point.into();
let proc_map = pid.map(ProcMap::new).transpose()?;
let path = resolve_attach_path(target.as_ref(), proc_map.as_ref())?;
let (symbol, offset) = match location.into() {
let (symbol, offset) = match location {
UProbeAttachLocation::Symbol(s) => (Some(s), 0),
UProbeAttachLocation::SymbolOffset(s, offset) => (Some(s), offset),
UProbeAttachLocation::AbsoluteOffset(offset) => (None, offset),

@ -55,7 +55,7 @@ fn test_array() {
for (prog_name, symbol) in progs_and_symbols {
let prog: &mut UProbe = ebpf.program_mut(prog_name).unwrap().try_into().unwrap();
prog.load().unwrap();
prog.attach(symbol, "/proc/self/exe", None, None).unwrap();
prog.attach(symbol, "/proc/self/exe", None).unwrap();
}
let result_array = ebpf.map(result_map).unwrap();
let result_array = Array::<_, u32>::try_from(result_array).unwrap();

@ -99,8 +99,7 @@ fn load_and_attach_uprobe(prog_name: &str, func_name: &str, bytes: &[u8]) -> Ebp
let prog: &mut UProbe = bpf.program_mut(prog_name).unwrap().try_into().unwrap();
prog.load().unwrap();
prog.attach(func_name, "/proc/self/exe", None, None)
.unwrap();
prog.attach(func_name, "/proc/self/exe", None).unwrap();
bpf
}

@ -90,12 +90,7 @@ fn relocation_tests(
let program: &mut UProbe = bpf.program_mut("program").unwrap().try_into().unwrap();
program.load().unwrap();
program
.attach(
"trigger_btf_relocations_program",
"/proc/self/exe",
None,
None,
)
.attach("trigger_btf_relocations_program", "/proc/self/exe", None)
.unwrap();
trigger_btf_relocations_program();

@ -65,9 +65,7 @@ fn test_loaded_programs() {
};
// Ensure we can perform basic operations on the re-created program.
let res = p
.attach("uprobe_function", "/proc/self/exe", None, None)
.unwrap();
let res = p.attach("uprobe_function", "/proc/self/exe", None).unwrap();
// Ensure the program can be detached.
p.detach(res).unwrap();

@ -47,7 +47,7 @@ macro_rules! define_linear_ds_host_test {
] {
let prog: &mut UProbe = bpf.program_mut(prog_name).unwrap().try_into().unwrap();
prog.load().unwrap();
prog.attach(symbol, "/proc/self/exe", None, None).unwrap();
prog.attach(symbol, "/proc/self/exe", None).unwrap();
}
let array_map = bpf.map("RESULT").unwrap();
let array = Array::<_, u64>::try_from(array_map).unwrap();

@ -56,7 +56,7 @@ fn multiple_btf_maps() {
let prog: &mut UProbe = bpf.program_mut("bpf_prog").unwrap().try_into().unwrap();
prog.load().unwrap();
prog.attach("trigger_bpf_program", "/proc/self/exe", None, None)
prog.attach("trigger_bpf_program", "/proc/self/exe", None)
.unwrap();
trigger_bpf_program();
@ -106,7 +106,7 @@ fn pin_lifecycle_multiple_btf_maps() {
let prog: &mut UProbe = bpf.program_mut("bpf_prog").unwrap().try_into().unwrap();
prog.load().unwrap();
prog.attach("trigger_bpf_program", "/proc/self/exe", None, None)
prog.attach("trigger_bpf_program", "/proc/self/exe", None)
.unwrap();
trigger_bpf_program();
@ -336,7 +336,7 @@ fn basic_uprobe() {
let program_name = "test_uprobe";
let attach = |prog: &mut P| {
prog.attach("uprobe_function", "/proc/self/exe", None, None)
prog.attach("uprobe_function", "/proc/self/exe", None)
.unwrap()
};
run_unload_program_test(
@ -582,7 +582,7 @@ fn pin_lifecycle_uprobe() {
let program_name = "test_uprobe";
let attach = |prog: &mut P| {
prog.attach("uprobe_function", "/proc/self/exe", None, None)
prog.attach("uprobe_function", "/proc/self/exe", None)
.unwrap()
};
let program_pin = "/sys/fs/bpf/aya-uprobe-test-prog";

@ -69,7 +69,7 @@ fn log() {
let prog: &mut UProbe = bpf.program_mut("test_log").unwrap().try_into().unwrap();
prog.load().unwrap();
prog.attach("trigger_ebpf_program", "/proc/self/exe", None, None)
prog.attach("trigger_ebpf_program", "/proc/self/exe", None)
.unwrap();
// Call the function that the uprobe is attached to, so it starts logging.
@ -248,7 +248,7 @@ fn log_level_only_error_warn() {
let prog: &mut UProbe = bpf.program_mut("test_log").unwrap().try_into().unwrap();
prog.load().unwrap();
prog.attach("trigger_ebpf_program", "/proc/self/exe", None, None)
prog.attach("trigger_ebpf_program", "/proc/self/exe", None)
.unwrap();
trigger_ebpf_program();
@ -303,7 +303,7 @@ fn log_level_prevents_verif_fail() {
.try_into()
.unwrap();
prog.load().unwrap();
prog.attach("trigger_ebpf_program", "/proc/self/exe", None, None)
prog.attach("trigger_ebpf_program", "/proc/self/exe", None)
.unwrap();
trigger_ebpf_program();

@ -20,13 +20,8 @@ fn test_maps_disjoint() {
.unwrap();
prog.load().unwrap();
prog.attach(
"trigger_ebpf_program_maps_disjoint",
"/proc/self/exe",
None,
None,
)
.unwrap();
prog.attach("trigger_ebpf_program_maps_disjoint", "/proc/self/exe", None)
.unwrap();
let [foo, bar, baz] = bpf.maps_disjoint_mut(["FOO", "BAR", "BAZ"]);

@ -55,7 +55,7 @@ fn load_and_attach(name: &str, bytes: &[u8]) -> Ebpf {
let prog: &mut UProbe = bpf.program_mut(name).unwrap().try_into().unwrap();
prog.load().unwrap();
prog.attach("trigger_relocations_program", "/proc/self/exe", None, None)
prog.attach("trigger_relocations_program", "/proc/self/exe", None)
.unwrap();
bpf

@ -66,13 +66,8 @@ impl RingBufTest {
.try_into()
.unwrap();
prog.load().unwrap();
prog.attach(
"ring_buf_trigger_ebpf_program",
"/proc/self/exe",
None,
None,
)
.unwrap();
prog.attach("ring_buf_trigger_ebpf_program", "/proc/self/exe", None)
.unwrap();
Self {
_bpf: bpf,

@ -29,7 +29,7 @@ fn bpf_strncmp() {
.unwrap();
prog.load().unwrap();
prog.attach("trigger_bpf_strncmp", "/proc/self/exe", None, None)
prog.attach("trigger_bpf_strncmp", "/proc/self/exe", None)
.unwrap();
}

@ -26,7 +26,7 @@ fn test_uprobe_cookie() {
const PROG_A: &str = "uprobe_cookie_trigger_ebpf_program_a";
const PROG_B: &str = "uprobe_cookie_trigger_ebpf_program_b";
let attach = |prog: &mut UProbe, fn_name, cookie| {
prog.attach(fn_name, "/proc/self/exe", None, Some(cookie))
prog.attach((fn_name, cookie), "/proc/self/exe", None)
.unwrap()
};

@ -7341,8 +7341,12 @@ pub aya::programs::uprobe::UProbeAttachLocation::Symbol(&'a str)
pub aya::programs::uprobe::UProbeAttachLocation::SymbolOffset(&'a str, u64)
impl core::convert::From<u64> for aya::programs::uprobe::UProbeAttachLocation<'static>
pub fn aya::programs::uprobe::UProbeAttachLocation<'static>::from(offset: u64) -> Self
impl<'a> core::clone::Clone for aya::programs::uprobe::UProbeAttachLocation<'a>
pub fn aya::programs::uprobe::UProbeAttachLocation<'a>::clone(&self) -> aya::programs::uprobe::UProbeAttachLocation<'a>
impl<'a> core::convert::From<&'a str> for aya::programs::uprobe::UProbeAttachLocation<'a>
pub fn aya::programs::uprobe::UProbeAttachLocation<'a>::from(s: &'a str) -> Self
impl<'a> core::fmt::Debug for aya::programs::uprobe::UProbeAttachLocation<'a>
pub fn aya::programs::uprobe::UProbeAttachLocation<'a>::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
impl<'a> core::marker::Freeze for aya::programs::uprobe::UProbeAttachLocation<'a>
impl<'a> core::marker::Send for aya::programs::uprobe::UProbeAttachLocation<'a>
impl<'a> core::marker::Sync for aya::programs::uprobe::UProbeAttachLocation<'a>
@ -7357,12 +7361,18 @@ pub fn aya::programs::uprobe::UProbeAttachLocation<'a>::try_from(value: U) -> co
impl<T, U> core::convert::TryInto<U> for aya::programs::uprobe::UProbeAttachLocation<'a> where U: core::convert::TryFrom<T>
pub type aya::programs::uprobe::UProbeAttachLocation<'a>::Error = <U as core::convert::TryFrom<T>>::Error
pub fn aya::programs::uprobe::UProbeAttachLocation<'a>::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
impl<T> alloc::borrow::ToOwned for aya::programs::uprobe::UProbeAttachLocation<'a> where T: core::clone::Clone
pub type aya::programs::uprobe::UProbeAttachLocation<'a>::Owned = T
pub fn aya::programs::uprobe::UProbeAttachLocation<'a>::clone_into(&self, target: &mut T)
pub fn aya::programs::uprobe::UProbeAttachLocation<'a>::to_owned(&self) -> T
impl<T> core::any::Any for aya::programs::uprobe::UProbeAttachLocation<'a> where T: 'static + ?core::marker::Sized
pub fn aya::programs::uprobe::UProbeAttachLocation<'a>::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya::programs::uprobe::UProbeAttachLocation<'a> where T: ?core::marker::Sized
pub fn aya::programs::uprobe::UProbeAttachLocation<'a>::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya::programs::uprobe::UProbeAttachLocation<'a> where T: ?core::marker::Sized
pub fn aya::programs::uprobe::UProbeAttachLocation<'a>::borrow_mut(&mut self) -> &mut T
impl<T> core::clone::CloneToUninit for aya::programs::uprobe::UProbeAttachLocation<'a> where T: core::clone::Clone
pub unsafe fn aya::programs::uprobe::UProbeAttachLocation<'a>::clone_to_uninit(&self, dest: *mut u8)
impl<T> core::convert::From<T> for aya::programs::uprobe::UProbeAttachLocation<'a>
pub fn aya::programs::uprobe::UProbeAttachLocation<'a>::from(t: T) -> T
pub enum aya::programs::uprobe::UProbeError
@ -7414,7 +7424,7 @@ pub fn aya::programs::uprobe::UProbeError::from(t: T) -> T
pub struct aya::programs::uprobe::UProbe
impl aya::programs::uprobe::UProbe
pub const aya::programs::uprobe::UProbe::PROGRAM_TYPE: aya::programs::ProgramType
pub fn aya::programs::uprobe::UProbe::attach<'loc, T: core::convert::AsRef<std::path::Path>, Loc: core::convert::Into<aya::programs::uprobe::UProbeAttachLocation<'loc>>>(&mut self, location: Loc, target: T, pid: core::option::Option<u32>, cookie: core::option::Option<u64>) -> core::result::Result<aya::programs::uprobe::UProbeLinkId, aya::programs::ProgramError>
pub fn aya::programs::uprobe::UProbe::attach<'loc, T: core::convert::AsRef<std::path::Path>, Point: core::convert::Into<aya::programs::uprobe::UProbeAttachPoint<'loc>>>(&mut self, point: Point, target: T, pid: core::option::Option<u32>) -> core::result::Result<aya::programs::uprobe::UProbeLinkId, aya::programs::ProgramError>
pub fn aya::programs::uprobe::UProbe::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P, kind: aya::programs::ProbeKind) -> core::result::Result<Self, aya::programs::ProgramError>
pub fn aya::programs::uprobe::UProbe::kind(&self) -> aya::programs::ProbeKind
pub fn aya::programs::uprobe::UProbe::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
@ -7464,6 +7474,48 @@ impl<T> core::borrow::BorrowMut<T> for aya::programs::uprobe::UProbe where T: ?c
pub fn aya::programs::uprobe::UProbe::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya::programs::uprobe::UProbe
pub fn aya::programs::uprobe::UProbe::from(t: T) -> T
pub struct aya::programs::uprobe::UProbeAttachPoint<'a>
pub aya::programs::uprobe::UProbeAttachPoint::cookie: core::option::Option<u64>
pub aya::programs::uprobe::UProbeAttachPoint::location: aya::programs::uprobe::UProbeAttachLocation<'a>
impl<'a> aya::programs::uprobe::UProbeAttachPoint<'a>
pub fn aya::programs::uprobe::UProbeAttachPoint<'a>::new<L: core::convert::Into<aya::programs::uprobe::UProbeAttachLocation<'a>>>(location: L) -> Self
pub fn aya::programs::uprobe::UProbeAttachPoint<'a>::with_cookie(self, cookie: u64) -> Self
impl<'a, L: core::convert::Into<aya::programs::uprobe::UProbeAttachLocation<'a>>> core::convert::From<(L, u64)> for aya::programs::uprobe::UProbeAttachPoint<'a>
pub fn aya::programs::uprobe::UProbeAttachPoint<'a>::from((location, cookie): (L, u64)) -> Self
impl<'a, L: core::convert::Into<aya::programs::uprobe::UProbeAttachLocation<'a>>> core::convert::From<L> for aya::programs::uprobe::UProbeAttachPoint<'a>
pub fn aya::programs::uprobe::UProbeAttachPoint<'a>::from(location: L) -> Self
impl<'a> core::clone::Clone for aya::programs::uprobe::UProbeAttachPoint<'a>
pub fn aya::programs::uprobe::UProbeAttachPoint<'a>::clone(&self) -> aya::programs::uprobe::UProbeAttachPoint<'a>
impl<'a> core::fmt::Debug for aya::programs::uprobe::UProbeAttachPoint<'a>
pub fn aya::programs::uprobe::UProbeAttachPoint<'a>::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
impl<'a> core::marker::Freeze for aya::programs::uprobe::UProbeAttachPoint<'a>
impl<'a> core::marker::Send for aya::programs::uprobe::UProbeAttachPoint<'a>
impl<'a> core::marker::Sync for aya::programs::uprobe::UProbeAttachPoint<'a>
impl<'a> core::marker::Unpin for aya::programs::uprobe::UProbeAttachPoint<'a>
impl<'a> core::panic::unwind_safe::RefUnwindSafe for aya::programs::uprobe::UProbeAttachPoint<'a>
impl<'a> core::panic::unwind_safe::UnwindSafe for aya::programs::uprobe::UProbeAttachPoint<'a>
impl<T, U> core::convert::Into<U> for aya::programs::uprobe::UProbeAttachPoint<'a> where U: core::convert::From<T>
pub fn aya::programs::uprobe::UProbeAttachPoint<'a>::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya::programs::uprobe::UProbeAttachPoint<'a> where U: core::convert::Into<T>
pub type aya::programs::uprobe::UProbeAttachPoint<'a>::Error = core::convert::Infallible
pub fn aya::programs::uprobe::UProbeAttachPoint<'a>::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error>
impl<T, U> core::convert::TryInto<U> for aya::programs::uprobe::UProbeAttachPoint<'a> where U: core::convert::TryFrom<T>
pub type aya::programs::uprobe::UProbeAttachPoint<'a>::Error = <U as core::convert::TryFrom<T>>::Error
pub fn aya::programs::uprobe::UProbeAttachPoint<'a>::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
impl<T> alloc::borrow::ToOwned for aya::programs::uprobe::UProbeAttachPoint<'a> where T: core::clone::Clone
pub type aya::programs::uprobe::UProbeAttachPoint<'a>::Owned = T
pub fn aya::programs::uprobe::UProbeAttachPoint<'a>::clone_into(&self, target: &mut T)
pub fn aya::programs::uprobe::UProbeAttachPoint<'a>::to_owned(&self) -> T
impl<T> core::any::Any for aya::programs::uprobe::UProbeAttachPoint<'a> where T: 'static + ?core::marker::Sized
pub fn aya::programs::uprobe::UProbeAttachPoint<'a>::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya::programs::uprobe::UProbeAttachPoint<'a> where T: ?core::marker::Sized
pub fn aya::programs::uprobe::UProbeAttachPoint<'a>::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya::programs::uprobe::UProbeAttachPoint<'a> where T: ?core::marker::Sized
pub fn aya::programs::uprobe::UProbeAttachPoint<'a>::borrow_mut(&mut self) -> &mut T
impl<T> core::clone::CloneToUninit for aya::programs::uprobe::UProbeAttachPoint<'a> where T: core::clone::Clone
pub unsafe fn aya::programs::uprobe::UProbeAttachPoint<'a>::clone_to_uninit(&self, dest: *mut u8)
impl<T> core::convert::From<T> for aya::programs::uprobe::UProbeAttachPoint<'a>
pub fn aya::programs::uprobe::UProbeAttachPoint<'a>::from(t: T) -> T
pub struct aya::programs::uprobe::UProbeLink(_)
impl aya::programs::links::Link for aya::programs::uprobe::UProbeLink
pub type aya::programs::uprobe::UProbeLink::Id = aya::programs::uprobe::UProbeLinkId
@ -10147,7 +10199,7 @@ pub fn aya::programs::trace_point::TracePoint::from(t: T) -> T
pub struct aya::programs::UProbe
impl aya::programs::uprobe::UProbe
pub const aya::programs::uprobe::UProbe::PROGRAM_TYPE: aya::programs::ProgramType
pub fn aya::programs::uprobe::UProbe::attach<'loc, T: core::convert::AsRef<std::path::Path>, Loc: core::convert::Into<aya::programs::uprobe::UProbeAttachLocation<'loc>>>(&mut self, location: Loc, target: T, pid: core::option::Option<u32>, cookie: core::option::Option<u64>) -> core::result::Result<aya::programs::uprobe::UProbeLinkId, aya::programs::ProgramError>
pub fn aya::programs::uprobe::UProbe::attach<'loc, T: core::convert::AsRef<std::path::Path>, Point: core::convert::Into<aya::programs::uprobe::UProbeAttachPoint<'loc>>>(&mut self, point: Point, target: T, pid: core::option::Option<u32>) -> core::result::Result<aya::programs::uprobe::UProbeLinkId, aya::programs::ProgramError>
pub fn aya::programs::uprobe::UProbe::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P, kind: aya::programs::ProbeKind) -> core::result::Result<Self, aya::programs::ProgramError>
pub fn aya::programs::uprobe::UProbe::kind(&self) -> aya::programs::ProbeKind
pub fn aya::programs::uprobe::UProbe::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>

Loading…
Cancel
Save