@@ -66,7 +66,7 @@ pub mod xdp;
66
66
67
67
use libc:: ENOSPC ;
68
68
use std:: {
69
- ffi:: CString ,
69
+ ffi:: { CStr , CString } ,
70
70
io,
71
71
os:: unix:: io:: { AsRawFd , RawFd } ,
72
72
path:: Path ,
@@ -103,13 +103,14 @@ pub use uprobe::{UProbe, UProbeError};
103
103
pub use xdp:: { Xdp , XdpError , XdpFlags } ;
104
104
105
105
use crate :: {
106
- generated:: { bpf_attach_type, bpf_prog_info, bpf_prog_type} ,
106
+ generated:: { bpf_attach_type, bpf_prog_info, bpf_prog_type, bpf_task_fd_type } ,
107
107
maps:: MapError ,
108
108
obj:: { self , btf:: BtfError , Function , KernelVersion } ,
109
109
pin:: PinError ,
110
110
sys:: {
111
111
bpf_get_object, bpf_load_program, bpf_pin_object, bpf_prog_get_fd_by_id,
112
- bpf_prog_get_info_by_fd, bpf_prog_query, retry_with_verifier_logs, BpfLoadProgramAttrs ,
112
+ bpf_prog_get_info_by_fd, bpf_prog_query, bpf_task_fd_query, retry_with_verifier_logs,
113
+ BpfLoadProgramAttrs ,
113
114
} ,
114
115
util:: VerifierLog ,
115
116
} ;
@@ -849,3 +850,111 @@ impl ProgramInfo {
849
850
Ok ( ProgramInfo ( info) )
850
851
}
851
852
}
853
+
854
+ /// Kind of a probe program from a process FD.
855
+ #[ repr( u32 ) ]
856
+ #[ non_exhaustive]
857
+ #[ derive( Debug , Copy , Clone , Hash , PartialEq , Eq ) ]
858
+ pub enum TaskFdKind {
859
+ /// Raw tracepoint.
860
+ RawTracePoint = bpf_task_fd_type:: BPF_FD_TYPE_RAW_TRACEPOINT as u32 ,
861
+ /// Tracepoint.
862
+ TracePoint = bpf_task_fd_type:: BPF_FD_TYPE_TRACEPOINT as u32 ,
863
+ /// Kernel probe.
864
+ KProbe = bpf_task_fd_type:: BPF_FD_TYPE_KPROBE as u32 ,
865
+ /// Kernel return probe.
866
+ KRetProbe = bpf_task_fd_type:: BPF_FD_TYPE_KRETPROBE as u32 ,
867
+ /// User space probe.
868
+ UProbe = bpf_task_fd_type:: BPF_FD_TYPE_UPROBE as u32 ,
869
+ /// User space return probe.
870
+ URetProbe = bpf_task_fd_type:: BPF_FD_TYPE_URETPROBE as u32 ,
871
+ }
872
+
873
+ impl TryFrom < u32 > for TaskFdKind {
874
+ type Error = ProgramError ;
875
+
876
+ fn try_from ( v : u32 ) -> Result < Self , Self :: Error > {
877
+ use bpf_task_fd_type:: * ;
878
+ use TaskFdKind :: * ;
879
+ Ok ( match v {
880
+ x if x == BPF_FD_TYPE_RAW_TRACEPOINT as u32 => RawTracePoint ,
881
+ x if x == BPF_FD_TYPE_TRACEPOINT as u32 => TracePoint ,
882
+ x if x == BPF_FD_TYPE_KPROBE as u32 => KProbe ,
883
+ x if x == BPF_FD_TYPE_KRETPROBE as u32 => KRetProbe ,
884
+ x if x == BPF_FD_TYPE_UPROBE as u32 => UProbe ,
885
+ x if x == BPF_FD_TYPE_URETPROBE as u32 => URetProbe ,
886
+ _ => return Err ( ProgramError :: UnexpectedProgramType ) ,
887
+ } )
888
+ }
889
+ }
890
+
891
+ /// Details of a probe program from a process FD.
892
+ #[ derive( Debug ) ]
893
+ pub struct TaskFdDetails < ' buf > {
894
+ /// Program ID.
895
+ id : u32 ,
896
+ /// Program kind.
897
+ kind : TaskFdKind ,
898
+ /// Program name.
899
+ name : Option < & ' buf CStr > ,
900
+ /// Optional program probe address.
901
+ probe_addr : Option < u64 > ,
902
+ /// Optional program probe offset.
903
+ probe_offset : Option < u64 > ,
904
+ }
905
+
906
+ impl < ' buf > TaskFdDetails < ' buf > {
907
+ /// Query the details of an FD in a process (task), looking for probe programs.
908
+ ///
909
+ /// `Ok(None)` is returned if the target FD does not exist or is not a probe program.
910
+ pub fn query_task_fd (
911
+ pid : u32 ,
912
+ target_fd : RawFd ,
913
+ out_name_buf : Option < & mut [ u8 ] > ,
914
+ ) -> Result < Option < TaskFdDetails < ' buf > > , ProgramError > {
915
+ let out = match bpf_task_fd_query ( pid, target_fd, out_name_buf) {
916
+ Ok ( v) => v,
917
+ // ENOTSUPP (errno 95) means that the target FD is not a perf program.
918
+ Err ( e) if e. raw_os_error ( ) == Some ( 95 ) => return Ok ( None ) ,
919
+ // ENOENT (errno 2) means that the target FD or PID does not exist.
920
+ Err ( e) if e. raw_os_error ( ) == Some ( 2 ) => return Ok ( None ) ,
921
+ Err ( e) => {
922
+ return Err ( ProgramError :: SyscallError {
923
+ call : "bpf_task_fd_query" . to_owned ( ) ,
924
+ io_error : e,
925
+ } )
926
+ }
927
+ } ;
928
+ let kind = TaskFdKind :: try_from ( out. fd_type as u32 ) ?;
929
+ Ok ( Some ( TaskFdDetails {
930
+ id : out. prog_id ,
931
+ kind,
932
+ name : out. name ,
933
+ probe_addr : out. probe_addr ,
934
+ probe_offset : out. probe_offset ,
935
+ } ) )
936
+ }
937
+
938
+ /// Return the program ID.
939
+ pub fn id ( & self ) -> u32 {
940
+ self . id
941
+ }
942
+
943
+ /// Return the program kind.
944
+ pub fn kind ( & self ) -> TaskFdKind {
945
+ self . kind
946
+ }
947
+
948
+ /// Return the program name.
949
+ pub fn name ( & self ) -> Option < & CStr > {
950
+ self . name
951
+ }
952
+
953
+ /// Return the program probe address and offset.
954
+ pub fn address_and_offset ( & self ) -> Option < ( u64 , u64 ) > {
955
+ match ( self . probe_addr , self . probe_offset ) {
956
+ ( Some ( a) , Some ( o) ) => Some ( ( a, o) ) ,
957
+ _ => None ,
958
+ }
959
+ }
960
+ }
0 commit comments