Skip to content

Commit

Permalink
aya/maps: add pin() api
Browse files Browse the repository at this point in the history
- Adds new `maps_mut()` API to the BpfManager to allow us to iterate though
and pin all of maps at the same time.

- Adds new pin(Path)/unpin(Path) api to Maps so they
can be generically pinned AFTER load.

- Adds macro for pinning explicit map types in aya.
Convert all explicit map types "inner" field to be
pub crate in order to facilitate this.

Signed-off-by: astoycos <astoycos@redhat.com>
  • Loading branch information
astoycos committed Sep 22, 2023
1 parent b0f8c72 commit d4804bd
Show file tree
Hide file tree
Showing 14 changed files with 166 additions and 15 deletions.
25 changes: 24 additions & 1 deletion aya/src/bpf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ impl<'a> BpfLoader<'a> {
if let Some(btf) = obj.fixup_and_sanitize_btf(features)? {
match load_btf(btf.to_bytes(), *verifier_log_level) {
Ok(btf_fd) => Some(Arc::new(btf_fd)),
// Only report an error here if the BTF is truely needed, otherwise proceed without.
// Only report an error here if the BTF is truly needed, otherwise proceed without.
Err(err) => {
for program in obj.programs.values() {
match program.section {
Expand Down Expand Up @@ -837,6 +837,29 @@ impl Bpf {
self.maps.iter().map(|(name, map)| (name.as_str(), map))
}

/// An iterator over all the maps that allows modification.
///
/// # Examples
/// ```no_run
/// # use std::path::Path;
/// # #[derive(thiserror::Error, Debug)]
/// # enum Error {
/// # #[error(transparent)]
/// # Bpf(#[from] aya::BpfError),
/// # #[error(transparent)]
/// # Pin(#[from] aya::pin::PinError)
/// # }
/// # let mut bpf = aya::Bpf::load(&[])?;
/// # let pin_path = Path::new("/tmp/pin_path");
/// for (_, map) in bpf.maps_mut() {
/// map.pin(pin_path)?;
/// }
/// # Ok::<(), Error>(())
/// ```
pub fn maps_mut(&mut self) -> impl Iterator<Item = (&str, &mut Map)> {
self.maps.iter_mut().map(|(name, map)| (name.as_str(), map))
}

/// Returns a reference to the program with the given name.
///
/// You can use this to inspect a program and its properties. To load and attach a program, use
Expand Down
2 changes: 1 addition & 1 deletion aya/src/maps/array/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use crate::{
/// ```
#[doc(alias = "BPF_MAP_TYPE_ARRAY")]
pub struct Array<T, V: Pod> {
inner: T,
pub(crate) inner: T,
_v: PhantomData<V>,
}

Expand Down
2 changes: 1 addition & 1 deletion aya/src/maps/array/per_cpu_array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ use crate::{
/// ```
#[doc(alias = "BPF_MAP_TYPE_PERCPU_ARRAY")]
pub struct PerCpuArray<T, V: Pod> {
inner: T,
pub(crate) inner: T,
_v: PhantomData<V>,
}

Expand Down
2 changes: 1 addition & 1 deletion aya/src/maps/array/program_array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ use crate::{
/// ```
#[doc(alias = "BPF_MAP_TYPE_PROG_ARRAY")]
pub struct ProgramArray<T> {
inner: T,
pub(crate) inner: T,
}

impl<T: Borrow<MapData>> ProgramArray<T> {
Expand Down
2 changes: 1 addition & 1 deletion aya/src/maps/bloom_filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ use crate::{
#[doc(alias = "BPF_MAP_TYPE_BLOOM_FILTER")]
#[derive(Debug)]
pub struct BloomFilter<T, V: Pod> {
inner: T,
pub(crate) inner: T,
_v: PhantomData<V>,
}

Expand Down
2 changes: 1 addition & 1 deletion aya/src/maps/hash_map/hash_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use crate::{
#[doc(alias = "BPF_MAP_TYPE_LRU_HASH")]
#[derive(Debug)]
pub struct HashMap<T, K, V> {
inner: T,
pub(crate) inner: T,
_k: PhantomData<K>,
_v: PhantomData<V>,
}
Expand Down
2 changes: 1 addition & 1 deletion aya/src/maps/hash_map/per_cpu_hash_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ use crate::{
#[doc(alias = "BPF_MAP_TYPE_LRU_PERCPU_HASH")]
#[doc(alias = "BPF_MAP_TYPE_PERCPU_HASH")]
pub struct PerCpuHashMap<T, K: Pod, V: Pod> {
inner: T,
pub(crate) inner: T,
_k: PhantomData<K>,
_v: PhantomData<V>,
}
Expand Down
2 changes: 1 addition & 1 deletion aya/src/maps/lpm_trie.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ use crate::{
#[doc(alias = "BPF_MAP_TYPE_LPM_TRIE")]
#[derive(Debug)]
pub struct LpmTrie<T, K, V> {
inner: T,
pub(crate) inner: T,
_k: PhantomData<K>,
_v: PhantomData<V>,
}
Expand Down
82 changes: 80 additions & 2 deletions aya/src/maps/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
//! versa. Because of that, all map values must be plain old data and therefore
//! implement the [Pod] trait.
use std::{
borrow::BorrowMut,
ffi::CString,
fmt, io,
marker::PhantomData,
Expand Down Expand Up @@ -169,8 +170,8 @@ pub enum MapError {
#[error(transparent)]
SyscallError(#[from] SyscallError),

/// Could not pin map by name
#[error("map `{name:?}` requested pinning by name. pinning failed")]
/// Could not pin map
#[error("map `{name:?}` requested pinning. pinning failed")]
PinError {
/// The map name
name: Option<String>,
Expand Down Expand Up @@ -291,8 +292,85 @@ impl Map {
Self::Unsupported(map) => map.obj.map_type(),
}
}

/// Pins the map to a BPF filesystem.
///
/// When a BPF map is pinned to a BPF filesystem it will remain loaded after
/// Aya has unloaded the program.
/// To remove the map, the file on the BPF filesystem must be removed.
/// Any directories in the the path provided should have been created by the caller.
pub fn pin<P: AsRef<Path>>(&mut self, path: P) -> Result<(), PinError> {
match self {
Self::Array(map) => map.pin(path),
Self::PerCpuArray(map) => map.pin(path),
Self::ProgramArray(map) => map.pin(path),
Self::HashMap(map) => map.pin(path),
Self::LruHashMap(map) => map.pin(path),
Self::PerCpuHashMap(map) => map.pin(path),
Self::PerCpuLruHashMap(map) => map.pin(path),
Self::PerfEventArray(map) => map.pin(path),
Self::SockHash(map) => map.pin(path),
Self::SockMap(map) => map.pin(path),
Self::BloomFilter(map) => map.pin(path),
Self::LpmTrie(map) => map.pin(path),
Self::Stack(map) => map.pin(path),
Self::StackTraceMap(map) => map.pin(path),
Self::Queue(map) => map.pin(path),
Self::Unsupported(map) => map.pin(path),
}
}
}

// Implements map pinning for different map implementations
// TODO add support for PerfEventArrays and AsyncPerfEventArrays
macro_rules! impl_map_pin {
($ty_param:tt {
$($ty:ident),+ $(,)?
}) => {
$(impl_map_pin!(<$ty_param> $ty);)+
};
(
<($($ty_param:ident),*)>
$ty:ident
) => {
impl<T: BorrowMut<MapData>, $($ty_param: Pod),*> $ty<T, $($ty_param),*>
{
/// Pins the map to a BPF filesystem.
///
/// When a BPF map is pinned to a BPF filesystem it will remain loaded after
/// Aya has unloaded the program.
/// To remove the map, the file on the BPF filesystem must be removed.
/// Any directories in the the path provided should have been created by the caller.
pub fn pin<P: AsRef<Path>>(&mut self, path: P) -> Result<(), PinError> {
let data = self.inner.borrow_mut();
data.pin(path)
}
}

};
}

impl_map_pin!(() {
ProgramArray,
SockMap,
StackTraceMap,
});

impl_map_pin!((V) {
Array,
PerCpuArray,
SockHash,
BloomFilter,
Queue,
Stack,
});

impl_map_pin!((K, V) {
HashMap,
PerCpuHashMap,
LpmTrie,
});

// Implements TryFrom<Map> for different map implementations. Different map implementations can be
// constructed from different variants of the map enum. Also, the implementation may have type
// parameters (which we assume all have the bound `Pod` and nothing else).
Expand Down
2 changes: 1 addition & 1 deletion aya/src/maps/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use crate::{
/// ```
#[doc(alias = "BPF_MAP_TYPE_QUEUE")]
pub struct Queue<T, V: Pod> {
inner: T,
pub(crate) inner: T,
_v: PhantomData<V>,
}

Expand Down
2 changes: 1 addition & 1 deletion aya/src/maps/sock/sock_hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ use crate::{
/// ```
#[doc(alias = "BPF_MAP_TYPE_SOCKHASH")]
pub struct SockHash<T, K> {
inner: T,
pub(crate) inner: T,
_k: PhantomData<K>,
}

Expand Down
2 changes: 1 addition & 1 deletion aya/src/maps/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use crate::{
/// ```
#[doc(alias = "BPF_MAP_TYPE_STACK")]
pub struct Stack<T, V: Pod> {
inner: T,
pub(crate) inner: T,
_v: PhantomData<V>,
}

Expand Down
2 changes: 1 addition & 1 deletion aya/src/maps/stack_trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ use crate::{
#[derive(Debug)]
#[doc(alias = "BPF_MAP_TYPE_STACK_TRACE")]
pub struct StackTraceMap<T> {
inner: T,
pub(crate) inner: T,
max_stack_depth: usize,
}

Expand Down
Loading

0 comments on commit d4804bd

Please sign in to comment.