Skip to content

Commit

Permalink
aya: remove unwrap and NonZero* in info
Browse files Browse the repository at this point in the history
Addresses the feedback from aya-rs#1007:
- remove panic from `unwrap` and `expect`
- Option<NonZero*> => Option<int> with `0` mapping to `None`

Refs: aya-rs#1007
  • Loading branch information
tyrone-wu authored and vadorovsky committed Sep 8, 2024
1 parent 635ed3b commit 02d1db5
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 140 deletions.
8 changes: 4 additions & 4 deletions aya-log/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,21 +136,21 @@ impl EbpfLogger {
) -> Result<EbpfLogger, Error> {
let program_info = loaded_programs()
.filter_map(|info| info.ok())
.find(|info| info.id().is_some_and(|id| id.get() == program_id))
.find(|info| info.id() == program_id)
.ok_or(Error::ProgramNotFound)?;

let map = program_info
.map_ids()
.map_err(Error::ProgramError)?
.expect("`map_ids` field in `bpf_prog_info` not available")
.ok_or_else(|| Error::MapNotFound)?
.iter()
.filter_map(|id| MapInfo::from_id(id.get()).ok())
.filter_map(|id| MapInfo::from_id(*id).ok())
.find(|map_info| match map_info.name_as_str() {
Some(name) => name == MAP_NAME,
None => false,
})
.ok_or(Error::MapNotFound)?;
let map = MapData::from_id(map.id().unwrap().get()).map_err(Error::MapError)?;
let map = MapData::from_id(map.id()).map_err(Error::MapError)?;

Self::read_logs_async(Map::PerfEventArray(map), logger)?;

Expand Down
38 changes: 13 additions & 25 deletions aya/src/maps/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
use std::{
ffi::CString,
num::NonZeroU32,
os::fd::{AsFd as _, BorrowedFd},
path::Path,
};
Expand All @@ -19,6 +18,8 @@ use crate::{
};

/// Provides Provides metadata information about a loaded eBPF map.
///
/// Introduced in kernel v4.13.
#[doc(alias = "bpf_map_info")]
#[derive(Debug)]
pub struct MapInfo(pub(crate) bpf_map_info);
Expand Down Expand Up @@ -49,38 +50,30 @@ impl MapInfo {

/// The unique ID for this map.
///
/// `None` is returned if the field is not available.
///
/// Introduced in kernel v4.13.
pub fn id(&self) -> Option<NonZeroU32> {
NonZeroU32::new(self.0.id)
pub fn id(&self) -> u32 {
self.0.id
}

/// The key size for this map in bytes.
///
/// `None` is returned if the field is not available.
///
/// Introduced in kernel v4.13.
pub fn key_size(&self) -> Option<NonZeroU32> {
NonZeroU32::new(self.0.key_size)
pub fn key_size(&self) -> u32 {
self.0.key_size
}

/// The value size for this map in bytes.
///
/// `None` is returned if the field is not available.
///
/// Introduced in kernel v4.13.
pub fn value_size(&self) -> Option<NonZeroU32> {
NonZeroU32::new(self.0.value_size)
pub fn value_size(&self) -> u32 {
self.0.value_size
}

/// The maximum number of entries in this map.
///
/// `None` is returned if the field is not available.
///
/// Introduced in kernel v4.13.
pub fn max_entries(&self) -> Option<NonZeroU32> {
NonZeroU32::new(self.0.max_entries)
pub fn max_entries(&self) -> u32 {
self.0.max_entries
}

/// The flags used in loading this map.
Expand All @@ -103,14 +96,9 @@ impl MapInfo {
///
/// Introduced in kernel v4.15.
pub fn name_as_str(&self) -> Option<&str> {
let name = std::str::from_utf8(self.name()).ok();
if let Some(name_str) = name {
// Char in program name was introduced in the same commit as map name
if FEATURES.bpf_name() || !name_str.is_empty() {
return name;
}
}
None
let name = std::str::from_utf8(self.name()).ok()?;
// Char in program name was introduced in the same commit as map name
(FEATURES.bpf_name() || !name.is_empty()).then_some(name)
}

/// Returns a file descriptor referencing the map.
Expand Down
8 changes: 4 additions & 4 deletions aya/src/maps/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1217,11 +1217,11 @@ mod tests {
.map(|map_info| {
let map_info = map_info.unwrap();
(
map_info.id().unwrap().get(),
map_info.key_size().unwrap().get(),
map_info.value_size().unwrap().get(),
map_info.id(),
map_info.key_size(),
map_info.value_size(),
map_info.map_flags(),
map_info.max_entries().unwrap().get(),
map_info.max_entries(),
map_info.fd().unwrap().as_fd().as_raw_fd(),
)
})
Expand Down
70 changes: 21 additions & 49 deletions aya/src/programs/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
use std::{
ffi::CString,
num::{NonZeroU32, NonZeroU64},
os::fd::{AsFd as _, BorrowedFd},
path::Path,
time::{Duration, SystemTime},
Expand Down Expand Up @@ -46,11 +45,9 @@ impl ProgramInfo {

/// The unique ID for this program.
///
/// `None` is returned if the field is not available.
///
/// Introduced in kernel v4.13.
pub fn id(&self) -> Option<NonZeroU32> {
NonZeroU32::new(self.0.id)
pub fn id(&self) -> u32 {
self.0.id
}

/// The program tag.
Expand All @@ -59,23 +56,19 @@ impl ProgramInfo {
/// [`Self::id()`]. A program's ID can vary every time it's loaded or unloaded, but the tag
/// will remain the same.
///
/// `None` is returned if the field is not available.
///
/// Introduced in kernel v4.13.
pub fn tag(&self) -> Option<NonZeroU64> {
NonZeroU64::new(u64::from_be_bytes(self.0.tag))
pub fn tag(&self) -> u64 {
u64::from_be_bytes(self.0.tag)
}

/// The size in bytes of the program's JIT-compiled machine code.
///
/// Note that this field is only updated when BPF JIT compiler is enabled. Kernels v4.15 and
/// above may already have it enabled by default.
///
/// `None` is returned if the field is not available, or if the JIT compiler is not enabled.
///
/// Introduced in kernel v4.13.
pub fn size_jitted(&self) -> Option<NonZeroU32> {
NonZeroU32::new(self.0.jited_prog_len)
pub fn size_jitted(&self) -> u32 {
self.0.jited_prog_len
}

/// The size in bytes of the program's translated eBPF bytecode.
Expand All @@ -86,8 +79,8 @@ impl ProgramInfo {
/// `None` is returned if the field is not available.
///
/// Introduced in kernel v4.15.
pub fn size_translated(&self) -> Option<NonZeroU32> {
NonZeroU32::new(self.0.xlated_prog_len)
pub fn size_translated(&self) -> Option<u32> {
(self.0.xlated_prog_len > 0).then_some(self.0.xlated_prog_len)
}

/// The time when the program was loaded.
Expand All @@ -96,11 +89,7 @@ impl ProgramInfo {
///
/// Introduced in kernel v4.15.
pub fn loaded_at(&self) -> Option<SystemTime> {
if self.0.load_time > 0 {
Some(boot_time() + Duration::from_nanos(self.0.load_time))
} else {
None
}
(self.0.load_time > 0).then_some(boot_time() + Duration::from_nanos(self.0.load_time))
}

/// The user ID of the process who loaded the program.
Expand All @@ -110,29 +99,19 @@ impl ProgramInfo {
/// Introduced in kernel v4.15.
pub fn created_by_uid(&self) -> Option<u32> {
// This field was introduced in the same commit as `load_time`.
if self.0.load_time > 0 {
Some(self.0.created_by_uid)
} else {
None
}
(self.0.load_time > 0).then_some(self.0.created_by_uid)
}

/// The IDs of the maps used by the program.
///
/// `None` is returned if the field is not available.
///
/// Introduced in kernel v4.15.
pub fn map_ids(&self) -> Result<Option<Vec<NonZeroU32>>, ProgramError> {
pub fn map_ids(&self) -> Result<Option<Vec<u32>>, ProgramError> {
if FEATURES.prog_info_map_ids() {
let mut map_ids = vec![0u32; self.0.nr_map_ids as usize];
bpf_prog_get_info_by_fd(self.fd()?.as_fd(), &mut map_ids)?;

Ok(Some(
map_ids
.into_iter()
.map(|id| NonZeroU32::new(id).unwrap())
.collect(),
))
Ok(Some(map_ids))
} else {
Ok(None)
}
Expand All @@ -151,13 +130,8 @@ impl ProgramInfo {
///
/// Introduced in kernel v4.15.
pub fn name_as_str(&self) -> Option<&str> {
let name = std::str::from_utf8(self.name()).ok();
if let Some(name_str) = name {
if FEATURES.bpf_name() || !name_str.is_empty() {
return name;
}
}
None
let name = std::str::from_utf8(self.name()).ok()?;
(FEATURES.bpf_name() || !name.is_empty()).then_some(name)
}

/// Returns true if the program is defined with a GPL-compatible license.
Expand All @@ -166,18 +140,16 @@ impl ProgramInfo {
///
/// Introduced in kernel v4.18.
pub fn gpl_compatible(&self) -> Option<bool> {
if FEATURES.prog_info_gpl_compatible() {
Some(self.0.gpl_compatible() != 0)
} else {
None
}
FEATURES
.prog_info_gpl_compatible()
.then_some(self.0.gpl_compatible() != 0)
}

/// The BTF ID for the program.
///
/// Introduced in kernel v5.0.
pub fn btf_id(&self) -> Option<NonZeroU32> {
NonZeroU32::new(self.0.btf_id)
pub fn btf_id(&self) -> Option<u32> {
(self.0.btf_id > 0).then_some(self.0.btf_id)
}

/// The accumulated time that the program has been actively running.
Expand Down Expand Up @@ -213,8 +185,8 @@ impl ProgramInfo {
/// `None` is returned if the field is not available.
///
/// Introduced in kernel v5.16.
pub fn verified_instruction_count(&self) -> Option<NonZeroU32> {
NonZeroU32::new(self.0.verified_insns)
pub fn verified_instruction_count(&self) -> Option<u32> {
(self.0.verified_insns > 0).then_some(self.0.verified_insns)
}

/// How much memory in bytes has been allocated and locked for the program.
Expand Down
Loading

0 comments on commit 02d1db5

Please sign in to comment.