Explorar o código

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 <[email protected]>
Dave Tucker hai 1 ano
pai
achega
938f979fe7
Modificáronse 2 ficheiros con 30 adicións e 4 borrados
  1. 29 4
      aya/src/maps/mod.rs
  2. 1 0
      xtask/public-api/aya.txt

+ 29 - 4
aya/src/maps/mod.rs

@@ -469,7 +469,8 @@ impl MapData {
             }
             Err(_) => {
                 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()),
                     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 _;
 
         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| {
             PinError::InvalidPinPath {
-                path: path.clone(),
+                path: path.to_path_buf(),
                 error,
             }
         })?;

+ 1 - 0
xtask/public-api/aya.txt

@@ -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::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::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
 pub fn aya::maps::MapData::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
 impl core::marker::Send for aya::maps::MapData