From 0bf97eba64b44835300d8291cd4f78c220c3ad48 Mon Sep 17 00:00:00 2001 From: astoycos Date: Thu, 21 Sep 2023 13:50:21 -0400 Subject: [PATCH 1/3] aya/maps: fix libbpf_pin_by_name Aligns with libbpf for the special LIBBPF_PIN_BY_NAME map flag. Specifically if the flag is provided without a pin path default to "/sys/fs/bpf". Signed-off-by: astoycos --- aya/src/bpf.rs | 13 +++++++------ aya/src/maps/mod.rs | 3 +-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/aya/src/bpf.rs b/aya/src/bpf.rs index 2272bc524..7e03a12ac 100644 --- a/aya/src/bpf.rs +++ b/aya/src/bpf.rs @@ -492,8 +492,13 @@ impl<'a> BpfLoader<'a> { let mut map = match obj.pinning() { PinningType::None => MapData::create(obj, &name, btf_fd)?, PinningType::ByName => { - let path = map_pin_path.as_ref().ok_or(BpfError::NoPinPath)?; - MapData::create_pinned(path, obj, &name, btf_fd)? + // pin maps in /sys/fs/bpf by default to align with libbpf + // behavior https://github.com/libbpf/libbpf/blob/v1.2.2/src/libbpf.c#L2161. + let path = map_pin_path + .as_deref() + .unwrap_or_else(|| Path::new("/sys/fs/bpf")); + + MapData::create_pinned_by_name(path, obj, &name, btf_fd)? } }; map.finalize()?; @@ -951,10 +956,6 @@ pub enum BpfError { error: io::Error, }, - /// Pinning requested but no path provided - #[error("pinning requested but no path provided")] - NoPinPath, - /// Unexpected pinning type #[error("unexpected pinning type {name}")] UnexpectedPinningType { diff --git a/aya/src/maps/mod.rs b/aya/src/maps/mod.rs index 849714192..af9ec8681 100644 --- a/aya/src/maps/mod.rs +++ b/aya/src/maps/mod.rs @@ -461,7 +461,7 @@ impl MapData { Ok(Self { obj, fd }) } - pub(crate) fn create_pinned>( + pub(crate) fn create_pinned_by_name>( path: P, obj: obj::Map, name: &str, @@ -490,7 +490,6 @@ impl MapData { } Err(_) => { let mut map = Self::create(obj, name, btf_fd)?; - let path = path.join(name); map.pin(&path).map_err(|error| MapError::PinError { name: Some(name.into()), error, From 7b71c7e1cd8d6948764d02afb0279151c6eae437 Mon Sep 17 00:00:00 2001 From: astoycos Date: Fri, 22 Sep 2023 10:35:19 -0400 Subject: [PATCH 2/3] aya/maps: add pin() api - 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 --- aya/src/bpf.rs | 25 ++++++- aya/src/maps/array/array.rs | 2 +- aya/src/maps/array/per_cpu_array.rs | 2 +- aya/src/maps/array/program_array.rs | 2 +- aya/src/maps/bloom_filter.rs | 2 +- aya/src/maps/hash_map/hash_map.rs | 2 +- aya/src/maps/hash_map/per_cpu_hash_map.rs | 2 +- aya/src/maps/lpm_trie.rs | 2 +- aya/src/maps/mod.rs | 86 ++++++++++++++++++++++- aya/src/maps/queue.rs | 2 +- aya/src/maps/sock/sock_hash.rs | 2 +- aya/src/maps/stack.rs | 2 +- aya/src/maps/stack_trace.rs | 2 +- aya/src/maps/xdp/cpu_map.rs | 2 +- aya/src/maps/xdp/dev_map.rs | 2 +- aya/src/maps/xdp/dev_map_hash.rs | 2 +- aya/src/maps/xdp/xsk_map.rs | 2 +- xtask/public-api/aya.txt | 68 +++++++++++++++++- 18 files changed, 190 insertions(+), 19 deletions(-) diff --git a/aya/src/bpf.rs b/aya/src/bpf.rs index 7e03a12ac..571621637 100644 --- a/aya/src/bpf.rs +++ b/aya/src/bpf.rs @@ -398,7 +398,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 { @@ -861,6 +861,29 @@ impl Bpf { self.maps.iter().map(|(name, map)| (name.as_str(), map)) } + /// A mutable iterator over all the maps. + /// + /// # 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 { + 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 diff --git a/aya/src/maps/array/array.rs b/aya/src/maps/array/array.rs index 5d137d057..9fdc91e3d 100644 --- a/aya/src/maps/array/array.rs +++ b/aya/src/maps/array/array.rs @@ -31,7 +31,7 @@ use crate::{ /// ``` #[doc(alias = "BPF_MAP_TYPE_ARRAY")] pub struct Array { - inner: T, + pub(crate) inner: T, _v: PhantomData, } diff --git a/aya/src/maps/array/per_cpu_array.rs b/aya/src/maps/array/per_cpu_array.rs index f384b7133..9c261f0c8 100644 --- a/aya/src/maps/array/per_cpu_array.rs +++ b/aya/src/maps/array/per_cpu_array.rs @@ -50,7 +50,7 @@ use crate::{ /// ``` #[doc(alias = "BPF_MAP_TYPE_PERCPU_ARRAY")] pub struct PerCpuArray { - inner: T, + pub(crate) inner: T, _v: PhantomData, } diff --git a/aya/src/maps/array/program_array.rs b/aya/src/maps/array/program_array.rs index 48bb6b9d7..513bf77f3 100644 --- a/aya/src/maps/array/program_array.rs +++ b/aya/src/maps/array/program_array.rs @@ -48,7 +48,7 @@ use crate::{ /// ``` #[doc(alias = "BPF_MAP_TYPE_PROG_ARRAY")] pub struct ProgramArray { - inner: T, + pub(crate) inner: T, } impl> ProgramArray { diff --git a/aya/src/maps/bloom_filter.rs b/aya/src/maps/bloom_filter.rs index d038e35f3..5c547fb09 100644 --- a/aya/src/maps/bloom_filter.rs +++ b/aya/src/maps/bloom_filter.rs @@ -36,7 +36,7 @@ use crate::{ #[doc(alias = "BPF_MAP_TYPE_BLOOM_FILTER")] #[derive(Debug)] pub struct BloomFilter { - inner: T, + pub(crate) inner: T, _v: PhantomData, } diff --git a/aya/src/maps/hash_map/hash_map.rs b/aya/src/maps/hash_map/hash_map.rs index bfc968456..72c81b958 100644 --- a/aya/src/maps/hash_map/hash_map.rs +++ b/aya/src/maps/hash_map/hash_map.rs @@ -34,7 +34,7 @@ use crate::{ #[doc(alias = "BPF_MAP_TYPE_LRU_HASH")] #[derive(Debug)] pub struct HashMap { - inner: T, + pub(crate) inner: T, _k: PhantomData, _v: PhantomData, } diff --git a/aya/src/maps/hash_map/per_cpu_hash_map.rs b/aya/src/maps/hash_map/per_cpu_hash_map.rs index b19853907..fe404ce0e 100644 --- a/aya/src/maps/hash_map/per_cpu_hash_map.rs +++ b/aya/src/maps/hash_map/per_cpu_hash_map.rs @@ -43,7 +43,7 @@ use crate::{ #[doc(alias = "BPF_MAP_TYPE_LRU_PERCPU_HASH")] #[doc(alias = "BPF_MAP_TYPE_PERCPU_HASH")] pub struct PerCpuHashMap { - inner: T, + pub(crate) inner: T, _k: PhantomData, _v: PhantomData, } diff --git a/aya/src/maps/lpm_trie.rs b/aya/src/maps/lpm_trie.rs index 181a2f57a..139a9cb9e 100644 --- a/aya/src/maps/lpm_trie.rs +++ b/aya/src/maps/lpm_trie.rs @@ -48,7 +48,7 @@ use crate::{ #[doc(alias = "BPF_MAP_TYPE_LPM_TRIE")] #[derive(Debug)] pub struct LpmTrie { - inner: T, + pub(crate) inner: T, _k: PhantomData, _v: PhantomData, } diff --git a/aya/src/maps/mod.rs b/aya/src/maps/mod.rs index af9ec8681..771486c2d 100644 --- a/aya/src/maps/mod.rs +++ b/aya/src/maps/mod.rs @@ -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, @@ -170,8 +171,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, @@ -308,8 +309,89 @@ impl Map { Self::Unsupported(map) => map.obj.map_type(), } } + + /// Pins the map to a BPF filesystem. + /// + /// When a map is pinned it will remain loaded until the corresponding file + /// is deleted. All parent directories in the given `path` must already exist. + pub fn pin>(&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::CpuMap(map) => map.pin(path), + Self::DevMap(map) => map.pin(path), + Self::DevMapHash(map) => map.pin(path), + Self::XskMap(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, $($ty_param: Pod),*> $ty + { + /// Pins the map to a BPF filesystem. + /// + /// When a map is pinned it will remain loaded until the corresponding file + /// is deleted. All parent directories in the given `path` must already exist. + pub fn pin>(&mut self, path: P) -> Result<(), PinError> { + let data = self.inner.borrow_mut(); + data.pin(path) + } + } + + }; } +impl_map_pin!(() { + ProgramArray, + SockMap, + StackTraceMap, + CpuMap, + DevMap, + DevMapHash, + XskMap, +}); + +impl_map_pin!((V) { + Array, + PerCpuArray, + SockHash, + BloomFilter, + Queue, + Stack, +}); + +impl_map_pin!((K, V) { + HashMap, + PerCpuHashMap, + LpmTrie, +}); + // Implements TryFrom 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). diff --git a/aya/src/maps/queue.rs b/aya/src/maps/queue.rs index 31c446338..b9177b246 100644 --- a/aya/src/maps/queue.rs +++ b/aya/src/maps/queue.rs @@ -30,7 +30,7 @@ use crate::{ /// ``` #[doc(alias = "BPF_MAP_TYPE_QUEUE")] pub struct Queue { - inner: T, + pub(crate) inner: T, _v: PhantomData, } diff --git a/aya/src/maps/sock/sock_hash.rs b/aya/src/maps/sock/sock_hash.rs index 99d0f871a..e3074be85 100644 --- a/aya/src/maps/sock/sock_hash.rs +++ b/aya/src/maps/sock/sock_hash.rs @@ -65,7 +65,7 @@ use crate::{ /// ``` #[doc(alias = "BPF_MAP_TYPE_SOCKHASH")] pub struct SockHash { - inner: T, + pub(crate) inner: T, _k: PhantomData, } diff --git a/aya/src/maps/stack.rs b/aya/src/maps/stack.rs index ac1453cd2..a85fe14d5 100644 --- a/aya/src/maps/stack.rs +++ b/aya/src/maps/stack.rs @@ -30,7 +30,7 @@ use crate::{ /// ``` #[doc(alias = "BPF_MAP_TYPE_STACK")] pub struct Stack { - inner: T, + pub(crate) inner: T, _v: PhantomData, } diff --git a/aya/src/maps/stack_trace.rs b/aya/src/maps/stack_trace.rs index fdf1d9374..389b28f78 100644 --- a/aya/src/maps/stack_trace.rs +++ b/aya/src/maps/stack_trace.rs @@ -67,7 +67,7 @@ use crate::{ #[derive(Debug)] #[doc(alias = "BPF_MAP_TYPE_STACK_TRACE")] pub struct StackTraceMap { - inner: T, + pub(crate) inner: T, max_stack_depth: usize, } diff --git a/aya/src/maps/xdp/cpu_map.rs b/aya/src/maps/xdp/cpu_map.rs index f48fcdc29..85f9e679a 100644 --- a/aya/src/maps/xdp/cpu_map.rs +++ b/aya/src/maps/xdp/cpu_map.rs @@ -50,7 +50,7 @@ use crate::{ /// Kernel documentation: #[doc(alias = "BPF_MAP_TYPE_CPUMAP")] pub struct CpuMap { - inner: T, + pub(crate) inner: T, } impl> CpuMap { diff --git a/aya/src/maps/xdp/dev_map.rs b/aya/src/maps/xdp/dev_map.rs index 6b6cd5456..31e9b3acb 100644 --- a/aya/src/maps/xdp/dev_map.rs +++ b/aya/src/maps/xdp/dev_map.rs @@ -42,7 +42,7 @@ use crate::{ /// Kernel documentation: #[doc(alias = "BPF_MAP_TYPE_DEVMAP")] pub struct DevMap { - inner: T, + pub(crate) inner: T, } impl> DevMap { diff --git a/aya/src/maps/xdp/dev_map_hash.rs b/aya/src/maps/xdp/dev_map_hash.rs index 65b00ee49..63a93b024 100644 --- a/aya/src/maps/xdp/dev_map_hash.rs +++ b/aya/src/maps/xdp/dev_map_hash.rs @@ -42,7 +42,7 @@ use crate::{ /// Kernel documentation: #[doc(alias = "BPF_MAP_TYPE_DEVMAP_HASH")] pub struct DevMapHash { - inner: T, + pub(crate) inner: T, } impl> DevMapHash { diff --git a/aya/src/maps/xdp/xsk_map.rs b/aya/src/maps/xdp/xsk_map.rs index 5382ae4c9..43924abf5 100644 --- a/aya/src/maps/xdp/xsk_map.rs +++ b/aya/src/maps/xdp/xsk_map.rs @@ -36,7 +36,7 @@ use crate::{ /// Kernel documentation: #[doc(alias = "BPF_MAP_TYPE_XSKMAP")] pub struct XskMap { - inner: T, + pub(crate) inner: T, } impl> XskMap { diff --git a/xtask/public-api/aya.txt b/xtask/public-api/aya.txt index 862214985..81fa16ecf 100644 --- a/xtask/public-api/aya.txt +++ b/xtask/public-api/aya.txt @@ -12,6 +12,8 @@ pub fn aya::maps::array::Array::get(&self, index: &u32, flags: u64) -> cor pub fn aya::maps::array::Array::iter(&self) -> impl core::iter::traits::iterator::Iterator> + '_ pub fn aya::maps::array::Array::len(&self) -> u32 impl, V: aya::Pod> aya::maps::array::Array +pub fn aya::maps::array::Array::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> +impl, V: aya::Pod> aya::maps::array::Array pub fn aya::maps::array::Array::set(&mut self, index: u32, value: impl core::borrow::Borrow, flags: u64) -> core::result::Result<(), aya::maps::MapError> impl<'a, V: aya::Pod> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::array::Array<&'a aya::maps::MapData, V> pub type aya::maps::array::Array<&'a aya::maps::MapData, V>::Error = aya::maps::MapError @@ -52,6 +54,8 @@ pub fn aya::maps::PerCpuArray::get(&self, index: &u32, flags: u64) -> core pub fn aya::maps::PerCpuArray::iter(&self) -> impl core::iter::traits::iterator::Iterator, aya::maps::MapError>> + '_ pub fn aya::maps::PerCpuArray::len(&self) -> u32 impl, V: aya::Pod> aya::maps::PerCpuArray +pub fn aya::maps::PerCpuArray::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> +impl, V: aya::Pod> aya::maps::PerCpuArray pub fn aya::maps::PerCpuArray::set(&mut self, index: u32, values: aya::maps::PerCpuValues, flags: u64) -> core::result::Result<(), aya::maps::MapError> impl<'a, V: aya::Pod> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::PerCpuArray<&'a aya::maps::MapData, V> pub type aya::maps::PerCpuArray<&'a aya::maps::MapData, V>::Error = aya::maps::MapError @@ -92,6 +96,8 @@ pub fn aya::maps::ProgramArray::indices(&self) -> aya::maps::MapKeys<'_, u32> impl> aya::maps::ProgramArray pub fn aya::maps::ProgramArray::clear_index(&mut self, index: &u32) -> core::result::Result<(), aya::maps::MapError> pub fn aya::maps::ProgramArray::set(&mut self, index: u32, program: &aya::programs::ProgramFd, flags: u64) -> core::result::Result<(), aya::maps::MapError> +impl> aya::maps::ProgramArray +pub fn aya::maps::ProgramArray::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> impl core::convert::TryFrom for aya::maps::ProgramArray pub type aya::maps::ProgramArray::Error = aya::maps::MapError pub fn aya::maps::ProgramArray::try_from(map: aya::maps::Map) -> core::result::Result @@ -128,6 +134,8 @@ impl, V: aya::Pod> aya::maps::bloom_ pub fn aya::maps::bloom_filter::BloomFilter::contains(&self, value: &V, flags: u64) -> core::result::Result<(), aya::maps::MapError> impl, V: aya::Pod> aya::maps::bloom_filter::BloomFilter pub fn aya::maps::bloom_filter::BloomFilter::insert(&mut self, value: impl core::borrow::Borrow, flags: u64) -> core::result::Result<(), aya::maps::MapError> +impl, V: aya::Pod> aya::maps::bloom_filter::BloomFilter +pub fn aya::maps::bloom_filter::BloomFilter::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> impl<'a, V: aya::Pod> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::bloom_filter::BloomFilter<&'a aya::maps::MapData, V> pub type aya::maps::bloom_filter::BloomFilter<&'a aya::maps::MapData, V>::Error = aya::maps::MapError pub fn aya::maps::bloom_filter::BloomFilter<&'a aya::maps::MapData, V>::try_from(map: &'a aya::maps::Map) -> core::result::Result @@ -169,6 +177,8 @@ pub fn aya::maps::hash_map::HashMap::keys(&self) -> aya::maps::MapKeys< impl, K: aya::Pod, V: aya::Pod> aya::maps::hash_map::HashMap pub fn aya::maps::hash_map::HashMap::insert(&mut self, key: impl core::borrow::Borrow, value: impl core::borrow::Borrow, flags: u64) -> core::result::Result<(), aya::maps::MapError> pub fn aya::maps::hash_map::HashMap::remove(&mut self, key: &K) -> core::result::Result<(), aya::maps::MapError> +impl, K: aya::Pod, V: aya::Pod> aya::maps::hash_map::HashMap +pub fn aya::maps::hash_map::HashMap::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> impl<'a, K: aya::Pod, V: aya::Pod> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::hash_map::HashMap<&'a aya::maps::MapData, K, V> pub type aya::maps::hash_map::HashMap<&'a aya::maps::MapData, K, V>::Error = aya::maps::MapError pub fn aya::maps::hash_map::HashMap<&'a aya::maps::MapData, K, V>::try_from(map: &'a aya::maps::Map) -> core::result::Result @@ -212,6 +222,8 @@ pub fn aya::maps::hash_map::PerCpuHashMap::keys(&self) -> aya::maps::Ma impl, K: aya::Pod, V: aya::Pod> aya::maps::hash_map::PerCpuHashMap pub fn aya::maps::hash_map::PerCpuHashMap::insert(&mut self, key: impl core::borrow::Borrow, values: aya::maps::PerCpuValues, flags: u64) -> core::result::Result<(), aya::maps::MapError> pub fn aya::maps::hash_map::PerCpuHashMap::remove(&mut self, key: &K) -> core::result::Result<(), aya::maps::MapError> +impl, K: aya::Pod, V: aya::Pod> aya::maps::hash_map::PerCpuHashMap +pub fn aya::maps::hash_map::PerCpuHashMap::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> impl<'a, K: aya::Pod, V: aya::Pod> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::hash_map::PerCpuHashMap<&'a aya::maps::MapData, K, V> pub type aya::maps::hash_map::PerCpuHashMap<&'a aya::maps::MapData, K, V>::Error = aya::maps::MapError pub fn aya::maps::hash_map::PerCpuHashMap<&'a aya::maps::MapData, K, V>::try_from(map: &'a aya::maps::Map) -> core::result::Result @@ -291,6 +303,8 @@ pub fn aya::maps::lpm_trie::LpmTrie::keys(&self) -> aya::maps::MapKeys< impl, K: aya::Pod, V: aya::Pod> aya::maps::lpm_trie::LpmTrie pub fn aya::maps::lpm_trie::LpmTrie::insert(&mut self, key: &aya::maps::lpm_trie::Key, value: impl core::borrow::Borrow, flags: u64) -> core::result::Result<(), aya::maps::MapError> pub fn aya::maps::lpm_trie::LpmTrie::remove(&mut self, key: &aya::maps::lpm_trie::Key) -> core::result::Result<(), aya::maps::MapError> +impl, K: aya::Pod, V: aya::Pod> aya::maps::lpm_trie::LpmTrie +pub fn aya::maps::lpm_trie::LpmTrie::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> impl<'a, K: aya::Pod, V: aya::Pod> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::lpm_trie::LpmTrie<&'a aya::maps::MapData, K, V> pub type aya::maps::lpm_trie::LpmTrie<&'a aya::maps::MapData, K, V>::Error = aya::maps::MapError pub fn aya::maps::lpm_trie::LpmTrie<&'a aya::maps::MapData, K, V>::try_from(map: &'a aya::maps::Map) -> core::result::Result @@ -524,6 +538,8 @@ pub struct aya::maps::queue::Queue impl, V: aya::Pod> aya::maps::queue::Queue pub fn aya::maps::queue::Queue::capacity(&self) -> u32 impl, V: aya::Pod> aya::maps::queue::Queue +pub fn aya::maps::queue::Queue::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> +impl, V: aya::Pod> aya::maps::queue::Queue pub fn aya::maps::queue::Queue::pop(&mut self, flags: u64) -> core::result::Result pub fn aya::maps::queue::Queue::push(&mut self, value: impl core::borrow::Borrow, flags: u64) -> core::result::Result<(), aya::maps::MapError> impl<'a, V: aya::Pod> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::queue::Queue<&'a aya::maps::MapData, V> @@ -566,6 +582,8 @@ pub fn aya::maps::SockHash::keys(&self) -> aya::maps::MapKeys<'_, K> impl, K: aya::Pod> aya::maps::SockHash pub fn aya::maps::SockHash::insert(&mut self, key: impl core::borrow::Borrow, value: I, flags: u64) -> core::result::Result<(), aya::maps::MapError> pub fn aya::maps::SockHash::remove(&mut self, key: &K) -> core::result::Result<(), aya::maps::MapError> +impl, V: aya::Pod> aya::maps::SockHash +pub fn aya::maps::SockHash::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> impl<'a, V: aya::Pod> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::SockHash<&'a aya::maps::MapData, V> pub type aya::maps::SockHash<&'a aya::maps::MapData, V>::Error = aya::maps::MapError pub fn aya::maps::SockHash<&'a aya::maps::MapData, V>::try_from(map: &'a aya::maps::Map) -> core::result::Result @@ -606,6 +624,8 @@ pub fn aya::maps::SockMap::indices(&self) -> aya::maps::MapKeys<'_, u32> impl> aya::maps::SockMap pub fn aya::maps::SockMap::clear_index(&mut self, index: &u32) -> core::result::Result<(), aya::maps::MapError> pub fn aya::maps::SockMap::set(&mut self, index: u32, socket: &I, flags: u64) -> core::result::Result<(), aya::maps::MapError> +impl> aya::maps::SockMap +pub fn aya::maps::SockMap::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> impl core::convert::TryFrom for aya::maps::SockMap pub type aya::maps::SockMap::Error = aya::maps::MapError pub fn aya::maps::SockMap::try_from(map: aya::maps::Map) -> core::result::Result @@ -667,6 +687,8 @@ pub struct aya::maps::stack::Stack impl, V: aya::Pod> aya::maps::stack::Stack pub fn aya::maps::stack::Stack::capacity(&self) -> u32 impl, V: aya::Pod> aya::maps::stack::Stack +pub fn aya::maps::stack::Stack::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> +impl, V: aya::Pod> aya::maps::stack::Stack pub fn aya::maps::stack::Stack::pop(&mut self, flags: u64) -> core::result::Result pub fn aya::maps::stack::Stack::push(&mut self, value: impl core::borrow::Borrow, flags: u64) -> core::result::Result<(), aya::maps::MapError> impl<'a, V: aya::Pod> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::stack::Stack<&'a aya::maps::MapData, V> @@ -756,6 +778,8 @@ impl> aya::maps::stack_trace::StackT pub fn aya::maps::stack_trace::StackTraceMap::get(&self, stack_id: &u32, flags: u64) -> core::result::Result pub fn aya::maps::stack_trace::StackTraceMap::iter(&self) -> aya::maps::MapIter<'_, u32, aya::maps::stack_trace::StackTrace, Self> pub fn aya::maps::stack_trace::StackTraceMap::stack_ids(&self) -> aya::maps::MapKeys<'_, u32> +impl> aya::maps::stack_trace::StackTraceMap +pub fn aya::maps::stack_trace::StackTraceMap::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> impl core::convert::TryFrom for aya::maps::stack_trace::StackTraceMap pub type aya::maps::stack_trace::StackTraceMap::Error = aya::maps::MapError pub fn aya::maps::stack_trace::StackTraceMap::try_from(map: aya::maps::Map) -> core::result::Result @@ -836,6 +860,8 @@ pub fn aya::maps::CpuMap::get(&self, cpu_index: u32, flags: u64) -> core::res pub fn aya::maps::CpuMap::iter(&self) -> impl core::iter::traits::iterator::Iterator> + '_ pub fn aya::maps::CpuMap::len(&self) -> u32 impl> aya::maps::CpuMap +pub fn aya::maps::CpuMap::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> +impl> aya::maps::CpuMap pub fn aya::maps::CpuMap::set(&mut self, cpu_index: u32, queue_size: u32, program: core::option::Option<&aya::programs::ProgramFd>, flags: u64) -> core::result::Result<(), aya::maps::xdp::XdpMapError> impl core::convert::TryFrom for aya::maps::CpuMap pub type aya::maps::CpuMap::Error = aya::maps::MapError @@ -873,6 +899,8 @@ pub fn aya::maps::DevMap::get(&self, index: u32, flags: u64) -> core::result: pub fn aya::maps::DevMap::iter(&self) -> impl core::iter::traits::iterator::Iterator> + '_ pub fn aya::maps::DevMap::len(&self) -> u32 impl> aya::maps::DevMap +pub fn aya::maps::DevMap::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> +impl> aya::maps::DevMap pub fn aya::maps::DevMap::set(&mut self, index: u32, target_if_index: u32, program: core::option::Option<&aya::programs::ProgramFd>, flags: u64) -> core::result::Result<(), aya::maps::xdp::XdpMapError> impl core::convert::TryFrom for aya::maps::DevMap pub type aya::maps::DevMap::Error = aya::maps::MapError @@ -912,6 +940,8 @@ pub fn aya::maps::DevMapHash::keys(&self) -> aya::maps::MapKeys<'_, u32> impl> aya::maps::DevMapHash pub fn aya::maps::DevMapHash::insert(&mut self, key: u32, target_if_index: u32, program: core::option::Option<&aya::programs::ProgramFd>, flags: u64) -> core::result::Result<(), aya::maps::xdp::XdpMapError> pub fn aya::maps::DevMapHash::remove(&mut self, key: u32) -> core::result::Result<(), aya::maps::MapError> +impl> aya::maps::DevMapHash +pub fn aya::maps::DevMapHash::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> impl core::convert::TryFrom for aya::maps::DevMapHash pub type aya::maps::DevMapHash::Error = aya::maps::MapError pub fn aya::maps::DevMapHash::try_from(map: aya::maps::Map) -> core::result::Result @@ -946,6 +976,8 @@ pub struct aya::maps::xdp::XskMap impl> aya::maps::XskMap pub fn aya::maps::XskMap::len(&self) -> u32 impl> aya::maps::XskMap +pub fn aya::maps::XskMap::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> +impl> aya::maps::XskMap pub fn aya::maps::XskMap::set(&mut self, index: u32, socket_fd: impl std::os::fd::raw::AsRawFd, flags: u64) -> core::result::Result<(), aya::maps::MapError> impl core::convert::TryFrom for aya::maps::XskMap pub type aya::maps::XskMap::Error = aya::maps::MapError @@ -998,6 +1030,8 @@ pub aya::maps::Map::Stack(aya::maps::MapData) pub aya::maps::Map::StackTraceMap(aya::maps::MapData) pub aya::maps::Map::Unsupported(aya::maps::MapData) pub aya::maps::Map::XskMap(aya::maps::MapData) +impl aya::maps::Map +pub fn aya::maps::Map::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> impl core::convert::TryFrom for aya::maps::CpuMap pub type aya::maps::CpuMap::Error = aya::maps::MapError pub fn aya::maps::CpuMap::try_from(map: aya::maps::Map) -> core::result::Result @@ -1252,6 +1286,8 @@ pub fn aya::maps::array::Array::get(&self, index: &u32, flags: u64) -> cor pub fn aya::maps::array::Array::iter(&self) -> impl core::iter::traits::iterator::Iterator> + '_ pub fn aya::maps::array::Array::len(&self) -> u32 impl, V: aya::Pod> aya::maps::array::Array +pub fn aya::maps::array::Array::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> +impl, V: aya::Pod> aya::maps::array::Array pub fn aya::maps::array::Array::set(&mut self, index: u32, value: impl core::borrow::Borrow, flags: u64) -> core::result::Result<(), aya::maps::MapError> impl<'a, V: aya::Pod> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::array::Array<&'a aya::maps::MapData, V> pub type aya::maps::array::Array<&'a aya::maps::MapData, V>::Error = aya::maps::MapError @@ -1324,6 +1360,8 @@ impl, V: aya::Pod> aya::maps::bloom_ pub fn aya::maps::bloom_filter::BloomFilter::contains(&self, value: &V, flags: u64) -> core::result::Result<(), aya::maps::MapError> impl, V: aya::Pod> aya::maps::bloom_filter::BloomFilter pub fn aya::maps::bloom_filter::BloomFilter::insert(&mut self, value: impl core::borrow::Borrow, flags: u64) -> core::result::Result<(), aya::maps::MapError> +impl, V: aya::Pod> aya::maps::bloom_filter::BloomFilter +pub fn aya::maps::bloom_filter::BloomFilter::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> impl<'a, V: aya::Pod> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::bloom_filter::BloomFilter<&'a aya::maps::MapData, V> pub type aya::maps::bloom_filter::BloomFilter<&'a aya::maps::MapData, V>::Error = aya::maps::MapError pub fn aya::maps::bloom_filter::BloomFilter<&'a aya::maps::MapData, V>::try_from(map: &'a aya::maps::Map) -> core::result::Result @@ -1362,6 +1400,8 @@ pub fn aya::maps::CpuMap::get(&self, cpu_index: u32, flags: u64) -> core::res pub fn aya::maps::CpuMap::iter(&self) -> impl core::iter::traits::iterator::Iterator> + '_ pub fn aya::maps::CpuMap::len(&self) -> u32 impl> aya::maps::CpuMap +pub fn aya::maps::CpuMap::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> +impl> aya::maps::CpuMap pub fn aya::maps::CpuMap::set(&mut self, cpu_index: u32, queue_size: u32, program: core::option::Option<&aya::programs::ProgramFd>, flags: u64) -> core::result::Result<(), aya::maps::xdp::XdpMapError> impl core::convert::TryFrom for aya::maps::CpuMap pub type aya::maps::CpuMap::Error = aya::maps::MapError @@ -1399,6 +1439,8 @@ pub fn aya::maps::DevMap::get(&self, index: u32, flags: u64) -> core::result: pub fn aya::maps::DevMap::iter(&self) -> impl core::iter::traits::iterator::Iterator> + '_ pub fn aya::maps::DevMap::len(&self) -> u32 impl> aya::maps::DevMap +pub fn aya::maps::DevMap::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> +impl> aya::maps::DevMap pub fn aya::maps::DevMap::set(&mut self, index: u32, target_if_index: u32, program: core::option::Option<&aya::programs::ProgramFd>, flags: u64) -> core::result::Result<(), aya::maps::xdp::XdpMapError> impl core::convert::TryFrom for aya::maps::DevMap pub type aya::maps::DevMap::Error = aya::maps::MapError @@ -1438,6 +1480,8 @@ pub fn aya::maps::DevMapHash::keys(&self) -> aya::maps::MapKeys<'_, u32> impl> aya::maps::DevMapHash pub fn aya::maps::DevMapHash::insert(&mut self, key: u32, target_if_index: u32, program: core::option::Option<&aya::programs::ProgramFd>, flags: u64) -> core::result::Result<(), aya::maps::xdp::XdpMapError> pub fn aya::maps::DevMapHash::remove(&mut self, key: u32) -> core::result::Result<(), aya::maps::MapError> +impl> aya::maps::DevMapHash +pub fn aya::maps::DevMapHash::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> impl core::convert::TryFrom for aya::maps::DevMapHash pub type aya::maps::DevMapHash::Error = aya::maps::MapError pub fn aya::maps::DevMapHash::try_from(map: aya::maps::Map) -> core::result::Result @@ -1476,6 +1520,8 @@ pub fn aya::maps::hash_map::HashMap::keys(&self) -> aya::maps::MapKeys< impl, K: aya::Pod, V: aya::Pod> aya::maps::hash_map::HashMap pub fn aya::maps::hash_map::HashMap::insert(&mut self, key: impl core::borrow::Borrow, value: impl core::borrow::Borrow, flags: u64) -> core::result::Result<(), aya::maps::MapError> pub fn aya::maps::hash_map::HashMap::remove(&mut self, key: &K) -> core::result::Result<(), aya::maps::MapError> +impl, K: aya::Pod, V: aya::Pod> aya::maps::hash_map::HashMap +pub fn aya::maps::hash_map::HashMap::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> impl<'a, K: aya::Pod, V: aya::Pod> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::hash_map::HashMap<&'a aya::maps::MapData, K, V> pub type aya::maps::hash_map::HashMap<&'a aya::maps::MapData, K, V>::Error = aya::maps::MapError pub fn aya::maps::hash_map::HashMap<&'a aya::maps::MapData, K, V>::try_from(map: &'a aya::maps::Map) -> core::result::Result @@ -1519,6 +1565,8 @@ pub fn aya::maps::lpm_trie::LpmTrie::keys(&self) -> aya::maps::MapKeys< impl, K: aya::Pod, V: aya::Pod> aya::maps::lpm_trie::LpmTrie pub fn aya::maps::lpm_trie::LpmTrie::insert(&mut self, key: &aya::maps::lpm_trie::Key, value: impl core::borrow::Borrow, flags: u64) -> core::result::Result<(), aya::maps::MapError> pub fn aya::maps::lpm_trie::LpmTrie::remove(&mut self, key: &aya::maps::lpm_trie::Key) -> core::result::Result<(), aya::maps::MapError> +impl, K: aya::Pod, V: aya::Pod> aya::maps::lpm_trie::LpmTrie +pub fn aya::maps::lpm_trie::LpmTrie::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> impl<'a, K: aya::Pod, V: aya::Pod> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::lpm_trie::LpmTrie<&'a aya::maps::MapData, K, V> pub type aya::maps::lpm_trie::LpmTrie<&'a aya::maps::MapData, K, V>::Error = aya::maps::MapError pub fn aya::maps::lpm_trie::LpmTrie<&'a aya::maps::MapData, K, V>::try_from(map: &'a aya::maps::Map) -> core::result::Result @@ -1674,6 +1722,8 @@ pub fn aya::maps::PerCpuArray::get(&self, index: &u32, flags: u64) -> core pub fn aya::maps::PerCpuArray::iter(&self) -> impl core::iter::traits::iterator::Iterator, aya::maps::MapError>> + '_ pub fn aya::maps::PerCpuArray::len(&self) -> u32 impl, V: aya::Pod> aya::maps::PerCpuArray +pub fn aya::maps::PerCpuArray::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> +impl, V: aya::Pod> aya::maps::PerCpuArray pub fn aya::maps::PerCpuArray::set(&mut self, index: u32, values: aya::maps::PerCpuValues, flags: u64) -> core::result::Result<(), aya::maps::MapError> impl<'a, V: aya::Pod> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::PerCpuArray<&'a aya::maps::MapData, V> pub type aya::maps::PerCpuArray<&'a aya::maps::MapData, V>::Error = aya::maps::MapError @@ -1716,6 +1766,8 @@ pub fn aya::maps::hash_map::PerCpuHashMap::keys(&self) -> aya::maps::Ma impl, K: aya::Pod, V: aya::Pod> aya::maps::hash_map::PerCpuHashMap pub fn aya::maps::hash_map::PerCpuHashMap::insert(&mut self, key: impl core::borrow::Borrow, values: aya::maps::PerCpuValues, flags: u64) -> core::result::Result<(), aya::maps::MapError> pub fn aya::maps::hash_map::PerCpuHashMap::remove(&mut self, key: &K) -> core::result::Result<(), aya::maps::MapError> +impl, K: aya::Pod, V: aya::Pod> aya::maps::hash_map::PerCpuHashMap +pub fn aya::maps::hash_map::PerCpuHashMap::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> impl<'a, K: aya::Pod, V: aya::Pod> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::hash_map::PerCpuHashMap<&'a aya::maps::MapData, K, V> pub type aya::maps::hash_map::PerCpuHashMap<&'a aya::maps::MapData, K, V>::Error = aya::maps::MapError pub fn aya::maps::hash_map::PerCpuHashMap<&'a aya::maps::MapData, K, V>::try_from(map: &'a aya::maps::Map) -> core::result::Result @@ -1824,6 +1876,8 @@ pub fn aya::maps::ProgramArray::indices(&self) -> aya::maps::MapKeys<'_, u32> impl> aya::maps::ProgramArray pub fn aya::maps::ProgramArray::clear_index(&mut self, index: &u32) -> core::result::Result<(), aya::maps::MapError> pub fn aya::maps::ProgramArray::set(&mut self, index: u32, program: &aya::programs::ProgramFd, flags: u64) -> core::result::Result<(), aya::maps::MapError> +impl> aya::maps::ProgramArray +pub fn aya::maps::ProgramArray::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> impl core::convert::TryFrom for aya::maps::ProgramArray pub type aya::maps::ProgramArray::Error = aya::maps::MapError pub fn aya::maps::ProgramArray::try_from(map: aya::maps::Map) -> core::result::Result @@ -1858,6 +1912,8 @@ pub struct aya::maps::Queue impl, V: aya::Pod> aya::maps::queue::Queue pub fn aya::maps::queue::Queue::capacity(&self) -> u32 impl, V: aya::Pod> aya::maps::queue::Queue +pub fn aya::maps::queue::Queue::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> +impl, V: aya::Pod> aya::maps::queue::Queue pub fn aya::maps::queue::Queue::pop(&mut self, flags: u64) -> core::result::Result pub fn aya::maps::queue::Queue::push(&mut self, value: impl core::borrow::Borrow, flags: u64) -> core::result::Result<(), aya::maps::MapError> impl<'a, V: aya::Pod> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::queue::Queue<&'a aya::maps::MapData, V> @@ -1899,6 +1955,8 @@ pub fn aya::maps::SockHash::keys(&self) -> aya::maps::MapKeys<'_, K> impl, K: aya::Pod> aya::maps::SockHash pub fn aya::maps::SockHash::insert(&mut self, key: impl core::borrow::Borrow, value: I, flags: u64) -> core::result::Result<(), aya::maps::MapError> pub fn aya::maps::SockHash::remove(&mut self, key: &K) -> core::result::Result<(), aya::maps::MapError> +impl, V: aya::Pod> aya::maps::SockHash +pub fn aya::maps::SockHash::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> impl<'a, V: aya::Pod> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::SockHash<&'a aya::maps::MapData, V> pub type aya::maps::SockHash<&'a aya::maps::MapData, V>::Error = aya::maps::MapError pub fn aya::maps::SockHash<&'a aya::maps::MapData, V>::try_from(map: &'a aya::maps::Map) -> core::result::Result @@ -1939,6 +1997,8 @@ pub fn aya::maps::SockMap::indices(&self) -> aya::maps::MapKeys<'_, u32> impl> aya::maps::SockMap pub fn aya::maps::SockMap::clear_index(&mut self, index: &u32) -> core::result::Result<(), aya::maps::MapError> pub fn aya::maps::SockMap::set(&mut self, index: u32, socket: &I, flags: u64) -> core::result::Result<(), aya::maps::MapError> +impl> aya::maps::SockMap +pub fn aya::maps::SockMap::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> impl core::convert::TryFrom for aya::maps::SockMap pub type aya::maps::SockMap::Error = aya::maps::MapError pub fn aya::maps::SockMap::try_from(map: aya::maps::Map) -> core::result::Result @@ -1973,6 +2033,8 @@ pub struct aya::maps::Stack impl, V: aya::Pod> aya::maps::stack::Stack pub fn aya::maps::stack::Stack::capacity(&self) -> u32 impl, V: aya::Pod> aya::maps::stack::Stack +pub fn aya::maps::stack::Stack::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> +impl, V: aya::Pod> aya::maps::stack::Stack pub fn aya::maps::stack::Stack::pop(&mut self, flags: u64) -> core::result::Result pub fn aya::maps::stack::Stack::push(&mut self, value: impl core::borrow::Borrow, flags: u64) -> core::result::Result<(), aya::maps::MapError> impl<'a, V: aya::Pod> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::stack::Stack<&'a aya::maps::MapData, V> @@ -2010,6 +2072,8 @@ impl> aya::maps::stack_trace::StackT pub fn aya::maps::stack_trace::StackTraceMap::get(&self, stack_id: &u32, flags: u64) -> core::result::Result pub fn aya::maps::stack_trace::StackTraceMap::iter(&self) -> aya::maps::MapIter<'_, u32, aya::maps::stack_trace::StackTrace, Self> pub fn aya::maps::stack_trace::StackTraceMap::stack_ids(&self) -> aya::maps::MapKeys<'_, u32> +impl> aya::maps::stack_trace::StackTraceMap +pub fn aya::maps::stack_trace::StackTraceMap::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> impl core::convert::TryFrom for aya::maps::stack_trace::StackTraceMap pub type aya::maps::stack_trace::StackTraceMap::Error = aya::maps::MapError pub fn aya::maps::stack_trace::StackTraceMap::try_from(map: aya::maps::Map) -> core::result::Result @@ -2053,6 +2117,8 @@ pub struct aya::maps::XskMap impl> aya::maps::XskMap pub fn aya::maps::XskMap::len(&self) -> u32 impl> aya::maps::XskMap +pub fn aya::maps::XskMap::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> +impl> aya::maps::XskMap pub fn aya::maps::XskMap::set(&mut self, index: u32, socket_fd: impl std::os::fd::raw::AsRawFd, flags: u64) -> core::result::Result<(), aya::maps::MapError> impl core::convert::TryFrom for aya::maps::XskMap pub type aya::maps::XskMap::Error = aya::maps::MapError @@ -7349,7 +7415,6 @@ pub aya::BpfError::FileError::error: std::io::error::Error pub aya::BpfError::FileError::path: std::path::PathBuf pub aya::BpfError::MapError(aya::maps::MapError) pub aya::BpfError::NoBTF -pub aya::BpfError::NoPinPath pub aya::BpfError::ParseError(aya_obj::obj::ParseError) pub aya::BpfError::ProgramError(aya::programs::ProgramError) pub aya::BpfError::RelocationError(aya_obj::relocation::BpfRelocationError) @@ -7403,6 +7468,7 @@ pub fn aya::Bpf::load_file>(path: P) -> pub fn aya::Bpf::map(&self, name: &str) -> core::option::Option<&aya::maps::Map> pub fn aya::Bpf::map_mut(&mut self, name: &str) -> core::option::Option<&mut aya::maps::Map> pub fn aya::Bpf::maps(&self) -> impl core::iter::traits::iterator::Iterator +pub fn aya::Bpf::maps_mut(&mut self) -> impl core::iter::traits::iterator::Iterator pub fn aya::Bpf::program(&self, name: &str) -> core::option::Option<&aya::programs::Program> pub fn aya::Bpf::program_mut(&mut self, name: &str) -> core::option::Option<&mut aya::programs::Program> pub fn aya::Bpf::programs(&self) -> impl core::iter::traits::iterator::Iterator From 82039144bdf7d46d536b62d94d29268990180294 Mon Sep 17 00:00:00 2001 From: astoycos Date: Fri, 22 Sep 2023 10:37:57 -0400 Subject: [PATCH 3/3] integration-test: Add map pinning coverage Add coverage to the new public api's for map pinning (pin and unpin) which can be called on the generic aya::Map type OR explit map types. Additionally add coverage for the new libbpf LIBBPF_PIN_BY_NAME behavior. Signed-off-by: astoycos --- test/integration-test/bpf/multimap-btf.bpf.c | 11 +++ test/integration-test/src/tests/load.rs | 70 ++++++++++++++++++++ test/integration-test/src/tests/rbpf.rs | 24 ++++--- 3 files changed, 95 insertions(+), 10 deletions(-) diff --git a/test/integration-test/bpf/multimap-btf.bpf.c b/test/integration-test/bpf/multimap-btf.bpf.c index f6d34bcf8..9e5951659 100644 --- a/test/integration-test/bpf/multimap-btf.bpf.c +++ b/test/integration-test/bpf/multimap-btf.bpf.c @@ -17,13 +17,24 @@ struct { __uint(max_entries, 1); } map_2 SEC(".maps"); +struct { + __uint(type, BPF_MAP_TYPE_ARRAY); + __type(key, __u32); + __type(value, __u64); + __uint(max_entries, 1); + __uint(pinning, LIBBPF_PIN_BY_NAME); +} map_pin_by_name SEC(".maps"); + SEC("uprobe") int bpf_prog(void *ctx) { __u32 key = 0; __u64 twenty_four = 24; __u64 forty_two = 42; + __u64 forty_four = 44; + bpf_map_update_elem(&map_1, &key, &twenty_four, BPF_ANY); bpf_map_update_elem(&map_2, &key, &forty_two, BPF_ANY); + bpf_map_update_elem(&map_pin_by_name, &key, &forty_four, BPF_ANY); return 0; } diff --git a/test/integration-test/src/tests/load.rs b/test/integration-test/src/tests/load.rs index 5e193dbf8..685867e92 100644 --- a/test/integration-test/src/tests/load.rs +++ b/test/integration-test/src/tests/load.rs @@ -1,5 +1,7 @@ use std::{ convert::TryInto as _, + fs::remove_file, + path::Path, thread, time::{Duration, SystemTime}, }; @@ -40,6 +42,8 @@ fn multiple_btf_maps() { let map_1: Array<_, u64> = bpf.take_map("map_1").unwrap().try_into().unwrap(); let map_2: Array<_, u64> = bpf.take_map("map_2").unwrap().try_into().unwrap(); + let map_pin_by_name: Array<_, u64> = + bpf.take_map("map_pin_by_name").unwrap().try_into().unwrap(); let prog: &mut UProbe = bpf.program_mut("bpf_prog").unwrap().try_into().unwrap(); prog.load().unwrap(); @@ -51,9 +55,75 @@ fn multiple_btf_maps() { let key = 0; let val_1 = map_1.get(&key, 0).unwrap(); let val_2 = map_2.get(&key, 0).unwrap(); + let val_3 = map_pin_by_name.get(&key, 0).unwrap(); assert_eq!(val_1, 24); assert_eq!(val_2, 42); + assert_eq!(val_3, 44); + let map_pin = Path::new("/sys/fs/bpf/map_pin_by_name"); + assert!(&map_pin.exists()); + + remove_file(map_pin).unwrap(); +} + +#[test] +fn pin_lifecycle_multiple_btf_maps() { + let mut bpf = Bpf::load(crate::MULTIMAP_BTF).unwrap(); + + // "map_pin_by_name" should already be pinned, unpin and pin again later + let map_pin_by_name_path = Path::new("/sys/fs/bpf/map_pin_by_name"); + + assert!(map_pin_by_name_path.exists()); + remove_file(map_pin_by_name_path).unwrap(); + + // pin and unpin all maps before casting to explicit types + for (i, (name, map)) in bpf.maps_mut().enumerate() { + // Don't pin system maps or the map that's already pinned by name. + if name.contains(".rodata") || name.contains(".bss") { + continue; + } + let map_pin_path = &Path::new("/sys/fs/bpf/").join(i.to_string()); + + map.pin(map_pin_path).unwrap(); + + assert!(map_pin_path.exists()); + remove_file(map_pin_path).unwrap(); + } + + let mut map_1: Array<_, u64> = bpf.take_map("map_1").unwrap().try_into().unwrap(); + let mut map_2: Array<_, u64> = bpf.take_map("map_2").unwrap().try_into().unwrap(); + let mut map_pin_by_name: Array<_, u64> = + bpf.take_map("map_pin_by_name").unwrap().try_into().unwrap(); + + let prog: &mut UProbe = bpf.program_mut("bpf_prog").unwrap().try_into().unwrap(); + prog.load().unwrap(); + prog.attach(Some("trigger_bpf_program"), 0, "/proc/self/exe", None) + .unwrap(); + + trigger_bpf_program(); + + let key = 0; + let val_1 = map_1.get(&key, 0).unwrap(); + let val_2 = map_2.get(&key, 0).unwrap(); + let val_3 = map_pin_by_name.get(&key, 0).unwrap(); + + assert_eq!(val_1, 24); + assert_eq!(val_2, 42); + assert_eq!(val_3, 44); + + let map_1_pin_path = Path::new("/sys/fs/bpf/map_1"); + let map_2_pin_path = Path::new("/sys/fs/bpf/map_2"); + + map_1.pin(map_1_pin_path).unwrap(); + map_2.pin(map_2_pin_path).unwrap(); + map_pin_by_name.pin(map_pin_by_name_path).unwrap(); + assert!(map_1_pin_path.exists()); + assert!(map_2_pin_path.exists()); + assert!(map_pin_by_name_path.exists()); + + remove_file(map_1_pin_path).unwrap(); + remove_file(map_2_pin_path).unwrap(); + remove_file(map_pin_by_name_path).unwrap(); } #[no_mangle] diff --git a/test/integration-test/src/tests/rbpf.rs b/test/integration-test/src/tests/rbpf.rs index 3d2c0c970..d2aeafd8d 100644 --- a/test/integration-test/src/tests/rbpf.rs +++ b/test/integration-test/src/tests/rbpf.rs @@ -34,7 +34,7 @@ fn run_with_rbpf() { assert_eq!(vm.execute_program().unwrap(), XDP_PASS); } -static mut MULTIMAP_MAPS: [*mut Vec; 2] = [null_mut(), null_mut()]; +static mut MULTIMAP_MAPS: [*mut Vec; 3] = [null_mut(); 3]; #[test] fn use_map_with_rbpf() { @@ -47,11 +47,11 @@ fn use_map_with_rbpf() { ); // Initialize maps: - // - fd: 0xCAFE00 or 0xCAFE01 (the 0xCAFE00 part is used to distinguish fds from indices), + // - fd: Bitwise OR of the map_id with 0xCAFE00 (used to distinguish fds from indices), // - Note that rbpf does not convert fds into real pointers, // so we keeps the pointers to our maps in MULTIMAP_MAPS, to be used in helpers. let mut maps = HashMap::new(); - let mut map_instances = vec![vec![0u64], vec![0u64]]; + let mut map_instances = vec![vec![0u64], vec![0u64], vec![0u64]]; for (name, map) in object.maps.iter() { assert_eq!(map.key_size(), size_of::() as u32); assert_eq!(map.value_size(), size_of::() as u32); @@ -60,8 +60,14 @@ fn use_map_with_rbpf() { aya_obj::generated::bpf_map_type::BPF_MAP_TYPE_ARRAY as u32 ); - let map_id = if name == "map_1" { 0 } else { 1 }; - let fd = map_id as std::os::fd::RawFd | 0xCAFE00; + let map_id = match name.as_str() { + "map_1" => 0, + "map_2" => 1, + "map_pin_by_name" => 2, + n => panic!("Unexpected map: {n}"), + }; + + let fd = map_id as i32 | 0xCAFE00; maps.insert(name.to_owned(), (fd, map.clone())); unsafe { @@ -102,18 +108,16 @@ fn use_map_with_rbpf() { .expect("Helper failed"); assert_eq!(vm.execute_program().unwrap(), 0); - assert_eq!(map_instances[0][0], 24); - assert_eq!(map_instances[1][0], 42); + assert_eq!(map_instances, [[24], [42], [44]]); unsafe { - MULTIMAP_MAPS[0] = null_mut(); - MULTIMAP_MAPS[1] = null_mut(); + MULTIMAP_MAPS.iter_mut().for_each(|v| *v = null_mut()); } } #[track_caller] fn bpf_map_update_elem_multimap(map: u64, key: u64, value: u64, _: u64, _: u64) -> u64 { - assert_matches!(map, 0xCAFE00 | 0xCAFE01); + assert_matches!(map, 0xCAFE00 | 0xCAFE01 | 0xCAFE02); let key = *unsafe { (key as usize as *const u32).as_ref().unwrap() }; let value = *unsafe { (value as usize as *const u64).as_ref().unwrap() }; assert_eq!(key, 0);