Skip to content

Commit 2575135

Browse files
alexgartrelldanielocfb
authored andcommitted
libbpf-rs: Implement more complete BpfInfoIter
Fetch the actual data from the kernel. In this case, partial fetches of either name or btf data don't make sense, so we haven't implemented the Options pattern as we did for the BpfProgIter
1 parent be857ed commit 2575135

File tree

2 files changed

+70
-18
lines changed

2 files changed

+70
-18
lines changed

examples/bpf_query/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ fn map() {
6262

6363
fn btf() {
6464
for btf in query::BtfInfoIter::default() {
65-
println!("id={:4} size={}", btf.id, btf.btf_size);
65+
println!("id={:4} name={} size={}", btf.id, btf.name, btf.btf.len());
6666
}
6767
}
6868

libbpf-rs/src/query.rs

Lines changed: 69 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ fn name_arr_to_string(a: &[c_char], default: &str) -> String {
106106
}
107107
}
108108

109-
#[derive(Clone, Debug)]
110109
/// BTF Line information
110+
#[derive(Clone, Debug)]
111111
pub struct LineInfo {
112112
/// Offset of instruction in vector
113113
pub insn_off: u32,
@@ -497,32 +497,84 @@ gen_info_impl!(
497497

498498
/// Information about BPF type format
499499
#[derive(Debug, Clone)]
500-
// TODO: Document members.
501500
#[allow(missing_docs)]
502501
pub struct BtfInfo {
503-
pub btf: u64,
504-
pub btf_size: u32,
502+
/// The name associated with this btf information in the kernel
503+
pub name: String,
504+
/// The raw btf bytes from the kernel
505+
pub btf: Vec<u8>,
506+
/// The btf id associated with this btf information in the kernel
505507
pub id: u32,
506508
}
507509

508510
impl BtfInfo {
509-
fn from_uapi(_fd: i32, s: libbpf_sys::bpf_btf_info) -> Option<Self> {
510-
Some(Self {
511-
btf: s.btf,
512-
btf_size: s.btf_size,
513-
id: s.id,
511+
fn load_from_fd(fd: i32) -> Result<Self> {
512+
let mut item = libbpf_sys::bpf_btf_info::default();
513+
let mut btf: Vec<u8> = Vec::new();
514+
let mut name: Vec<u8> = Vec::new();
515+
516+
let item_ptr: *mut libbpf_sys::bpf_btf_info = &mut item;
517+
let mut len = size_of::<libbpf_sys::bpf_btf_info>() as u32;
518+
519+
let ret =
520+
unsafe { libbpf_sys::bpf_obj_get_info_by_fd(fd, item_ptr as *mut c_void, &mut len) };
521+
util::parse_ret(ret)?;
522+
523+
// The API gives you the ascii string length while expecting
524+
// you to give it back space for a nul-terminator
525+
item.name_len += 1;
526+
name.resize(item.name_len as usize, 0u8);
527+
item.name = name.as_mut_ptr() as *mut c_void as u64;
528+
529+
btf.resize(item.btf_size as usize, 0u8);
530+
item.btf = btf.as_mut_ptr() as *mut c_void as u64;
531+
532+
let ret =
533+
unsafe { libbpf_sys::bpf_obj_get_info_by_fd(fd, item_ptr as *mut c_void, &mut len) };
534+
util::parse_ret(ret)?;
535+
536+
Ok(BtfInfo {
537+
name: String::from_utf8(name).unwrap_or_else(|_| "(?)".to_string()),
538+
btf,
539+
id: item.id,
514540
})
515541
}
516542
}
517543

518-
gen_info_impl!(
519-
/// Iterator that returns [`BtfInfo`]s.
520-
BtfInfoIter,
521-
BtfInfo,
522-
libbpf_sys::bpf_btf_info,
523-
libbpf_sys::bpf_btf_get_next_id,
524-
libbpf_sys::bpf_btf_get_fd_by_id
525-
);
544+
#[derive(Debug, Default)]
545+
/// An iterator for the btf type information of modules and programs
546+
/// in the kernel
547+
pub struct BtfInfoIter {
548+
cur_id: u32,
549+
}
550+
551+
impl Iterator for BtfInfoIter {
552+
type Item = BtfInfo;
553+
554+
fn next(&mut self) -> Option<Self::Item> {
555+
loop {
556+
if unsafe { libbpf_sys::bpf_btf_get_next_id(self.cur_id, &mut self.cur_id) } != 0 {
557+
return None;
558+
}
559+
560+
let fd = unsafe { libbpf_sys::bpf_btf_get_fd_by_id(self.cur_id) };
561+
if fd < 0 {
562+
if errno::errno() == errno::Errno::ENOENT as i32 {
563+
continue;
564+
}
565+
return None;
566+
}
567+
568+
let info = BtfInfo::load_from_fd(fd);
569+
let _ = close(fd);
570+
571+
match info {
572+
Ok(i) => return Some(i),
573+
Err(e) => eprintln!("Failed to load btf information: {}", e),
574+
}
575+
}
576+
}
577+
}
526578

527579
#[derive(Debug, Clone)]
528580
// TODO: Document members.

0 commit comments

Comments
 (0)