Bladeren bron

Attempt auto detach of probe for debugfs

Dan Everton 3 jaren geleden
bovenliggende
commit
d0321bd
4 gewijzigde bestanden met toevoegingen van 62 en 46 verwijderingen
  1. 1 5
      aya/src/programs/kprobe.rs
  2. 37 1
      aya/src/programs/perf_attach.rs
  3. 23 35
      aya/src/programs/probe.rs
  4. 1 5
      aya/src/programs/uprobe.rs

+ 1 - 5
aya/src/programs/kprobe.rs

@@ -6,7 +6,7 @@ use crate::{
     generated::bpf_prog_type::BPF_PROG_TYPE_KPROBE,
     programs::{
         load_program,
-        probe::{attach, detach, ProbeKind},
+        probe::{attach, ProbeKind},
         LinkRef, ProgramData, ProgramError,
     },
 };
@@ -73,10 +73,6 @@ impl KProbe {
     pub fn attach(&mut self, fn_name: &str, offset: u64) -> Result<LinkRef, ProgramError> {
         attach(&mut self.data, self.kind, fn_name, offset, None)
     }
-
-    pub fn detach(&mut self, fn_name: &str) -> Result<(), ProgramError> {
-        detach(&mut self.data, self.kind, fn_name)
-    }
 }
 
 /// The type returned when attaching a [`KProbe`] fails.

+ 37 - 1
aya/src/programs/perf_attach.rs

@@ -3,6 +3,7 @@ use std::os::unix::io::RawFd;
 
 use crate::{
     sys::perf_event_ioctl, PERF_EVENT_IOC_DISABLE, PERF_EVENT_IOC_ENABLE, PERF_EVENT_IOC_SET_BPF,
+    programs::ProbeKind, programs::probe::detach_debug_fs
 };
 
 use super::{Link, LinkRef, ProgramData, ProgramError};
@@ -10,6 +11,8 @@ use super::{Link, LinkRef, ProgramData, ProgramError};
 #[derive(Debug)]
 struct PerfLink {
     perf_fd: Option<RawFd>,
+    probe_kind: Option<ProbeKind>,
+    event_alias: Option<String>,
 }
 
 impl Link for PerfLink {
@@ -17,6 +20,13 @@ impl Link for PerfLink {
         if let Some(fd) = self.perf_fd.take() {
             let _ = perf_event_ioctl(fd, PERF_EVENT_IOC_DISABLE, 0);
             unsafe { close(fd) };
+
+            if let Some(probe_kind) = self.probe_kind.take() {
+                if let Some(event_alias) = self.event_alias.take() {
+                    let _ = detach_debug_fs(probe_kind, &event_alias);
+                }
+            }
+
             Ok(())
         } else {
             Err(ProgramError::AlreadyDetached)
@@ -45,5 +55,31 @@ pub(crate) fn perf_attach(data: &mut ProgramData, fd: RawFd) -> Result<LinkRef,
         }
     })?;
 
-    Ok(data.link(PerfLink { perf_fd: Some(fd) }))
+    Ok(data.link(PerfLink {
+        perf_fd: Some(fd),
+        probe_kind: None,
+        event_alias: None,
+    }))
+}
+
+pub(crate) fn perf_attach_debugfs(data: &mut ProgramData, fd: RawFd, probe_kind: ProbeKind, event_alias: String) -> Result<LinkRef, ProgramError> {
+    let prog_fd = data.fd_or_err()?;
+    perf_event_ioctl(fd, PERF_EVENT_IOC_SET_BPF, prog_fd).map_err(|(_, io_error)| {
+        ProgramError::SyscallError {
+            call: "PERF_EVENT_IOC_SET_BPF".to_owned(),
+            io_error,
+        }
+    })?;
+    perf_event_ioctl(fd, PERF_EVENT_IOC_ENABLE, 0).map_err(|(_, io_error)| {
+        ProgramError::SyscallError {
+            call: "PERF_EVENT_IOC_ENABLE".to_owned(),
+            io_error,
+        }
+    })?;
+
+    Ok(data.link(PerfLink {
+        perf_fd: Some(fd),
+        probe_kind: Some(probe_kind),
+        event_alias: Some(event_alias),
+    }))
 }

+ 23 - 35
aya/src/programs/probe.rs

@@ -7,7 +7,7 @@ use std::{
 
 use crate::{
     programs::{
-        kprobe::KProbeError, perf_attach, trace_point::read_sys_fs_trace_point_id,
+        kprobe::KProbeError, perf_attach, perf_attach_debugfs, trace_point::read_sys_fs_trace_point_id,
         uprobe::UProbeError, LinkRef, ProgramData, ProgramError,
     },
     sys::{kernel_version, perf_event_open_probe, perf_event_open_trace_point},
@@ -32,22 +32,22 @@ pub(crate) fn attach(
     offset: u64,
     pid: Option<pid_t>,
 ) -> Result<LinkRef, ProgramError> {
+    
     // https://github.com/torvalds/linux/commit/e12f03d7031a977356e3d7b75a68c2185ff8d155
+    // Use debugfs to create probe 
     let k_ver = kernel_version().unwrap();
-    let fd = if k_ver >= (4, 17, 0) {
-        create_as_probe(kind, fn_name, offset, pid)?
-    } else {
-        create_as_trace_point(kind, fn_name, offset, pid)?
+    if k_ver < (4, 17, 0) {
+        let (fd, event_alias) = create_as_trace_point(kind, fn_name, offset, pid)?;
+
+        return perf_attach_debugfs(program_data, fd, kind, event_alias);
     };
+    
+    let fd = create_as_probe(kind, fn_name, offset, pid)?;
 
     perf_attach(program_data, fd)
 }
 
-pub(crate) fn detach(
-    program_data: &mut ProgramData,
-    kind: ProbeKind,
-    fn_name: &str,
-) -> Result<(), ProgramError> {
+pub(crate) fn detach_debug_fs(kind: ProbeKind, event_alias: &str) -> Result<(), ProgramError> {
     use ProbeKind::*;
 
     /*
@@ -64,27 +64,15 @@ pub(crate) fn detach(
         UProbe | URetProbe => "uprobe",
     };
 
-    let probe_type_prefix = match kind {
-        KProbe | UProbe => 'p',
-        KRetProbe | URetProbe => 'r',
-    };
-
     let events_file_name = format!("/sys/kernel/debug/tracing/{}_events", event_type);
-    let event_name = format!(
-        "{}s/{}_{}_aya_{}",
-        probe_type_prefix,
-        event_type,
-        program_data.name,
-        process::id()
-    );
 
     let found = match kind {
         KProbe | KRetProbe => {
-            find_in_sys_kernel_debug_tracing_events(&events_file_name, event_name.clone())
+            find_in_sys_kernel_debug_tracing_events(&events_file_name, event_alias)
                 .map_err(|(filename, io_error)| KProbeError::FileError { filename, io_error })?
         }
         UProbe | URetProbe => {
-            find_in_sys_kernel_debug_tracing_events(&events_file_name, event_name.clone())
+            find_in_sys_kernel_debug_tracing_events(&events_file_name, event_alias)
                 .map_err(|(filename, io_error)| UProbeError::FileError { filename, io_error })?
         }
     };
@@ -92,11 +80,11 @@ pub(crate) fn detach(
     if found {
         match kind {
             KProbe | KRetProbe => {
-                delete_in_sys_kernel_debug_tracing_events(&events_file_name, &event_name)
+                delete_in_sys_kernel_debug_tracing_events(&events_file_name, event_alias)
                     .map_err(|(filename, io_error)| KProbeError::FileError { filename, io_error })?
             }
             UProbe | URetProbe => {
-                delete_in_sys_kernel_debug_tracing_events(&events_file_name, &event_name)
+                delete_in_sys_kernel_debug_tracing_events(&events_file_name, event_alias)
                     .map_err(|(filename, io_error)| UProbeError::FileError { filename, io_error })?
             }
         };
@@ -147,7 +135,7 @@ fn create_as_trace_point(
     name: &str,
     offset: u64,
     pid: Option<pid_t>,
-) -> Result<i32, ProgramError> {
+) -> Result<(i32, String), ProgramError> {
     use ProbeKind::*;
 
     let (event_type, event_alias) = match kind {
@@ -172,7 +160,7 @@ fn create_as_trace_point(
         }
     })? as i32;
 
-    Ok(fd)
+    Ok((fd, event_alias))
 }
 
 fn create_probe_event(
@@ -223,13 +211,13 @@ fn create_probe_event(
 }
 
 fn find_in_sys_kernel_debug_tracing_events(
-    events_file_name: &String,
-    event_name: String,
+    events_file_name: &str,
+    event_name: &str,
 ) -> Result<bool, (String, io::Error)> {
     use std::io::BufRead;
 
     let events_file =
-        fs::File::open(events_file_name).map_err(|e| (events_file_name.clone(), e))?;
+        fs::File::open(events_file_name).map_err(|e| (events_file_name.to_string(), e))?;
 
     Ok(io::BufReader::new(events_file)
         .lines()
@@ -238,17 +226,17 @@ fn find_in_sys_kernel_debug_tracing_events(
 }
 
 fn delete_in_sys_kernel_debug_tracing_events(
-    events_file_name: &String,
-    event_name: &String,
+    events_file_name: &str,
+    event_name: &str,
 ) -> Result<(), (String, io::Error)> {
     let mut events_file = fs::OpenOptions::new()
         .append(true)
         .open(events_file_name)
-        .map_err(|e| (events_file_name.clone(), e))?;
+        .map_err(|e| (events_file_name.to_string(), e))?;
 
     events_file
         .write_fmt(format_args!("-:{}", event_name))
-        .map_err(|e| (events_file_name.clone(), e))?;
+        .map_err(|e| (events_file_name.to_string(), e))?;
 
     Ok(())
 }

+ 1 - 5
aya/src/programs/uprobe.rs

@@ -17,7 +17,7 @@ use crate::{
     generated::bpf_prog_type::BPF_PROG_TYPE_KPROBE,
     programs::{
         load_program,
-        probe::{attach, detach, ProbeKind},
+        probe::{attach, ProbeKind},
         LinkRef, ProgramData, ProgramError,
     },
 };
@@ -126,10 +126,6 @@ impl UProbe {
 
         attach(&mut self.data, self.kind, &path, sym_offset + offset, pid)
     }
-
-    pub fn detach(&mut self, fn_name: &str) -> Result<(), ProgramError> {
-        detach(&mut self.data, self.kind, fn_name)
-    }
 }
 
 /// The type returned when attaching an [`UProbe`] fails.