Skip to content

Commit

Permalink
s/MiriSafeFd/MockableFd/
Browse files Browse the repository at this point in the history
The need for this type isn't specific to Miri; it is necessary on
toolchains containing rust-lang/rust#124210 - it
just so happens that today this is nightly only, and so is Miri.
  • Loading branch information
tamird committed May 2, 2024
1 parent f448b3a commit 96ef6d4
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 32 deletions.
32 changes: 16 additions & 16 deletions aya/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,65 +97,65 @@ pub use object::Endianness;
pub use sys::netlink_set_link_up;

// See https://github.com/rust-lang/rust/pull/124210; this structure exists to avoid crashing the
// process when we try to close a fake file descriptor in Miri.
// process when we try to close a fake file descriptor.
#[derive(Debug)]
struct MiriSafeFd {
#[cfg(not(miri))]
struct MockableFd {
#[cfg(not(test))]
fd: OwnedFd,
#[cfg(miri)]
#[cfg(test)]
fd: Option<OwnedFd>,
}

impl MiriSafeFd {
#[cfg(any(test, miri))]
impl MockableFd {
#[cfg(test)]
const MOCK_FD: u16 = 1337;

#[cfg(not(miri))]
#[cfg(not(test))]
fn from_fd(fd: OwnedFd) -> Self {
Self { fd }
}

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

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

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

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

#[cfg(miri)]
#[cfg(test)]
fn as_fd(&self) -> BorrowedFd<'_> {
let Self { fd } = self;
fd.as_ref().unwrap().as_fd()
}
}

impl Drop for MiriSafeFd {
#[cfg(not(miri))]
impl Drop for MockableFd {
#[cfg(not(test))]
fn drop(&mut self) {
// Intentional no-op.
}

#[cfg(miri)]
#[cfg(test)]
fn drop(&mut self) {
use std::os::fd::AsRawFd as _;

Expand Down
16 changes: 8 additions & 8 deletions aya/src/maps/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,12 +211,12 @@ impl From<InvalidMapTypeError> for MapError {
/// A map file descriptor.
#[derive(Debug)]
pub struct MapFd {
fd: crate::MiriSafeFd,
fd: crate::MockableFd,
}

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

Expand Down Expand Up @@ -1052,7 +1052,7 @@ mod test_utils {
Syscall::Ebpf {
cmd: bpf_cmd::BPF_MAP_CREATE,
..
} => Ok(crate::MiriSafeFd::MOCK_FD.into()),
} => Ok(crate::MockableFd::MOCK_FD.into()),
call => panic!("unexpected syscall {:?}", call),
});
MapData::create(obj, "foo", None).unwrap()
Expand Down Expand Up @@ -1103,15 +1103,15 @@ mod tests {
unsafe { attr.__bindgen_anon_6.__bindgen_anon_1.map_id },
1234
);
Ok(crate::MiriSafeFd::MOCK_FD.into())
Ok(crate::MockableFd::MOCK_FD.into())
}
Syscall::Ebpf {
cmd: bpf_cmd::BPF_OBJ_GET_INFO_BY_FD,
attr,
} => {
assert_eq!(
unsafe { attr.info.bpf_fd },
crate::MiriSafeFd::MOCK_FD.into()
crate::MockableFd::MOCK_FD.into()
);
Ok(0)
}
Expand All @@ -1123,7 +1123,7 @@ mod tests {
Ok(MapData {
obj: _,
fd,
}) => assert_eq!(fd.as_fd().as_raw_fd(), crate::MiriSafeFd::MOCK_FD.into())
}) => assert_eq!(fd.as_fd().as_raw_fd(), crate::MockableFd::MOCK_FD.into())
);
}

Expand All @@ -1133,7 +1133,7 @@ mod tests {
Syscall::Ebpf {
cmd: bpf_cmd::BPF_MAP_CREATE,
..
} => Ok(crate::MiriSafeFd::MOCK_FD.into()),
} => Ok(crate::MockableFd::MOCK_FD.into()),
_ => Err((-1, io::Error::from_raw_os_error(EFAULT))),
});

Expand All @@ -1142,7 +1142,7 @@ mod tests {
Ok(MapData {
obj: _,
fd,
}) => assert_eq!(fd.as_fd().as_raw_fd(), crate::MiriSafeFd::MOCK_FD.into())
}) => assert_eq!(fd.as_fd().as_raw_fd(), crate::MockableFd::MOCK_FD.into())
);
}

Expand Down
6 changes: 3 additions & 3 deletions aya/src/maps/perf/perf_buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ pub(crate) struct PerfBuffer {
buf: AtomicPtr<perf_event_mmap_page>,
size: usize,
page_size: usize,
fd: crate::MiriSafeFd,
fd: crate::MockableFd,
}

impl PerfBuffer {
Expand Down Expand Up @@ -120,7 +120,7 @@ impl PerfBuffer {
});
}

let fd = crate::MiriSafeFd::from_fd(fd);
let fd = crate::MockableFd::from_fd(fd);
let perf_buf = Self {
buf: AtomicPtr::new(buf as *mut perf_event_mmap_page),
size,
Expand Down Expand Up @@ -303,7 +303,7 @@ mod tests {
fn fake_mmap(buf: &MMappedBuf) {
override_syscall(|call| match call {
Syscall::PerfEventOpen { .. } | Syscall::PerfEventIoctl { .. } => {
Ok(crate::MiriSafeFd::MOCK_FD.into())
Ok(crate::MockableFd::MOCK_FD.into())
}
call => panic!("unexpected syscall: {:?}", call),
});
Expand Down
10 changes: 5 additions & 5 deletions aya/src/sys/bpf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -730,7 +730,7 @@ pub(crate) fn is_perf_link_supported() -> bool {
u.prog_type = bpf_prog_type::BPF_PROG_TYPE_TRACEPOINT as u32;

if let Ok(fd) = bpf_prog_load(&mut attr) {
let fd = crate::MiriSafeFd::from_fd(fd);
let fd = crate::MockableFd::from_fd(fd);
let fd = fd.as_fd();
matches!(
// Uses an invalid target FD so we get EBADF if supported.
Expand Down Expand Up @@ -830,7 +830,7 @@ pub(crate) fn is_prog_id_supported(map_type: bpf_map_type) -> bool {

// SAFETY: BPF_MAP_CREATE returns a new file descriptor.
let fd = unsafe { fd_sys_bpf(bpf_cmd::BPF_MAP_CREATE, &mut attr) };
let fd = fd.map(crate::MiriSafeFd::from_fd);
let fd = fd.map(crate::MockableFd::from_fd);
fd.is_ok()
}

Expand Down Expand Up @@ -1103,7 +1103,7 @@ mod tests {
cmd: bpf_cmd::BPF_LINK_CREATE,
..
} => Err((-1, io::Error::from_raw_os_error(EBADF))),
_ => Ok(crate::MiriSafeFd::MOCK_FD.into()),
_ => Ok(crate::MockableFd::MOCK_FD.into()),
});
let supported = is_perf_link_supported();
assert!(supported);
Expand All @@ -1113,15 +1113,15 @@ mod tests {
cmd: bpf_cmd::BPF_LINK_CREATE,
..
} => Err((-1, io::Error::from_raw_os_error(EINVAL))),
_ => Ok(crate::MiriSafeFd::MOCK_FD.into()),
_ => Ok(crate::MockableFd::MOCK_FD.into()),
});
let supported = is_perf_link_supported();
assert!(!supported);
}

#[test]
fn test_prog_id_supported() {
override_syscall(|_call| Ok(crate::MiriSafeFd::MOCK_FD.into()));
override_syscall(|_call| Ok(crate::MockableFd::MOCK_FD.into()));

// Ensure that the three map types we can check are accepted
let supported = is_prog_id_supported(bpf_map_type::BPF_MAP_TYPE_CPUMAP);
Expand Down

0 comments on commit 96ef6d4

Please sign in to comment.