From a599fb95a47b6b4e05d5cd442db8ab05b40c807e Mon Sep 17 00:00:00 2001 From: Omri Steiner Date: Fri, 2 May 2025 17:30:04 +0200 Subject: [PATCH] aya: move Mmap struct to a utility module --- aya/src/maps/mod.rs | 62 ++------------------------------ aya/src/maps/perf/perf_buffer.rs | 2 +- aya/src/maps/ring_buf.rs | 4 +-- aya/src/util.rs | 2 ++ aya/src/util/mmap.rs | 62 ++++++++++++++++++++++++++++++++ 5 files changed, 69 insertions(+), 63 deletions(-) create mode 100644 aya/src/util/mmap.rs diff --git a/aya/src/maps/mod.rs b/aya/src/maps/mod.rs index 849b14bc..21bb2b4c 100644 --- a/aya/src/maps/mod.rs +++ b/aya/src/maps/mod.rs @@ -60,9 +60,7 @@ use std::{ }; use aya_obj::{EbpfSectionKind, InvalidTypeBinding, generated::bpf_map_type, parse_map_info}; -use libc::{ - MAP_FAILED, RLIM_INFINITY, RLIMIT_MEMLOCK, c_int, c_void, getrlimit, off_t, rlim_t, rlimit, -}; +use libc::{RLIM_INFINITY, RLIMIT_MEMLOCK, getrlimit, rlim_t, rlimit}; use log::warn; use thiserror::Error; @@ -71,7 +69,7 @@ use crate::{ pin::PinError, sys::{ SyscallError, bpf_create_map, bpf_get_object, bpf_map_freeze, bpf_map_get_fd_by_id, - bpf_map_get_next_key, bpf_map_update_elem_ptr, bpf_pin_object, mmap, munmap, + bpf_map_get_next_key, bpf_map_update_elem_ptr, bpf_pin_object, }, util::{KernelVersion, nr_cpus}, }; @@ -944,62 +942,6 @@ impl Deref for PerCpuValues { } } -// MMap corresponds to a memory-mapped region. -// -// The data is unmapped in Drop. -#[cfg_attr(test, derive(Debug))] -struct MMap { - ptr: ptr::NonNull, - len: usize, -} - -// Needed because NonNull is !Send and !Sync out of caution that the data -// might be aliased unsafely. -unsafe impl Send for MMap {} -unsafe impl Sync for MMap {} - -impl MMap { - fn new( - fd: BorrowedFd<'_>, - len: usize, - prot: c_int, - flags: c_int, - offset: off_t, - ) -> Result { - match unsafe { mmap(ptr::null_mut(), len, prot, flags, fd, offset) } { - MAP_FAILED => Err(SyscallError { - call: "mmap", - io_error: io::Error::last_os_error(), - }), - ptr => { - let ptr = ptr::NonNull::new(ptr).ok_or( - // This should never happen, but to be paranoid, and so we never need to talk - // about a null pointer, we check it anyway. - SyscallError { - call: "mmap", - io_error: io::Error::other("mmap returned null pointer"), - }, - )?; - Ok(Self { ptr, len }) - } - } - } -} - -impl AsRef<[u8]> for MMap { - fn as_ref(&self) -> &[u8] { - let Self { ptr, len } = self; - unsafe { std::slice::from_raw_parts(ptr.as_ptr().cast(), *len) } - } -} - -impl Drop for MMap { - fn drop(&mut self) { - let Self { ptr, len } = *self; - unsafe { munmap(ptr.as_ptr(), len) }; - } -} - #[cfg(test)] mod test_utils { use aya_obj::{ diff --git a/aya/src/maps/perf/perf_buffer.rs b/aya/src/maps/perf/perf_buffer.rs index 27554ac7..d39f6a3f 100644 --- a/aya/src/maps/perf/perf_buffer.rs +++ b/aya/src/maps/perf/perf_buffer.rs @@ -14,8 +14,8 @@ use libc::{MAP_SHARED, PROT_READ, PROT_WRITE}; use thiserror::Error; use crate::{ - maps::MMap, sys::{PerfEventIoctlRequest, SyscallError, perf_event_ioctl, perf_event_open_bpf}, + util::mmap::MMap, }; /// Perf buffer error. diff --git a/aya/src/maps/ring_buf.rs b/aya/src/maps/ring_buf.rs index e455329f..bc9143f8 100644 --- a/aya/src/maps/ring_buf.rs +++ b/aya/src/maps/ring_buf.rs @@ -17,8 +17,8 @@ use aya_obj::generated::{BPF_RINGBUF_BUSY_BIT, BPF_RINGBUF_DISCARD_BIT, BPF_RING use libc::{MAP_SHARED, PROT_READ, PROT_WRITE}; use crate::{ - maps::{MMap, MapData, MapError}, - util::page_size, + maps::{MapData, MapError}, + util::{mmap::MMap, page_size}, }; /// A map that can be used to receive events from eBPF programs. diff --git a/aya/src/util.rs b/aya/src/util.rs index cd3b7ac6..d7717d62 100644 --- a/aya/src/util.rs +++ b/aya/src/util.rs @@ -18,6 +18,8 @@ use log::warn; use crate::Pod; +pub mod mmap; + /// Represents a kernel version, in major.minor.release version. // Adapted from https://docs.rs/procfs/latest/procfs/sys/kernel/struct.Version.html. #[derive(Debug, Copy, Clone, Eq, PartialEq, PartialOrd)] diff --git a/aya/src/util/mmap.rs b/aya/src/util/mmap.rs new file mode 100644 index 00000000..1b340b03 --- /dev/null +++ b/aya/src/util/mmap.rs @@ -0,0 +1,62 @@ +//! Safe wrapper around memory-mapped files. + +use libc::{MAP_FAILED, c_int, c_void, off_t}; +use std::{io, os::fd::BorrowedFd, ptr}; + +use crate::sys::{SyscallError, mmap, munmap}; + +// MMap corresponds to a memory-mapped region. +// +// The data is unmapped in Drop. +#[cfg_attr(test, derive(Debug))] +pub(crate) struct MMap { + pub(crate) ptr: ptr::NonNull, + pub(crate) len: usize, +} + +// Needed because NonNull is !Send and !Sync out of caution that the data +// might be aliased unsafely. +unsafe impl Send for MMap {} +unsafe impl Sync for MMap {} + +impl MMap { + pub(crate) fn new( + fd: BorrowedFd<'_>, + len: usize, + prot: c_int, + flags: c_int, + offset: off_t, + ) -> Result { + match unsafe { mmap(ptr::null_mut(), len, prot, flags, fd, offset) } { + MAP_FAILED => Err(SyscallError { + call: "mmap", + io_error: io::Error::last_os_error(), + }), + ptr => { + let ptr = ptr::NonNull::new(ptr).ok_or( + // This should never happen, but to be paranoid, and so we never need to talk + // about a null pointer, we check it anyway. + SyscallError { + call: "mmap", + io_error: io::Error::other("mmap returned null pointer"), + }, + )?; + Ok(Self { ptr, len }) + } + } + } +} + +impl AsRef<[u8]> for MMap { + fn as_ref(&self) -> &[u8] { + let Self { ptr, len } = self; + unsafe { std::slice::from_raw_parts(ptr.as_ptr().cast(), *len) } + } +} + +impl Drop for MMap { + fn drop(&mut self) { + let Self { ptr, len } = *self; + unsafe { munmap(ptr.as_ptr(), len) }; + } +}