Reduce state cardinality from 4 to 2

Encode into the type system the fact that PerfLink::probe_kind and
PerfLink::event_alias are present or absent together.
reviewable/pr707/r1
Tamir Duberstein 1 year ago
parent 445cb8b463
commit 0ec9afdb07
No known key found for this signature in database

@ -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<ProbeKind>,
event_alias: Option<String>,
event: Option<ProbeEvent>,
}
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<PerfLinkInner,
)? as RawFd;
Ok(PerfLinkInner::FdLink(FdLink::new(link_fd)))
} else {
perf_attach_either(prog_fd, fd, None, None)
perf_attach_either(prog_fd, fd, None)
}
}
pub(crate) fn perf_attach_debugfs(
prog_fd: RawFd,
fd: OwnedFd,
probe_kind: ProbeKind,
event_alias: String,
event: ProbeEvent,
) -> Result<PerfLinkInner, ProgramError> {
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<ProbeKind>,
event_alias: Option<String>,
event: Option<ProbeEvent>,
) -> Result<PerfLinkInner, ProgramError> {
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 }))
}

@ -42,6 +42,12 @@ impl ProbeKind {
}
}
#[derive(Debug)]
pub(crate) struct ProbeEvent {
kind: ProbeKind,
event_alias: String,
}
pub(crate) fn attach<T: Link + From<PerfLinkInner>>(
program_data: &mut ProgramData<T>,
kind: ProbeKind,
@ -56,8 +62,7 @@ pub(crate) fn attach<T: Link + From<PerfLinkInner>>(
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<T: Link + From<PerfLinkInner>>(
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()

Loading…
Cancel
Save