Skip to content

Commit

Permalink
Use MockableFd everywhere
Browse files Browse the repository at this point in the history
Rust 1.80 contains rust-lang/rust#124210,
causing tests which we skip under miri to segfault.
  • Loading branch information
tamird authored and vadorovsky committed Jul 29, 2024
1 parent a167554 commit e12fcf4
Show file tree
Hide file tree
Showing 14 changed files with 121 additions and 79 deletions.
7 changes: 5 additions & 2 deletions aya/src/bpf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{
collections::{HashMap, HashSet},
fs, io,
os::{
fd::{AsFd as _, AsRawFd as _, OwnedFd},
fd::{AsFd as _, AsRawFd as _},
raw::c_int,
},
path::{Path, PathBuf},
Expand Down Expand Up @@ -1123,7 +1123,10 @@ pub enum EbpfError {
#[deprecated(since = "0.13.0", note = "use `EbpfError` instead")]
pub type BpfError = EbpfError;

fn load_btf(raw_btf: Vec<u8>, verifier_log_level: VerifierLogLevel) -> Result<OwnedFd, BtfError> {
fn load_btf(
raw_btf: Vec<u8>,
verifier_log_level: VerifierLogLevel,
) -> Result<crate::MockableFd, BtfError> {
let (ret, verifier_log) = retry_with_verifier_logs(10, |logger| {
bpf_load_btf(raw_btf.as_slice(), logger, verifier_log_level)
});
Expand Down
56 changes: 39 additions & 17 deletions aya/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ pub use programs::loaded_programs;
mod sys;
pub mod util;

use std::os::fd::{AsFd, BorrowedFd, OwnedFd};
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, OwnedFd, RawFd};

pub use bpf::*;
pub use obj::btf::{Btf, BtfError};
Expand Down Expand Up @@ -123,35 +123,55 @@ impl MockableFd {

#[cfg(test)]
fn from_fd(fd: OwnedFd) -> Self {
Self { fd: Some(fd) }
let fd = Some(fd);
Self { fd }
}

#[cfg(not(test))]
fn try_clone(&self) -> std::io::Result<Self> {
fn inner(&self) -> &OwnedFd {
let Self { fd } = self;
let fd = fd.try_clone()?;
Ok(Self { fd })
fd
}

#[cfg(test)]
fn try_clone(&self) -> std::io::Result<Self> {
fn inner(&self) -> &OwnedFd {
let Self { fd } = self;
let fd = fd.as_ref().map(OwnedFd::try_clone).transpose()?;
Ok(Self { fd })
fd.as_ref().unwrap()
}

fn try_clone(&self) -> std::io::Result<Self> {
let fd = self.inner();
let fd = fd.try_clone()?;
Ok(Self::from_fd(fd))
}
}

impl<T> From<T> for MockableFd
where
OwnedFd: From<T>,
{
fn from(value: T) -> Self {
let fd = OwnedFd::from(value);
Self::from_fd(fd)
}
}

impl AsFd for MockableFd {
#[cfg(not(test))]
fn as_fd(&self) -> BorrowedFd<'_> {
let Self { fd } = self;
fd.as_fd()
self.inner().as_fd()
}
}

#[cfg(test)]
fn as_fd(&self) -> BorrowedFd<'_> {
let Self { fd } = self;
fd.as_ref().unwrap().as_fd()
impl AsRawFd for MockableFd {
fn as_raw_fd(&self) -> RawFd {
self.inner().as_raw_fd()
}
}

impl FromRawFd for MockableFd {
unsafe fn from_raw_fd(fd: RawFd) -> Self {
let fd = OwnedFd::from_raw_fd(fd);
Self::from_fd(fd)
}
}

Expand All @@ -166,8 +186,10 @@ impl Drop for MockableFd {
use std::os::fd::AsRawFd as _;

let Self { fd } = self;
if fd.as_ref().unwrap().as_raw_fd() >= Self::mock_signed_fd() {
let fd: OwnedFd = fd.take().unwrap();
let fd = fd.take().unwrap();
if fd.as_raw_fd() < Self::mock_signed_fd() {
std::mem::drop(fd)
} else {
std::mem::forget(fd)
}
}
Expand Down
22 changes: 13 additions & 9 deletions aya/src/maps/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,7 @@ pub struct MapFd {
}

impl MapFd {
fn from_fd(fd: OwnedFd) -> Self {
let fd = crate::MockableFd::from_fd(fd);
fn from_fd(fd: crate::MockableFd) -> Self {
Self { fd }
}

Expand Down Expand Up @@ -657,13 +656,21 @@ impl MapData {
io_error,
})?;

Self::from_fd(fd)
Self::from_fd_inner(fd)
}

/// Loads a map from a map id.
pub fn from_id(id: u32) -> Result<Self, MapError> {
let fd = bpf_map_get_fd_by_id(id)?;
Self::from_fd(fd)
Self::from_fd_inner(fd)
}

fn from_fd_inner(fd: crate::MockableFd) -> Result<Self, MapError> {
let MapInfo(info) = MapInfo::new_from_fd(fd.as_fd())?;
Ok(Self {
obj: parse_map_info(info, PinningType::None),
fd: MapFd::from_fd(fd),
})
}

/// Loads a map from a file descriptor.
Expand All @@ -672,11 +679,8 @@ impl MapData {
/// This API is intended for cases where you have received a valid BPF FD from some other means.
/// For example, you received an FD over Unix Domain Socket.
pub fn from_fd(fd: OwnedFd) -> Result<Self, MapError> {
let MapInfo(info) = MapInfo::new_from_fd(fd.as_fd())?;
Ok(Self {
obj: parse_map_info(info, PinningType::None),
fd: MapFd::from_fd(fd),
})
let fd = crate::MockableFd::from_fd(fd);
Self::from_fd_inner(fd)
}

/// Allows the map to be pinned to the provided path.
Expand Down
1 change: 0 additions & 1 deletion aya/src/maps/perf/perf_buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ impl PerfBuffer {
});
}

let fd = crate::MockableFd::from_fd(fd);
let perf_buf = Self {
buf: AtomicPtr::new(buf as *mut perf_event_mmap_page),
size,
Expand Down
1 change: 1 addition & 0 deletions aya/src/programs/cgroup_device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ impl CgroupDevice {
.map(|prog_id| {
let prog_fd = bpf_prog_get_fd_by_id(prog_id)?;
let target_fd = target_fd.try_clone_to_owned()?;
let target_fd = crate::MockableFd::from_fd(target_fd);
let prog_fd = ProgramFd(prog_fd);
Ok(CgroupDeviceLink::new(CgroupDeviceLinkInner::ProgAttach(
ProgAttachLink::new(prog_fd, target_fd, BPF_CGROUP_DEVICE),
Expand Down
7 changes: 5 additions & 2 deletions aya/src/programs/extension.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Extension programs.

use std::os::fd::{AsFd as _, BorrowedFd, OwnedFd};
use std::os::fd::{AsFd as _, BorrowedFd};

use object::Endianness;
use thiserror::Error;
Expand Down Expand Up @@ -169,7 +169,10 @@ impl Extension {

/// Retrieves the FD of the BTF object for the provided `prog_fd` and the BTF ID of the function
/// with the name `func_name` within that BTF object.
fn get_btf_info(prog_fd: BorrowedFd<'_>, func_name: &str) -> Result<(OwnedFd, u32), ProgramError> {
fn get_btf_info(
prog_fd: BorrowedFd<'_>,
func_name: &str,
) -> Result<(crate::MockableFd, u32), ProgramError> {
// retrieve program information
let info = sys::bpf_prog_get_info_by_fd(prog_fd, &mut [])?;

Expand Down
12 changes: 7 additions & 5 deletions aya/src/programs/links.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{
collections::{hash_map::Entry, HashMap},
ffi::CString,
io,
os::fd::{AsFd as _, AsRawFd as _, BorrowedFd, OwnedFd, RawFd},
os::fd::{AsFd as _, AsRawFd as _, BorrowedFd, RawFd},
path::{Path, PathBuf},
};

Expand Down Expand Up @@ -107,11 +107,11 @@ pub struct FdLinkId(pub(crate) RawFd);
/// ```
#[derive(Debug)]
pub struct FdLink {
pub(crate) fd: OwnedFd,
pub(crate) fd: crate::MockableFd,
}

impl FdLink {
pub(crate) fn new(fd: OwnedFd) -> Self {
pub(crate) fn new(fd: crate::MockableFd) -> Self {
Self { fd }
}

Expand Down Expand Up @@ -231,14 +231,14 @@ pub struct ProgAttachLinkId(RawFd, RawFd, bpf_attach_type);
#[derive(Debug)]
pub struct ProgAttachLink {
prog_fd: ProgramFd,
target_fd: OwnedFd,
target_fd: crate::MockableFd,
attach_type: bpf_attach_type,
}

impl ProgAttachLink {
pub(crate) fn new(
prog_fd: ProgramFd,
target_fd: OwnedFd,
target_fd: crate::MockableFd,
attach_type: bpf_attach_type,
) -> Self {
Self {
Expand All @@ -258,7 +258,9 @@ impl ProgAttachLink {
// duplicate it prior to attaching it so the new file
// descriptor is closed at drop in case it fails to attach.
let prog_fd = prog_fd.try_clone_to_owned()?;
let prog_fd = crate::MockableFd::from_fd(prog_fd);
let target_fd = target_fd.try_clone_to_owned()?;
let target_fd = crate::MockableFd::from_fd(target_fd);
bpf_prog_attach(prog_fd.as_fd(), target_fd.as_fd(), attach_type)?;

let prog_fd = ProgramFd(prog_fd);
Expand Down
8 changes: 5 additions & 3 deletions aya/src/programs/lirc_mode2.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! Lirc programs.
use std::os::fd::{AsFd, AsRawFd as _, OwnedFd, RawFd};
use std::os::fd::{AsFd, AsRawFd as _, RawFd};

use crate::{
generated::{bpf_attach_type::BPF_LIRC_MODE2, bpf_prog_type::BPF_PROG_TYPE_LIRC_MODE2},
Expand Down Expand Up @@ -67,6 +67,7 @@ impl LircMode2 {
// descriptor is closed at drop in case it fails to attach.
let prog_fd = prog_fd.try_clone()?;
let lircdev_fd = lircdev.as_fd().try_clone_to_owned()?;
let lircdev_fd = crate::MockableFd::from_fd(lircdev_fd);

bpf_prog_attach(prog_fd.as_fd(), lircdev_fd.as_fd(), BPF_LIRC_MODE2)?;

Expand Down Expand Up @@ -98,6 +99,7 @@ impl LircMode2 {
.map(|prog_id| {
let prog_fd = bpf_prog_get_fd_by_id(prog_id)?;
let target_fd = target_fd.try_clone_to_owned()?;
let target_fd = crate::MockableFd::from_fd(target_fd);
let prog_fd = ProgramFd(prog_fd);
Ok(LircLink::new(prog_fd, target_fd))
})
Expand All @@ -113,11 +115,11 @@ pub struct LircLinkId(RawFd, RawFd);
/// An LircMode2 Link
pub struct LircLink {
prog_fd: ProgramFd,
target_fd: OwnedFd,
target_fd: crate::MockableFd,
}

impl LircLink {
pub(crate) fn new(prog_fd: ProgramFd, target_fd: OwnedFd) -> Self {
pub(crate) fn new(prog_fd: ProgramFd, target_fd: crate::MockableFd) -> Self {
Self { prog_fd, target_fd }
}

Expand Down
12 changes: 6 additions & 6 deletions aya/src/programs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ use std::{
ffi::CString,
io,
num::NonZeroU32,
os::fd::{AsFd, AsRawFd, BorrowedFd, OwnedFd},
os::fd::{AsFd, AsRawFd, BorrowedFd},
path::{Path, PathBuf},
sync::Arc,
time::{Duration, SystemTime},
Expand Down Expand Up @@ -224,7 +224,7 @@ pub enum ProgramError {

/// A [`Program`] file descriptor.
#[derive(Debug)]
pub struct ProgramFd(OwnedFd);
pub struct ProgramFd(crate::MockableFd);

impl ProgramFd {
/// Creates a new instance that shares the same underlying file description as [`self`].
Expand Down Expand Up @@ -460,10 +460,10 @@ pub(crate) struct ProgramData<T: Link> {
pub(crate) fd: Option<ProgramFd>,
pub(crate) links: LinkMap<T>,
pub(crate) expected_attach_type: Option<bpf_attach_type>,
pub(crate) attach_btf_obj_fd: Option<OwnedFd>,
pub(crate) attach_btf_obj_fd: Option<crate::MockableFd>,
pub(crate) attach_btf_id: Option<u32>,
pub(crate) attach_prog_fd: Option<ProgramFd>,
pub(crate) btf_fd: Option<Arc<OwnedFd>>,
pub(crate) btf_fd: Option<Arc<crate::MockableFd>>,
pub(crate) verifier_log_level: VerifierLogLevel,
pub(crate) path: Option<PathBuf>,
pub(crate) flags: u32,
Expand All @@ -473,7 +473,7 @@ impl<T: Link> ProgramData<T> {
pub(crate) fn new(
name: Option<String>,
obj: (obj::Program, obj::Function),
btf_fd: Option<Arc<OwnedFd>>,
btf_fd: Option<Arc<crate::MockableFd>>,
verifier_log_level: VerifierLogLevel,
) -> Self {
Self {
Expand All @@ -494,7 +494,7 @@ impl<T: Link> ProgramData<T> {

pub(crate) fn from_bpf_prog_info(
name: Option<String>,
fd: OwnedFd,
fd: crate::MockableFd,
path: &Path,
info: bpf_prog_info,
verifier_log_level: VerifierLogLevel,
Expand Down
10 changes: 5 additions & 5 deletions aya/src/programs/perf_attach.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! Perf attach links.
use std::os::fd::{AsFd as _, AsRawFd as _, BorrowedFd, OwnedFd, RawFd};
use std::os::fd::{AsFd as _, AsRawFd as _, BorrowedFd, RawFd};

use crate::{
generated::bpf_attach_type::BPF_PERF_EVENT,
Expand Down Expand Up @@ -48,7 +48,7 @@ pub struct PerfLinkId(RawFd);
/// The attachment type of PerfEvent programs.
#[derive(Debug)]
pub struct PerfLink {
perf_fd: OwnedFd,
perf_fd: crate::MockableFd,
event: Option<ProbeEvent>,
}

Expand All @@ -72,7 +72,7 @@ impl Link for PerfLink {

pub(crate) fn perf_attach(
prog_fd: BorrowedFd<'_>,
fd: OwnedFd,
fd: crate::MockableFd,
) -> Result<PerfLinkInner, ProgramError> {
if FEATURES.bpf_perf_link() {
let link_fd = bpf_link_create(prog_fd, LinkTarget::Fd(fd.as_fd()), BPF_PERF_EVENT, None, 0)
Expand All @@ -88,15 +88,15 @@ pub(crate) fn perf_attach(

pub(crate) fn perf_attach_debugfs(
prog_fd: BorrowedFd<'_>,
fd: OwnedFd,
fd: crate::MockableFd,
event: ProbeEvent,
) -> Result<PerfLinkInner, ProgramError> {
perf_attach_either(prog_fd, fd, Some(event))
}

fn perf_attach_either(
prog_fd: BorrowedFd<'_>,
fd: OwnedFd,
fd: crate::MockableFd,
event: Option<ProbeEvent>,
) -> Result<PerfLinkInner, ProgramError> {
perf_event_ioctl(fd.as_fd(), PERF_EVENT_IOC_SET_BPF, prog_fd.as_raw_fd()).map_err(
Expand Down
Loading

0 comments on commit e12fcf4

Please sign in to comment.