1use crate::core::BPF;
2use crate::error::BccError;
3use bcc_sys::bccapi::bpf_prog_type_BPF_PROG_TYPE_TRACEPOINT as BPF_PROG_TYPE_TRACEPOINT;
4
5#[derive(Default)]
6pub struct Tracepoint {
7 handler: Option<String>,
8 subsystem: Option<String>,
9 tracepoint: Option<String>,
10}
11
12impl Tracepoint {
13 pub fn new() -> Self {
16 Default::default()
17 }
18
19 pub fn handler(mut self, name: &str) -> Self {
22 self.handler = Some(name.to_owned());
23 self
24 }
25
26 pub fn subsystem(mut self, name: &str) -> Self {
28 self.subsystem = Some(name.to_owned());
29 self
30 }
31
32 pub fn tracepoint(mut self, name: &str) -> Self {
34 self.tracepoint = Some(name.to_owned());
35 self
36 }
37
38 pub fn attach(self, bpf: &mut BPF) -> Result<(), BccError> {
42 if self.handler.is_none() {
43 return Err(BccError::InvalidTracepoint {
44 message: "handler is required".to_string(),
45 });
46 }
47 if self.subsystem.is_none() {
48 return Err(BccError::InvalidTracepoint {
49 message: "subsystem is required".to_string(),
50 });
51 }
52 if self.tracepoint.is_none() {
53 return Err(BccError::InvalidTracepoint {
54 message: "tracepoint is required".to_string(),
55 });
56 }
57 let handler = self.handler.unwrap();
58 let subsystem = self.subsystem.unwrap();
59 let tracepoint = self.tracepoint.unwrap();
60
61 let code_fd = bpf.load(&handler, BPF_PROG_TYPE_TRACEPOINT, 0, 0)?;
62 let tracepoint = crate::core::Tracepoint::new(&subsystem, &tracepoint, code_fd)?;
63 bpf.tracepoints.insert(tracepoint);
64 Ok(())
65 }
66}