diff --git a/aya/src/programs/perf_attach.rs b/aya/src/programs/perf_attach.rs index f2c7e032..27db311c 100644 --- a/aya/src/programs/perf_attach.rs +++ b/aya/src/programs/perf_attach.rs @@ -3,7 +3,10 @@ use std::os::fd::{AsFd as _, AsRawFd as _, OwnedFd, RawFd}; use crate::{ generated::bpf_attach_type::BPF_PERF_EVENT, - programs::{probe::detach_debug_fs, FdLink, Link, ProbeKind, ProgramError}, + programs::{ + probe::{detach_debug_fs, ProbeEvent}, + FdLink, Link, ProgramError, + }, sys::{bpf_link_create, perf_event_ioctl, SysResult}, FEATURES, PERF_EVENT_IOC_DISABLE, PERF_EVENT_IOC_ENABLE, PERF_EVENT_IOC_SET_BPF, }; @@ -46,8 +49,7 @@ pub struct PerfLinkId(RawFd); #[derive(Debug)] pub struct PerfLink { perf_fd: OwnedFd, - probe_kind: Option, - event_alias: Option, + event: Option, } impl Link for PerfLink { @@ -57,13 +59,11 @@ impl Link for PerfLink { PerfLinkId(self.perf_fd.as_raw_fd()) } - fn detach(mut self) -> Result<(), ProgramError> { - let _: SysResult<_> = perf_event_ioctl(self.perf_fd.as_fd(), PERF_EVENT_IOC_DISABLE, 0); - - if let Some(probe_kind) = self.probe_kind.take() { - if let Some(event_alias) = self.event_alias.take() { - let _: Result<_, _> = detach_debug_fs(probe_kind, &event_alias); - } + fn detach(self) -> Result<(), ProgramError> { + let Self { perf_fd, event } = self; + let _: SysResult<_> = perf_event_ioctl(perf_fd.as_fd(), PERF_EVENT_IOC_DISABLE, 0); + if let Some(event) = event { + let _: Result<_, _> = detach_debug_fs(event); } Ok(()) @@ -80,24 +80,22 @@ pub(crate) fn perf_attach(prog_fd: RawFd, fd: OwnedFd) -> Result Result { - perf_attach_either(prog_fd, fd, Some(probe_kind), Some(event_alias)) + perf_attach_either(prog_fd, fd, Some(event)) } fn perf_attach_either( prog_fd: RawFd, fd: OwnedFd, - probe_kind: Option, - event_alias: Option, + event: Option, ) -> Result { perf_event_ioctl(fd.as_fd(), PERF_EVENT_IOC_SET_BPF, prog_fd).map_err(|(_, io_error)| { ProgramError::SyscallError { @@ -112,9 +110,5 @@ fn perf_attach_either( } })?; - Ok(PerfLinkInner::PerfLink(PerfLink { - perf_fd: fd, - probe_kind, - event_alias, - })) + Ok(PerfLinkInner::PerfLink(PerfLink { perf_fd: fd, event })) } diff --git a/aya/src/programs/probe.rs b/aya/src/programs/probe.rs index 38cd4d59..5b002e7e 100644 --- a/aya/src/programs/probe.rs +++ b/aya/src/programs/probe.rs @@ -42,6 +42,12 @@ impl ProbeKind { } } +#[derive(Debug)] +pub(crate) struct ProbeEvent { + kind: ProbeKind, + event_alias: String, +} + pub(crate) fn attach>( program_data: &mut ProgramData, kind: ProbeKind, @@ -56,8 +62,7 @@ pub(crate) fn attach>( let link = T::from(perf_attach_debugfs( program_data.fd_or_err()?, fd, - kind, - event_alias, + ProbeEvent { kind, event_alias }, )?); return program_data.links.insert(link); }; @@ -67,19 +72,22 @@ pub(crate) fn attach>( program_data.links.insert(link) } -pub(crate) fn detach_debug_fs(kind: ProbeKind, event_alias: &str) -> Result<(), ProgramError> { +pub(crate) fn detach_debug_fs(event: ProbeEvent) -> Result<(), ProgramError> { use ProbeKind::*; let tracefs = find_tracefs_path()?; - match kind { - KProbe | KRetProbe => delete_probe_event(tracefs, kind, event_alias) - .map_err(|(filename, io_error)| KProbeError::FileError { filename, io_error })?, - UProbe | URetProbe => delete_probe_event(tracefs, kind, event_alias) - .map_err(|(filename, io_error)| UProbeError::FileError { filename, io_error })?, - }; + let ProbeEvent { + kind, + event_alias: _, + } = &event; + let kind = *kind; + let result = delete_probe_event(tracefs, event); - Ok(()) + result.map_err(|(filename, io_error)| match kind { + KProbe | KRetProbe => KProbeError::FileError { filename, io_error }.into(), + UProbe | URetProbe => UProbeError::FileError { filename, io_error }.into(), + }) } fn create_as_probe( @@ -196,17 +204,14 @@ fn create_probe_event( Ok(event_alias) } -fn delete_probe_event( - tracefs: &Path, - kind: ProbeKind, - event_alias: &str, -) -> Result<(), (String, io::Error)> { +fn delete_probe_event(tracefs: &Path, event: ProbeEvent) -> Result<(), (String, io::Error)> { + let ProbeEvent { kind, event_alias } = event; let events_file_name = tracefs.join(format!("{}_events", kind.pmu())); let events = fs::read_to_string(&events_file_name) .map_err(|e| (events_file_name.display().to_string(), e))?; - let found = events.lines().any(|line| line.contains(event_alias)); + let found = events.lines().any(|line| line.contains(&event_alias)); if found { let mut events_file = OpenOptions::new()