aya: move Mmap struct to aya::util

reviewable/pr1264/r8
Omri Steiner 2 weeks ago committed by Tamir Duberstein
parent 583709f6a0
commit 3aded0e0a5

@ -60,9 +60,7 @@ use std::{
}; };
use aya_obj::{EbpfSectionKind, InvalidTypeBinding, generated::bpf_map_type, parse_map_info}; use aya_obj::{EbpfSectionKind, InvalidTypeBinding, generated::bpf_map_type, parse_map_info};
use libc::{ use libc::{RLIM_INFINITY, RLIMIT_MEMLOCK, getrlimit, rlim_t, rlimit};
MAP_FAILED, RLIM_INFINITY, RLIMIT_MEMLOCK, c_int, c_void, getrlimit, off_t, rlim_t, rlimit,
};
use log::warn; use log::warn;
use thiserror::Error; use thiserror::Error;
@ -71,7 +69,7 @@ use crate::{
pin::PinError, pin::PinError,
sys::{ sys::{
SyscallError, bpf_create_map, bpf_get_object, bpf_map_freeze, bpf_map_get_fd_by_id, 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}, util::{KernelVersion, nr_cpus},
}; };
@ -944,62 +942,6 @@ impl<T: Pod> Deref for PerCpuValues<T> {
} }
} }
// MMap corresponds to a memory-mapped region.
//
// The data is unmapped in Drop.
#[cfg_attr(test, derive(Debug))]
struct MMap {
ptr: ptr::NonNull<c_void>,
len: usize,
}
// Needed because NonNull<T> 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<Self, SyscallError> {
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)] #[cfg(test)]
mod test_utils { mod test_utils {
use aya_obj::{ use aya_obj::{

@ -14,8 +14,8 @@ use libc::{MAP_SHARED, PROT_READ, PROT_WRITE};
use thiserror::Error; use thiserror::Error;
use crate::{ use crate::{
maps::MMap,
sys::{PerfEventIoctlRequest, SyscallError, perf_event_ioctl, perf_event_open_bpf}, sys::{PerfEventIoctlRequest, SyscallError, perf_event_ioctl, perf_event_open_bpf},
util::MMap,
}; };
/// Perf buffer error. /// Perf buffer error.
@ -126,7 +126,7 @@ impl PerfBuffer {
} }
fn buf(&self) -> ptr::NonNull<perf_event_mmap_page> { fn buf(&self) -> ptr::NonNull<perf_event_mmap_page> {
self.mmap.ptr.cast() self.mmap.ptr().cast()
} }
pub(crate) fn readable(&self) -> bool { pub(crate) fn readable(&self) -> bool {

@ -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 libc::{MAP_SHARED, PROT_READ, PROT_WRITE};
use crate::{ use crate::{
maps::{MMap, MapData, MapError}, maps::{MapData, MapError},
util::page_size, util::{MMap, page_size},
}; };
/// A map that can be used to receive events from eBPF programs. /// A map that can be used to receive events from eBPF programs.
@ -201,10 +201,7 @@ impl ConsumerMetadata {
impl AsRef<AtomicUsize> for ConsumerMetadata { impl AsRef<AtomicUsize> for ConsumerMetadata {
fn as_ref(&self) -> &AtomicUsize { fn as_ref(&self) -> &AtomicUsize {
let Self { unsafe { self.mmap.ptr().cast::<AtomicUsize>().as_ref() }
mmap: MMap { ptr, .. },
} = self;
unsafe { ptr.cast::<AtomicUsize>().as_ref() }
} }
} }
@ -318,7 +315,7 @@ impl ProducerData {
ref mut pos_cache, ref mut pos_cache,
ref mut mask, ref mut mask,
} = self; } = self;
let pos = unsafe { mmap.ptr.cast().as_ref() }; let pos = unsafe { mmap.ptr().cast().as_ref() };
let mmap_data = mmap.as_ref(); let mmap_data = mmap.as_ref();
let data_pages = mmap_data.get(*data_offset..).unwrap_or_else(|| { let data_pages = mmap_data.get(*data_offset..).unwrap_or_else(|| {
panic!( panic!(

@ -8,15 +8,21 @@ use std::{
io::{self, BufRead, BufReader}, io::{self, BufRead, BufReader},
mem, mem,
num::ParseIntError, num::ParseIntError,
slice, os::fd::BorrowedFd,
ptr, slice,
str::{FromStr, Utf8Error}, str::{FromStr, Utf8Error},
}; };
use aya_obj::generated::{TC_H_MAJ_MASK, TC_H_MIN_MASK}; use aya_obj::generated::{TC_H_MAJ_MASK, TC_H_MIN_MASK};
use libc::{_SC_PAGESIZE, if_nametoindex, sysconf, uname, utsname}; use libc::{
_SC_PAGESIZE, MAP_FAILED, c_int, c_void, if_nametoindex, off_t, sysconf, uname, utsname,
};
use log::warn; use log::warn;
use crate::Pod; use crate::{
Pod,
sys::{SyscallError, mmap, munmap},
};
/// Represents a kernel version, in major.minor.release version. /// Represents a kernel version, in major.minor.release version.
// Adapted from https://docs.rs/procfs/latest/procfs/sys/kernel/struct.Version.html. // Adapted from https://docs.rs/procfs/latest/procfs/sys/kernel/struct.Version.html.
@ -431,6 +437,66 @@ pub(crate) fn bytes_of_bpf_name(bpf_name: &[core::ffi::c_char; 16]) -> &[u8] {
unsafe { slice::from_raw_parts(bpf_name.as_ptr() as *const _, length) } unsafe { slice::from_raw_parts(bpf_name.as_ptr() as *const _, length) }
} }
// MMap corresponds to a memory-mapped region.
//
// The data is unmapped in Drop.
#[cfg_attr(test, derive(Debug))]
pub(crate) struct MMap {
ptr: ptr::NonNull<c_void>,
len: usize,
}
// Needed because NonNull<T> 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<Self, SyscallError> {
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 })
}
}
}
pub(crate) fn ptr(&self) -> ptr::NonNull<c_void> {
self.ptr
}
}
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)] #[cfg(test)]
mod tests { mod tests {
use assert_matches::assert_matches; use assert_matches::assert_matches;

Loading…
Cancel
Save