aya: Make MapData::pin pub

This is to solve a use-case where a user (in this case bpfd) may want
to:

- MapData::from_pin to open a pinned map from bpffs
- MapData::pin to pin that object into another bpffs

Both operations should be easily accomplished without needing to cast
a MapData into a concrete Map type - e.g aya::maps::HashMap.

Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
pull/790/head
Dave Tucker 1 year ago
parent 0f4021ec89
commit 938f979fe7

@ -469,7 +469,8 @@ impl MapData {
} }
Err(_) => { Err(_) => {
let mut map = Self::create(obj, name, btf_fd)?; let mut map = Self::create(obj, name, btf_fd)?;
map.pin(name, path).map_err(|error| MapError::PinError { let path = path.join(name);
map.pin(&path).map_err(|error| MapError::PinError {
name: Some(name.into()), name: Some(name.into()),
error, error,
})?; })?;
@ -542,14 +543,38 @@ impl MapData {
}) })
} }
pub(crate) fn pin<P: AsRef<Path>>(&mut self, name: &str, path: P) -> Result<(), PinError> { /// Allows the map to be pinned to the provided path.
///
/// Any directories in the the path provided should have been created by the caller.
/// The path must be on a BPF filesystem.
///
/// # Errors
///
/// Returns a [`PinError::SyscallError`] if the underlying syscall fails.
/// This may also happen if the path already exists, in which case the wrapped
/// [`std::io::Error`] kind will be [`std::io::ErrorKind::AlreadyExists`].
/// Returns a [`PinError::InvalidPinPath`] if the path provided cannot be
/// converted to a [`CString`].
///
/// # Example
///
/// ```no_run
/// # let mut bpf = aya::Bpf::load(&[])?;
/// # use aya::maps::MapData;
///
/// let mut map = MapData::from_pin("/sys/fs/bpf/my_map")?;
/// map.pin("/sys/fs/bpf/my_map2")?;
///
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
pub fn pin<P: AsRef<Path>>(&mut self, path: P) -> Result<(), PinError> {
use std::os::unix::ffi::OsStrExt as _; use std::os::unix::ffi::OsStrExt as _;
let Self { fd, obj: _ } = self; let Self { fd, obj: _ } = self;
let path = path.as_ref().join(name); let path = path.as_ref();
let path_string = CString::new(path.as_os_str().as_bytes()).map_err(|error| { let path_string = CString::new(path.as_os_str().as_bytes()).map_err(|error| {
PinError::InvalidPinPath { PinError::InvalidPinPath {
path: path.clone(), path: path.to_path_buf(),
error, error,
} }
})?; })?;

@ -1223,6 +1223,7 @@ pub fn aya::maps::MapData::create(obj: aya_obj::maps::Map, name: &str, btf_fd: c
pub fn aya::maps::MapData::fd(&self) -> &aya::maps::MapFd pub fn aya::maps::MapData::fd(&self) -> &aya::maps::MapFd
pub fn aya::maps::MapData::from_fd(fd: std::os::fd::owned::OwnedFd) -> core::result::Result<Self, aya::maps::MapError> pub fn aya::maps::MapData::from_fd(fd: std::os::fd::owned::OwnedFd) -> core::result::Result<Self, aya::maps::MapError>
pub fn aya::maps::MapData::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::maps::MapError> pub fn aya::maps::MapData::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::maps::MapError>
pub fn aya::maps::MapData::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
impl core::fmt::Debug for aya::maps::MapData impl core::fmt::Debug for aya::maps::MapData
pub fn aya::maps::MapData::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result pub fn aya::maps::MapData::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
impl core::marker::Send for aya::maps::MapData impl core::marker::Send for aya::maps::MapData

Loading…
Cancel
Save