From 76af9483294f06835a1c0dfa07b50caf3a60eb5d Mon Sep 17 00:00:00 2001 From: Adam Preuss Date: Wed, 21 Jun 2023 19:29:54 +0000 Subject: [PATCH] aya: add helper to return map name --- aya/src/maps/mod.rs | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/aya/src/maps/mod.rs b/aya/src/maps/mod.rs index ceab7307..02c37668 100644 --- a/aya/src/maps/mod.rs +++ b/aya/src/maps/mod.rs @@ -49,7 +49,7 @@ //! implement the [Pod] trait. use std::{ borrow::BorrowMut, - ffi::{c_long, CString}, + ffi::{c_long, CStr, CString}, fmt, io, marker::PhantomData, mem, @@ -57,6 +57,7 @@ use std::{ os::fd::{AsFd, BorrowedFd, OwnedFd}, path::Path, ptr, + str::Utf8Error, }; use libc::{getrlimit, rlim_t, rlimit, RLIMIT_MEMLOCK, RLIM_INFINITY}; @@ -120,6 +121,10 @@ pub enum MapError { name: String, }, + /// Map name is not valid UTF-8 + #[error("map name is not valid UTF-8")] + Utf8(#[from] Utf8Error), + /// Failed to create map #[error("failed to create map `{name}` with code {code}")] CreateError { @@ -719,6 +724,13 @@ impl MapData { fd } + /// Returns the name of the map. + pub fn name(&self) -> Result { + let info = bpf_map_get_info_by_fd(self.fd.as_fd())?; + let name_str = unsafe { CStr::from_ptr(info.name.as_ptr()) }.to_str()?; + Ok(name_str.to_string()) + } + pub(crate) fn obj(&self) -> &obj::Map { let Self { obj, fd: _ } = self; obj @@ -994,6 +1006,37 @@ mod tests { ); } + #[test] + fn test_name() { + use crate::generated::bpf_map_info; + + const TEST_NAME: &str = "foo"; + + override_syscall(|call| match call { + Syscall::Bpf { + cmd: bpf_cmd::BPF_MAP_CREATE, + .. + } => Ok(42), + Syscall::Bpf { + cmd: bpf_cmd::BPF_OBJ_GET_INFO_BY_FD, + attr, + } => { + assert_eq!( + unsafe { attr.info.info_len }, + mem::size_of::() as u32 + ); + let map_info = unsafe { &mut *(attr.info.info as *mut bpf_map_info) }; + map_info.name[..TEST_NAME.len()] + .copy_from_slice(unsafe { std::mem::transmute(TEST_NAME) }); + Ok(0) + } + _ => Err((-1, io::Error::from_raw_os_error(EFAULT))), + }); + + let map_data = MapData::create(new_obj_map(), TEST_NAME, None).unwrap(); + assert_eq!(TEST_NAME, map_data.name().unwrap()); + } + #[test] fn test_create_failed() { override_syscall(|_| Err((-42, io::Error::from_raw_os_error(EFAULT))));