Skip to content

Commit e4c249c

Browse files
committed
Use MockableFd everywhere
Rust 1.80 contains rust-lang/rust#124210, causing tests which we skip under miri to segfault.
1 parent a167554 commit e4c249c

14 files changed

+121
-79
lines changed

aya/src/bpf.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::{
33
collections::{HashMap, HashSet},
44
fs, io,
55
os::{
6-
fd::{AsFd as _, AsRawFd as _, OwnedFd},
6+
fd::{AsFd as _, AsRawFd as _},
77
raw::c_int,
88
},
99
path::{Path, PathBuf},
@@ -1123,7 +1123,10 @@ pub enum EbpfError {
11231123
#[deprecated(since = "0.13.0", note = "use `EbpfError` instead")]
11241124
pub type BpfError = EbpfError;
11251125

1126-
fn load_btf(raw_btf: Vec<u8>, verifier_log_level: VerifierLogLevel) -> Result<OwnedFd, BtfError> {
1126+
fn load_btf(
1127+
raw_btf: Vec<u8>,
1128+
verifier_log_level: VerifierLogLevel,
1129+
) -> Result<crate::MockableFd, BtfError> {
11271130
let (ret, verifier_log) = retry_with_verifier_logs(10, |logger| {
11281131
bpf_load_btf(raw_btf.as_slice(), logger, verifier_log_level)
11291132
});

aya/src/lib.rs

+39-17
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ pub use programs::loaded_programs;
8787
mod sys;
8888
pub mod util;
8989

90-
use std::os::fd::{AsFd, BorrowedFd, OwnedFd};
90+
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, OwnedFd, RawFd};
9191

9292
pub use bpf::*;
9393
pub use obj::btf::{Btf, BtfError};
@@ -123,35 +123,55 @@ impl MockableFd {
123123

124124
#[cfg(test)]
125125
fn from_fd(fd: OwnedFd) -> Self {
126-
Self { fd: Some(fd) }
126+
let fd = Some(fd);
127+
Self { fd }
127128
}
128129

129130
#[cfg(not(test))]
130-
fn try_clone(&self) -> std::io::Result<Self> {
131+
fn inner(&self) -> &OwnedFd {
131132
let Self { fd } = self;
132-
let fd = fd.try_clone()?;
133-
Ok(Self { fd })
133+
fd
134134
}
135135

136136
#[cfg(test)]
137-
fn try_clone(&self) -> std::io::Result<Self> {
137+
fn inner(&self) -> &OwnedFd {
138138
let Self { fd } = self;
139-
let fd = fd.as_ref().map(OwnedFd::try_clone).transpose()?;
140-
Ok(Self { fd })
139+
fd.as_ref().unwrap()
140+
}
141+
142+
fn try_clone(&self) -> std::io::Result<Self> {
143+
let fd = self.inner();
144+
let fd = fd.try_clone()?;
145+
Ok(Self::from_fd(fd))
146+
}
147+
}
148+
149+
impl<T> From<T> for MockableFd
150+
where
151+
OwnedFd: From<T>,
152+
{
153+
fn from(value: T) -> Self {
154+
let fd = OwnedFd::from(value);
155+
Self::from_fd(fd)
141156
}
142157
}
143158

144159
impl AsFd for MockableFd {
145-
#[cfg(not(test))]
146160
fn as_fd(&self) -> BorrowedFd<'_> {
147-
let Self { fd } = self;
148-
fd.as_fd()
161+
self.inner().as_fd()
149162
}
163+
}
150164

151-
#[cfg(test)]
152-
fn as_fd(&self) -> BorrowedFd<'_> {
153-
let Self { fd } = self;
154-
fd.as_ref().unwrap().as_fd()
165+
impl AsRawFd for MockableFd {
166+
fn as_raw_fd(&self) -> RawFd {
167+
self.inner().as_raw_fd()
168+
}
169+
}
170+
171+
impl FromRawFd for MockableFd {
172+
unsafe fn from_raw_fd(fd: RawFd) -> Self {
173+
let fd = OwnedFd::from_raw_fd(fd);
174+
Self::from_fd(fd)
155175
}
156176
}
157177

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

168188
let Self { fd } = self;
169-
if fd.as_ref().unwrap().as_raw_fd() >= Self::mock_signed_fd() {
170-
let fd: OwnedFd = fd.take().unwrap();
189+
let fd = fd.take().unwrap();
190+
if fd.as_raw_fd() < Self::mock_signed_fd() {
191+
std::mem::drop(fd)
192+
} else {
171193
std::mem::forget(fd)
172194
}
173195
}

aya/src/maps/mod.rs

+13-9
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,7 @@ pub struct MapFd {
215215
}
216216

217217
impl MapFd {
218-
fn from_fd(fd: OwnedFd) -> Self {
219-
let fd = crate::MockableFd::from_fd(fd);
218+
fn from_fd(fd: crate::MockableFd) -> Self {
220219
Self { fd }
221220
}
222221

@@ -657,13 +656,21 @@ impl MapData {
657656
io_error,
658657
})?;
659658

660-
Self::from_fd(fd)
659+
Self::from_fd_inner(fd)
661660
}
662661

663662
/// Loads a map from a map id.
664663
pub fn from_id(id: u32) -> Result<Self, MapError> {
665664
let fd = bpf_map_get_fd_by_id(id)?;
666-
Self::from_fd(fd)
665+
Self::from_fd_inner(fd)
666+
}
667+
668+
fn from_fd_inner(fd: crate::MockableFd) -> Result<Self, MapError> {
669+
let MapInfo(info) = MapInfo::new_from_fd(fd.as_fd())?;
670+
Ok(Self {
671+
obj: parse_map_info(info, PinningType::None),
672+
fd: MapFd::from_fd(fd),
673+
})
667674
}
668675

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

682686
/// Allows the map to be pinned to the provided path.

aya/src/maps/perf/perf_buffer.rs

-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,6 @@ impl PerfBuffer {
120120
});
121121
}
122122

123-
let fd = crate::MockableFd::from_fd(fd);
124123
let perf_buf = Self {
125124
buf: AtomicPtr::new(buf as *mut perf_event_mmap_page),
126125
size,

aya/src/programs/cgroup_device.rs

+1
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ impl CgroupDevice {
122122
.map(|prog_id| {
123123
let prog_fd = bpf_prog_get_fd_by_id(prog_id)?;
124124
let target_fd = target_fd.try_clone_to_owned()?;
125+
let target_fd = crate::MockableFd::from_fd(target_fd);
125126
let prog_fd = ProgramFd(prog_fd);
126127
Ok(CgroupDeviceLink::new(CgroupDeviceLinkInner::ProgAttach(
127128
ProgAttachLink::new(prog_fd, target_fd, BPF_CGROUP_DEVICE),

aya/src/programs/extension.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Extension programs.
22
3-
use std::os::fd::{AsFd as _, BorrowedFd, OwnedFd};
3+
use std::os::fd::{AsFd as _, BorrowedFd};
44

55
use object::Endianness;
66
use thiserror::Error;
@@ -169,7 +169,10 @@ impl Extension {
169169

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

aya/src/programs/links.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::{
33
collections::{hash_map::Entry, HashMap},
44
ffi::CString,
55
io,
6-
os::fd::{AsFd as _, AsRawFd as _, BorrowedFd, OwnedFd, RawFd},
6+
os::fd::{AsFd as _, AsRawFd as _, BorrowedFd, RawFd},
77
path::{Path, PathBuf},
88
};
99

@@ -107,11 +107,11 @@ pub struct FdLinkId(pub(crate) RawFd);
107107
/// ```
108108
#[derive(Debug)]
109109
pub struct FdLink {
110-
pub(crate) fd: OwnedFd,
110+
pub(crate) fd: crate::MockableFd,
111111
}
112112

113113
impl FdLink {
114-
pub(crate) fn new(fd: OwnedFd) -> Self {
114+
pub(crate) fn new(fd: crate::MockableFd) -> Self {
115115
Self { fd }
116116
}
117117

@@ -231,14 +231,14 @@ pub struct ProgAttachLinkId(RawFd, RawFd, bpf_attach_type);
231231
#[derive(Debug)]
232232
pub struct ProgAttachLink {
233233
prog_fd: ProgramFd,
234-
target_fd: OwnedFd,
234+
target_fd: crate::MockableFd,
235235
attach_type: bpf_attach_type,
236236
}
237237

238238
impl ProgAttachLink {
239239
pub(crate) fn new(
240240
prog_fd: ProgramFd,
241-
target_fd: OwnedFd,
241+
target_fd: crate::MockableFd,
242242
attach_type: bpf_attach_type,
243243
) -> Self {
244244
Self {
@@ -258,7 +258,9 @@ impl ProgAttachLink {
258258
// duplicate it prior to attaching it so the new file
259259
// descriptor is closed at drop in case it fails to attach.
260260
let prog_fd = prog_fd.try_clone_to_owned()?;
261+
let prog_fd = crate::MockableFd::from_fd(prog_fd);
261262
let target_fd = target_fd.try_clone_to_owned()?;
263+
let target_fd = crate::MockableFd::from_fd(target_fd);
262264
bpf_prog_attach(prog_fd.as_fd(), target_fd.as_fd(), attach_type)?;
263265

264266
let prog_fd = ProgramFd(prog_fd);

aya/src/programs/lirc_mode2.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//! Lirc programs.
2-
use std::os::fd::{AsFd, AsRawFd as _, OwnedFd, RawFd};
2+
use std::os::fd::{AsFd, AsRawFd as _, RawFd};
33

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

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

@@ -98,6 +99,7 @@ impl LircMode2 {
9899
.map(|prog_id| {
99100
let prog_fd = bpf_prog_get_fd_by_id(prog_id)?;
100101
let target_fd = target_fd.try_clone_to_owned()?;
102+
let target_fd = crate::MockableFd::from_fd(target_fd);
101103
let prog_fd = ProgramFd(prog_fd);
102104
Ok(LircLink::new(prog_fd, target_fd))
103105
})
@@ -113,11 +115,11 @@ pub struct LircLinkId(RawFd, RawFd);
113115
/// An LircMode2 Link
114116
pub struct LircLink {
115117
prog_fd: ProgramFd,
116-
target_fd: OwnedFd,
118+
target_fd: crate::MockableFd,
117119
}
118120

119121
impl LircLink {
120-
pub(crate) fn new(prog_fd: ProgramFd, target_fd: OwnedFd) -> Self {
122+
pub(crate) fn new(prog_fd: ProgramFd, target_fd: crate::MockableFd) -> Self {
121123
Self { prog_fd, target_fd }
122124
}
123125

aya/src/programs/mod.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ use std::{
7272
ffi::CString,
7373
io,
7474
num::NonZeroU32,
75-
os::fd::{AsFd, AsRawFd, BorrowedFd, OwnedFd},
75+
os::fd::{AsFd, AsRawFd, BorrowedFd},
7676
path::{Path, PathBuf},
7777
sync::Arc,
7878
time::{Duration, SystemTime},
@@ -224,7 +224,7 @@ pub enum ProgramError {
224224

225225
/// A [`Program`] file descriptor.
226226
#[derive(Debug)]
227-
pub struct ProgramFd(OwnedFd);
227+
pub struct ProgramFd(crate::MockableFd);
228228

229229
impl ProgramFd {
230230
/// Creates a new instance that shares the same underlying file description as [`self`].
@@ -460,10 +460,10 @@ pub(crate) struct ProgramData<T: Link> {
460460
pub(crate) fd: Option<ProgramFd>,
461461
pub(crate) links: LinkMap<T>,
462462
pub(crate) expected_attach_type: Option<bpf_attach_type>,
463-
pub(crate) attach_btf_obj_fd: Option<OwnedFd>,
463+
pub(crate) attach_btf_obj_fd: Option<crate::MockableFd>,
464464
pub(crate) attach_btf_id: Option<u32>,
465465
pub(crate) attach_prog_fd: Option<ProgramFd>,
466-
pub(crate) btf_fd: Option<Arc<OwnedFd>>,
466+
pub(crate) btf_fd: Option<Arc<crate::MockableFd>>,
467467
pub(crate) verifier_log_level: VerifierLogLevel,
468468
pub(crate) path: Option<PathBuf>,
469469
pub(crate) flags: u32,
@@ -473,7 +473,7 @@ impl<T: Link> ProgramData<T> {
473473
pub(crate) fn new(
474474
name: Option<String>,
475475
obj: (obj::Program, obj::Function),
476-
btf_fd: Option<Arc<OwnedFd>>,
476+
btf_fd: Option<Arc<crate::MockableFd>>,
477477
verifier_log_level: VerifierLogLevel,
478478
) -> Self {
479479
Self {
@@ -494,7 +494,7 @@ impl<T: Link> ProgramData<T> {
494494

495495
pub(crate) fn from_bpf_prog_info(
496496
name: Option<String>,
497-
fd: OwnedFd,
497+
fd: crate::MockableFd,
498498
path: &Path,
499499
info: bpf_prog_info,
500500
verifier_log_level: VerifierLogLevel,

aya/src/programs/perf_attach.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//! Perf attach links.
2-
use std::os::fd::{AsFd as _, AsRawFd as _, BorrowedFd, OwnedFd, RawFd};
2+
use std::os::fd::{AsFd as _, AsRawFd as _, BorrowedFd, RawFd};
33

44
use crate::{
55
generated::bpf_attach_type::BPF_PERF_EVENT,
@@ -48,7 +48,7 @@ pub struct PerfLinkId(RawFd);
4848
/// The attachment type of PerfEvent programs.
4949
#[derive(Debug)]
5050
pub struct PerfLink {
51-
perf_fd: OwnedFd,
51+
perf_fd: crate::MockableFd,
5252
event: Option<ProbeEvent>,
5353
}
5454

@@ -72,7 +72,7 @@ impl Link for PerfLink {
7272

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

8989
pub(crate) fn perf_attach_debugfs(
9090
prog_fd: BorrowedFd<'_>,
91-
fd: OwnedFd,
91+
fd: crate::MockableFd,
9292
event: ProbeEvent,
9393
) -> Result<PerfLinkInner, ProgramError> {
9494
perf_attach_either(prog_fd, fd, Some(event))
9595
}
9696

9797
fn perf_attach_either(
9898
prog_fd: BorrowedFd<'_>,
99-
fd: OwnedFd,
99+
fd: crate::MockableFd,
100100
event: Option<ProbeEvent>,
101101
) -> Result<PerfLinkInner, ProgramError> {
102102
perf_event_ioctl(fd.as_fd(), PERF_EVENT_IOC_SET_BPF, prog_fd.as_raw_fd()).map_err(

0 commit comments

Comments
 (0)