aya/maps: add name to mapdata

Add a name field to mapdata to make the workflow
a bit simplier.

Signed-off-by: astoycos <astoycos@redhat.com>
reviewable/pr783/r1
astoycos 2 years ago
parent 5691829fcf
commit e84cd73fa3

@ -59,7 +59,7 @@ use crate::{
bpf_create_map, bpf_get_object, bpf_map_get_info_by_fd, bpf_map_get_next_key, bpf_create_map, bpf_get_object, bpf_map_get_info_by_fd, bpf_map_get_next_key,
bpf_pin_object, SyscallError, bpf_pin_object, SyscallError,
}, },
util::nr_cpus, util::{bytes_of_c_char, nr_cpus},
PinningType, Pod, PinningType, Pod,
}; };
@ -399,6 +399,7 @@ pub struct MapData {
pub(crate) fd: RawFd, pub(crate) fd: RawFd,
/// Indicates if this map has been pinned to bpffs /// Indicates if this map has been pinned to bpffs
pub pinned: bool, pub pinned: bool,
pub(crate) name: String,
} }
impl MapData { impl MapData {
@ -433,6 +434,7 @@ impl MapData {
obj, obj,
fd, fd,
pinned: false, pinned: false,
name: name.to_string(),
}) })
} }
@ -463,10 +465,11 @@ impl MapData {
obj, obj,
fd: fd.into_raw_fd(), fd: fd.into_raw_fd(),
pinned: false, pinned: false,
name: name.to_string(),
}), }),
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 { map.pin(path).map_err(|error| MapError::PinError {
name: Some(name.into()), name: Some(name.into()),
error, error,
})?; })?;
@ -496,10 +499,15 @@ impl MapData {
let info = bpf_map_get_info_by_fd(fd.as_fd())?; let info = bpf_map_get_info_by_fd(fd.as_fd())?;
let name_bytes = bytes_of_c_char(&info.name);
Ok(Self { Ok(Self {
obj: parse_map_info(info, PinningType::ByName), obj: parse_map_info(info, PinningType::ByName),
fd: fd.into_raw_fd(), fd: fd.into_raw_fd(),
pinned: true, pinned: true,
name: std::str::from_utf8(name_bytes)
.expect("unable to parse map name from bpf_map_info")
.to_string(),
}) })
} }
@ -511,19 +519,30 @@ impl MapData {
pub fn from_fd(fd: OwnedFd) -> Result<Self, MapError> { pub fn from_fd(fd: OwnedFd) -> Result<Self, MapError> {
let info = bpf_map_get_info_by_fd(fd.as_fd())?; let info = bpf_map_get_info_by_fd(fd.as_fd())?;
let name_bytes = bytes_of_c_char(&info.name);
Ok(Self { Ok(Self {
obj: parse_map_info(info, PinningType::None), obj: parse_map_info(info, PinningType::None),
fd: fd.into_raw_fd(), fd: fd.into_raw_fd(),
pinned: false, pinned: false,
name: std::str::from_utf8(name_bytes)
.expect("unable to parse map name from bpf_map_info")
.to_string(),
}) })
} }
pub(crate) fn pin<P: AsRef<Path>>(&mut self, name: &str, path: P) -> Result<(), PinError> { pub(crate) 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, pinned, obj: _ } = self; let Self {
fd,
pinned,
obj: _,
name,
} = self;
if *pinned { if *pinned {
return Err(PinError::AlreadyPinned { name: name.into() }); return Err(PinError::AlreadyPinned {
name: name.to_string(),
});
} }
let path = path.as_ref().join(name); let path = path.as_ref().join(name);
let path_string = CString::new(path.as_os_str().as_bytes()) let path_string = CString::new(path.as_os_str().as_bytes())
@ -555,11 +574,17 @@ impl Drop for MapData {
impl Clone for MapData { impl Clone for MapData {
fn clone(&self) -> Self { fn clone(&self) -> Self {
let Self { obj, fd, pinned } = self; let Self {
obj,
fd,
pinned,
name,
} = self;
Self { Self {
obj: obj.clone(), obj: obj.clone(),
fd: unsafe { libc::dup(*fd) }, fd: unsafe { libc::dup(*fd) },
pinned: *pinned, pinned: *pinned,
name: name.clone(),
} }
} }
} }
@ -797,6 +822,7 @@ mod tests {
obj: _, obj: _,
fd: 42, fd: 42,
pinned: false pinned: false
name: "foo".to_string(),
}) })
); );
} }

@ -117,7 +117,7 @@ use crate::{
bpf_prog_query, iter_link_ids, iter_prog_ids, retry_with_verifier_logs, bpf_prog_query, iter_link_ids, iter_prog_ids, retry_with_verifier_logs,
BpfLoadProgramAttrs, SyscallError, BpfLoadProgramAttrs, SyscallError,
}, },
util::KernelVersion, util::{bytes_of_c_char, KernelVersion},
VerifierLogLevel, VerifierLogLevel,
}; };
@ -977,17 +977,7 @@ impl ProgramInfo {
/// The name of the program as was provided when it was load. This is limited to 16 bytes /// The name of the program as was provided when it was load. This is limited to 16 bytes
pub fn name(&self) -> &[u8] { pub fn name(&self) -> &[u8] {
let length = self bytes_of_c_char(&self.0.name)
.0
.name
.iter()
.rposition(|ch| *ch != 0)
.map(|pos| pos + 1)
.unwrap_or(0);
// The name field is defined as [std::os::raw::c_char; 16]. c_char may be signed or
// unsigned depending on the platform; that's why we're using from_raw_parts here
unsafe { std::slice::from_raw_parts(self.0.name.as_ptr() as *const _, length) }
} }
/// The name of the program as a &str. If the name was not valid unicode, None is returned. /// The name of the program as a &str. If the name was not valid unicode, None is returned.

@ -337,6 +337,18 @@ pub(crate) fn bytes_of_slice<T: Pod>(val: &[T]) -> &[u8] {
unsafe { slice::from_raw_parts(val.as_ptr().cast(), size) } unsafe { slice::from_raw_parts(val.as_ptr().cast(), size) }
} }
pub(crate) fn bytes_of_c_char(val: &[std::os::raw::c_char]) -> &[u8] {
let length = val
.iter()
.rposition(|ch| *ch != 0)
.map(|pos| pos + 1)
.unwrap_or(0);
// The name field is defined as [std::os::raw::c_char; 16]. c_char may be signed or
// unsigned depending on the platform; that's why we're using from_raw_parts here
unsafe { std::slice::from_raw_parts(val.as_ptr() as *const _, length) }
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

Loading…
Cancel
Save