Skip to content

Commit

Permalink
Remove nix dependency in libbpf-rs
Browse files Browse the repository at this point in the history
Signed-off-by: Yan Wen <[email protected]>
  • Loading branch information
yan-ace62 authored and danielocfb committed Mar 19, 2024
1 parent 49c5f2b commit 98ccaf3
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 74 deletions.
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion libbpf-rs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ vendored = ["libbpf-sys/vendored"]
bitflags = "2.0"
libbpf-sys = { version = "1.3", default-features = false }
libc = "0.2"
nix = { version = "0.28", default-features = false, features = ["net", "user"] }
num_enum = "0.5"
strum_macros = "0.24"
thiserror = "1.0.10"
Expand Down
23 changes: 10 additions & 13 deletions libbpf-rs/src/iter.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::io;
use std::os::unix::io::AsFd as _;
use std::os::unix::io::AsRawFd as _;

use nix::unistd;
use std::os::fd::AsFd;
use std::os::fd::AsRawFd;
use std::os::fd::FromRawFd;
use std::os::fd::OwnedFd;

use crate::Error;
use crate::Link;
Expand All @@ -16,7 +16,7 @@ use crate::Result;
/// [`plain`](https://crates.io/crates/plain) helpful.
#[derive(Debug)]
pub struct Iter {
fd: i32,
fd: OwnedFd,
}

impl Iter {
Expand All @@ -27,22 +27,19 @@ impl Iter {
if fd < 0 {
return Err(Error::from(io::Error::last_os_error()));
}
Ok(Self { fd })
Ok(Self {
fd: unsafe { OwnedFd::from_raw_fd(fd) },
})
}
}

impl io::Read for Iter {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let bytes_read = unsafe { libc::read(self.fd, buf.as_mut_ptr() as *mut _, buf.len()) };
let bytes_read =
unsafe { libc::read(self.fd.as_raw_fd(), buf.as_mut_ptr() as *mut _, buf.len()) };
if bytes_read < 0 {
return Err(io::Error::last_os_error());
}
Ok(bytes_read as usize)
}
}

impl Drop for Iter {
fn drop(&mut self) {
let _ = unistd::close(self.fd);
}
}
13 changes: 5 additions & 8 deletions libbpf-rs/src/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ use std::slice::from_raw_parts;
use bitflags::bitflags;
use libbpf_sys::bpf_map_info;
use libbpf_sys::bpf_obj_get_info_by_fd;
use nix::unistd;
use num_enum::IntoPrimitive;
use num_enum::TryFromPrimitive;
use strum_macros::Display;
Expand Down Expand Up @@ -159,8 +158,8 @@ impl OpenMap {
}

/// Reuse an fd for a BPF map
pub fn reuse_fd(&self, fd: i32) -> Result<()> {
let ret = unsafe { libbpf_sys::bpf_map__reuse_fd(self.ptr.as_ptr(), fd) };
pub fn reuse_fd(&self, fd: BorrowedFd<'_>) -> Result<()> {
let ret = unsafe { libbpf_sys::bpf_map__reuse_fd(self.ptr.as_ptr(), fd.as_raw_fd()) };
util::parse_ret(ret)
}

Expand All @@ -172,12 +171,10 @@ impl OpenMap {
if fd < 0 {
return Err(Error::from(io::Error::last_os_error()));
}
let reuse_result = self.reuse_fd(fd);

// Always close `fd` regardless of if `reuse_fd` succeeded or failed
//
// Ignore errors b/c can't really recover from failure
let _ = unistd::close(fd);
let fd = unsafe { OwnedFd::from_raw_fd(fd) };

let reuse_result = self.reuse_fd(fd.as_fd());

reuse_result
}
Expand Down
114 changes: 68 additions & 46 deletions libbpf-rs/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@ use std::ffi::c_void;
use std::ffi::CString;
use std::io;
use std::mem::size_of_val;
use std::os::fd::AsFd;
use std::os::fd::AsRawFd;
use std::os::fd::BorrowedFd;
use std::os::fd::FromRawFd;
use std::os::fd::OwnedFd;
use std::os::raw::c_char;
use std::ptr;
use std::time::Duration;

use nix::unistd::close;

use crate::util;
use crate::MapType;
use crate::ProgramAttachType;
Expand All @@ -38,7 +41,7 @@ macro_rules! gen_info_impl {

impl $name {
// Returns Some(next_valid_fd), None on none left
fn next_valid_fd(&mut self) -> Option<i32> {
fn next_valid_fd(&mut self) -> Option<OwnedFd> {
loop {
if unsafe { $next_id(self.cur_id, &mut self.cur_id) } != 0 {
return None;
Expand All @@ -54,7 +57,7 @@ macro_rules! gen_info_impl {
return None;
}

return Some(fd);
return Some(unsafe { OwnedFd::from_raw_fd(fd)});
}
}
}
Expand All @@ -63,10 +66,7 @@ macro_rules! gen_info_impl {
type Item = $info_ty;

fn next(&mut self) -> Option<Self::Item> {
let fd = match self.next_valid_fd() {
Some(fd) => fd,
None => return None,
};
let fd = self.next_valid_fd()?;

// We need to use std::mem::zeroed() instead of just using
// ::default() because padding bytes need to be zero as well.
Expand All @@ -77,14 +77,13 @@ macro_rules! gen_info_impl {
let item_ptr: *mut $uapi_info_ty = &mut item;
let mut len = size_of_val(&item) as u32;

let ret = unsafe { libbpf_sys::bpf_obj_get_info_by_fd(fd, item_ptr as *mut c_void, &mut len) };
let ret = unsafe { libbpf_sys::bpf_obj_get_info_by_fd(fd.as_raw_fd(), item_ptr as *mut c_void, &mut len) };
let parsed_uapi = if ret != 0 {
None
} else {
<$info_ty>::from_uapi(fd, item)
<$info_ty>::from_uapi(fd.as_fd(), item)
};

let _ = close(fd);
parsed_uapi
}
}
Expand Down Expand Up @@ -270,7 +269,7 @@ impl ProgInfoQueryOptions {
}

impl ProgramInfo {
fn load_from_fd(fd: i32, opts: &ProgInfoQueryOptions) -> Result<Self> {
fn load_from_fd(fd: BorrowedFd<'_>, opts: &ProgInfoQueryOptions) -> Result<Self> {
let mut item = libbpf_sys::bpf_prog_info::default();

let mut xlated_prog_insns: Vec<u8> = Vec::new();
Expand All @@ -286,8 +285,9 @@ impl ProgramInfo {
let item_ptr: *mut libbpf_sys::bpf_prog_info = &mut item;
let mut len = size_of_val(&item) as u32;

let ret =
unsafe { libbpf_sys::bpf_obj_get_info_by_fd(fd, item_ptr as *mut c_void, &mut len) };
let ret = unsafe {
libbpf_sys::bpf_obj_get_info_by_fd(fd.as_raw_fd(), item_ptr as *mut c_void, &mut len)
};
util::parse_ret(ret)?;

// SANITY: `libbpf` should guarantee NUL termination.
Expand Down Expand Up @@ -366,8 +366,9 @@ impl ProgramInfo {
item.nr_jited_ksyms = 0;
}

let ret =
unsafe { libbpf_sys::bpf_obj_get_info_by_fd(fd, item_ptr as *mut c_void, &mut len) };
let ret = unsafe {
libbpf_sys::bpf_obj_get_info_by_fd(fd.as_raw_fd(), item_ptr as *mut c_void, &mut len)
};
util::parse_ret(ret)?;

return Ok(ProgramInfo {
Expand Down Expand Up @@ -401,10 +402,8 @@ impl ProgramInfo {
}
}

impl Iterator for ProgInfoIter {
type Item = ProgramInfo;

fn next(&mut self) -> Option<Self::Item> {
impl ProgInfoIter {
fn next_valid_fd(&mut self) -> Option<OwnedFd> {
loop {
if unsafe { libbpf_sys::bpf_prog_get_next_id(self.cur_id, &mut self.cur_id) } != 0 {
return None;
Expand All @@ -419,14 +418,23 @@ impl Iterator for ProgInfoIter {
return None;
}

let prog = ProgramInfo::load_from_fd(fd, &self.opts);
let _ = close(fd);
return Some(unsafe { OwnedFd::from_raw_fd(fd) });
}
}
}

match prog {
Ok(p) => return Some(p),
// TODO: We should consider bubbling up errors properly.
Err(_err) => (),
}
impl Iterator for ProgInfoIter {
type Item = ProgramInfo;

fn next(&mut self) -> Option<Self::Item> {
let fd = self.next_valid_fd()?;

let prog = ProgramInfo::load_from_fd(fd.as_fd(), &self.opts);

match prog {
Ok(p) => Some(p),
// TODO: We should consider bubbling up errors properly.
Err(_err) => None,
}
}
}
Expand All @@ -453,7 +461,7 @@ pub struct MapInfo {
}

impl MapInfo {
fn from_uapi(_fd: i32, s: libbpf_sys::bpf_map_info) -> Option<Self> {
fn from_uapi(_fd: BorrowedFd<'_>, s: libbpf_sys::bpf_map_info) -> Option<Self> {
// SANITY: `libbpf` should guarantee NUL termination.
let name = util::c_char_slice_to_cstr(&s.name).unwrap();
let ty = match MapType::try_from(s.type_) {
Expand Down Expand Up @@ -501,16 +509,17 @@ pub struct BtfInfo {
}

impl BtfInfo {
fn load_from_fd(fd: i32) -> Result<Self> {
fn load_from_fd(fd: BorrowedFd<'_>) -> Result<Self> {
let mut item = libbpf_sys::bpf_btf_info::default();
let mut btf: Vec<u8> = Vec::new();
let mut name: Vec<u8> = Vec::new();

let item_ptr: *mut libbpf_sys::bpf_btf_info = &mut item;
let mut len = size_of_val(&item) as u32;

let ret =
unsafe { libbpf_sys::bpf_obj_get_info_by_fd(fd, item_ptr as *mut c_void, &mut len) };
let ret = unsafe {
libbpf_sys::bpf_obj_get_info_by_fd(fd.as_raw_fd(), item_ptr as *mut c_void, &mut len)
};
util::parse_ret(ret)?;

// The API gives you the ascii string length while expecting
Expand All @@ -522,8 +531,9 @@ impl BtfInfo {
btf.resize(item.btf_size as usize, 0u8);
item.btf = btf.as_mut_ptr() as *mut c_void as u64;

let ret =
unsafe { libbpf_sys::bpf_obj_get_info_by_fd(fd, item_ptr as *mut c_void, &mut len) };
let ret = unsafe {
libbpf_sys::bpf_obj_get_info_by_fd(fd.as_raw_fd(), item_ptr as *mut c_void, &mut len)
};
util::parse_ret(ret)?;

Ok(BtfInfo {
Expand All @@ -544,10 +554,9 @@ pub struct BtfInfoIter {
cur_id: u32,
}

impl Iterator for BtfInfoIter {
type Item = BtfInfo;

fn next(&mut self) -> Option<Self::Item> {
impl BtfInfoIter {
// Returns Some(next_valid_fd), None on none left
fn next_valid_fd(&mut self) -> Option<OwnedFd> {
loop {
if unsafe { libbpf_sys::bpf_btf_get_next_id(self.cur_id, &mut self.cur_id) } != 0 {
return None;
Expand All @@ -562,14 +571,23 @@ impl Iterator for BtfInfoIter {
return None;
}

let info = BtfInfo::load_from_fd(fd);
let _ = close(fd);
return Some(unsafe { OwnedFd::from_raw_fd(fd) });
}
}
}

impl Iterator for BtfInfoIter {
type Item = BtfInfo;

match info {
Ok(i) => return Some(i),
// TODO: We should consider bubbling up errors properly.
Err(_err) => (),
}
fn next(&mut self) -> Option<Self::Item> {
let fd = self.next_valid_fd()?;

let info = BtfInfo::load_from_fd(fd.as_fd());

match info {
Ok(i) => Some(i),
// TODO: We should consider bubbling up errors properly.
Err(_err) => None,
}
}
}
Expand Down Expand Up @@ -627,7 +645,7 @@ pub struct LinkInfo {
}

impl LinkInfo {
fn from_uapi(fd: i32, mut s: libbpf_sys::bpf_link_info) -> Option<Self> {
fn from_uapi(fd: BorrowedFd<'_>, mut s: libbpf_sys::bpf_link_info) -> Option<Self> {
let type_info = match s.type_ {
libbpf_sys::BPF_LINK_TYPE_RAW_TRACEPOINT => {
let mut buf = [0; 256];
Expand All @@ -637,7 +655,11 @@ impl LinkInfo {
let mut len = size_of_val(&s) as u32;

let ret = unsafe {
libbpf_sys::bpf_obj_get_info_by_fd(fd, item_ptr as *mut c_void, &mut len)
libbpf_sys::bpf_obj_get_info_by_fd(
fd.as_raw_fd(),
item_ptr as *mut c_void,
&mut len,
)
};
if ret != 0 {
return None;
Expand Down
6 changes: 1 addition & 5 deletions libbpf-rs/tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use std::hint;
use std::io;
use std::io::Read;
use std::mem::size_of;
use std::os::fd::AsRawFd;
use std::os::unix::io::AsFd;
use std::path::Path;
use std::path::PathBuf;
Expand All @@ -19,8 +18,6 @@ use std::slice;
use std::sync::mpsc::channel;
use std::time::Duration;

use nix::unistd::close;

use plain::Plain;
use probe::probe;
use scopeguard::defer;
Expand Down Expand Up @@ -1780,8 +1777,7 @@ fn test_sudo_program_get_fd_and_id() {

let prog_fd = prog.as_fd();
let prog_id = Program::get_id_by_fd(prog_fd).expect("failed to get program id by fd");
let owned_prog_fd = Program::get_fd_by_id(prog_id).expect("failed to get program fd by id");
close(owned_prog_fd.as_raw_fd()).expect("failed to close owned program fd");
let _owned_prog_fd = Program::get_fd_by_id(prog_id).expect("failed to get program fd by id");
}

/// Check that autocreate disabled maps don't prevent object loading
Expand Down

0 comments on commit 98ccaf3

Please sign in to comment.