Skip to content

Commit

Permalink
Merge pull request #471 from banditopazzo/tracefs_mount_select
Browse files Browse the repository at this point in the history
add tracefs mount point select function
  • Loading branch information
alessandrod committed Jan 26, 2023
2 parents 556463a + 48fdf5a commit 7e5637b
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 22 deletions.
4 changes: 4 additions & 0 deletions aya/src/programs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,10 @@ pub enum ProgramError {
/// program name
name: String,
},

/// An error occurred while working with IO.
#[error(transparent)]
IOError(#[from] io::Error),
}

/// A [`Program`] file descriptor.
Expand Down
42 changes: 26 additions & 16 deletions aya/src/programs/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ use libc::pid_t;
use std::{
fs::{self, OpenOptions},
io::{self, Write},
path::Path,
process,
};

use crate::{
programs::{
kprobe::KProbeError, perf_attach, perf_attach::PerfLink, perf_attach_debugfs,
trace_point::read_sys_fs_trace_point_id, uprobe::UProbeError, Link, ProgramData,
ProgramError,
trace_point::read_sys_fs_trace_point_id, uprobe::UProbeError, utils::find_tracefs_path,
Link, ProgramData, ProgramError,
},
sys::{kernel_version, perf_event_open_probe, perf_event_open_trace_point},
};
Expand Down Expand Up @@ -60,10 +61,12 @@ pub(crate) fn attach<T: Link + From<PerfLink>>(
pub(crate) fn detach_debug_fs(kind: ProbeKind, event_alias: &str) -> Result<(), ProgramError> {
use ProbeKind::*;

let tracefs = find_tracefs_path()?;

match kind {
KProbe | KRetProbe => delete_probe_event(kind, event_alias)
KProbe | KRetProbe => delete_probe_event(tracefs, kind, event_alias)
.map_err(|(filename, io_error)| KProbeError::FileError { filename, io_error })?,
UProbe | URetProbe => delete_probe_event(kind, event_alias)
UProbe | URetProbe => delete_probe_event(tracefs, kind, event_alias)
.map_err(|(filename, io_error)| UProbeError::FileError { filename, io_error })?,
};

Expand Down Expand Up @@ -115,15 +118,17 @@ fn create_as_trace_point(
) -> Result<(i32, String), ProgramError> {
use ProbeKind::*;

let tracefs = find_tracefs_path()?;

let event_alias = match kind {
KProbe | KRetProbe => create_probe_event(kind, name, offset)
KProbe | KRetProbe => create_probe_event(tracefs, kind, name, offset)
.map_err(|(filename, io_error)| KProbeError::FileError { filename, io_error })?,
UProbe | URetProbe => create_probe_event(kind, name, offset)
UProbe | URetProbe => create_probe_event(tracefs, kind, name, offset)
.map_err(|(filename, io_error)| UProbeError::FileError { filename, io_error })?,
};

let category = format!("{}s", kind.pmu());
let tpid = read_sys_fs_trace_point_id(&category, &event_alias)?;
let tpid = read_sys_fs_trace_point_id(tracefs, &category, &event_alias)?;
let fd = perf_event_open_trace_point(tpid, pid).map_err(|(_code, io_error)| {
ProgramError::SyscallError {
call: "perf_event_open".to_owned(),
Expand All @@ -135,13 +140,14 @@ fn create_as_trace_point(
}

fn create_probe_event(
tracefs: &Path,
kind: ProbeKind,
fn_name: &str,
offset: u64,
) -> Result<String, (String, io::Error)> {
use ProbeKind::*;

let events_file_name = format!("/sys/kernel/debug/tracing/{}_events", kind.pmu());
let events_file_name = tracefs.join(format!("{}_events", kind.pmu()));
let probe_type_prefix = match kind {
KProbe | UProbe => 'p',
KRetProbe | URetProbe => 'r',
Expand Down Expand Up @@ -170,34 +176,38 @@ fn create_probe_event(
let mut events_file = OpenOptions::new()
.append(true)
.open(&events_file_name)
.map_err(|e| (events_file_name.clone(), e))?;
.map_err(|e| (events_file_name.display().to_string(), e))?;

events_file
.write_all(probe.as_bytes())
.map_err(|e| (events_file_name.clone(), e))?;
.map_err(|e| (events_file_name.display().to_string(), e))?;

Ok(event_alias)
}

fn delete_probe_event(kind: ProbeKind, event_alias: &str) -> Result<(), (String, io::Error)> {
let events_file_name = format!("/sys/kernel/debug/tracing/{}_events", kind.pmu());
fn delete_probe_event(
tracefs: &Path,
kind: ProbeKind,
event_alias: &str,
) -> Result<(), (String, io::Error)> {
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.clone(), e))?;
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));

if found {
let mut events_file = OpenOptions::new()
.append(true)
.open(&events_file_name)
.map_err(|e| (events_file_name.to_string(), e))?;
.map_err(|e| (events_file_name.display().to_string(), e))?;

let rm = format!("-:{event_alias}\n");

events_file
.write_all(rm.as_bytes())
.map_err(|e| (events_file_name.to_string(), e))?;
.map_err(|e| (events_file_name.display().to_string(), e))?;
}

Ok(())
Expand Down
13 changes: 8 additions & 5 deletions aya/src/programs/trace_point.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
//! Tracepoint programs.
use std::{fs, io};
use std::{fs, io, path::Path};
use thiserror::Error;

use crate::{
generated::bpf_prog_type::BPF_PROG_TYPE_TRACEPOINT,
programs::{
define_link_wrapper, load_program,
perf_attach::{perf_attach, PerfLink, PerfLinkId},
utils::find_tracefs_path,
ProgramData, ProgramError,
},
sys::perf_event_open_trace_point,
Expand Down Expand Up @@ -77,7 +78,8 @@ impl TracePoint {
///
/// The returned value can be used to detach, see [TracePoint::detach].
pub fn attach(&mut self, category: &str, name: &str) -> Result<TracePointLinkId, ProgramError> {
let id = read_sys_fs_trace_point_id(category, name)?;
let tracefs = find_tracefs_path()?;
let id = read_sys_fs_trace_point_id(tracefs, category, name)?;
let fd = perf_event_open_trace_point(id, None).map_err(|(_code, io_error)| {
ProgramError::SyscallError {
call: "perf_event_open".to_owned(),
Expand Down Expand Up @@ -114,20 +116,21 @@ define_link_wrapper!(
);

pub(crate) fn read_sys_fs_trace_point_id(
tracefs: &Path,
category: &str,
name: &str,
) -> Result<u32, TracePointError> {
let file = format!("/sys/kernel/debug/tracing/events/{category}/{name}/id");
let file = tracefs.join("events").join(category).join(name).join("id");

let id = fs::read_to_string(&file).map_err(|io_error| TracePointError::FileError {
filename: file.clone(),
filename: file.display().to_string(),
io_error,
})?;
let id = id
.trim()
.parse::<u32>()
.map_err(|error| TracePointError::FileError {
filename: file.clone(),
filename: file.display().to_string(),
io_error: io::Error::new(io::ErrorKind::Other, error),
})?;

Expand Down
25 changes: 24 additions & 1 deletion aya/src/programs/utils.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! Common functions shared between multiple eBPF program types.
use std::{ffi::CStr, os::unix::io::RawFd};
use std::{ffi::CStr, io, os::unix::io::RawFd, path::Path};

use crate::{
programs::{FdLink, Link, ProgramData, ProgramError},
Expand All @@ -22,3 +22,26 @@ pub(crate) fn attach_raw_tracepoint<T: Link + From<FdLink>>(

program_data.links.insert(FdLink::new(pfd).into())
}

/// Find tracefs filesystem path
pub(crate) fn find_tracefs_path() -> Result<&'static Path, ProgramError> {
lazy_static::lazy_static! {
static ref TRACE_FS: Option<&'static Path> = {
let known_mounts = [
Path::new("/sys/kernel/tracing"),
Path::new("/sys/kernel/debug/tracing"),
];

for mount in known_mounts {
if mount.exists() {
return Some(mount);
}
}
None
};
}

TRACE_FS
.as_deref()
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "tracefs not found").into())
}

0 comments on commit 7e5637b

Please sign in to comment.