aya: maps: introduce MapError::KeyNotFound

Change get() from -> Result<Option<V>, MapError> to -> Result<V,
MapError> where MapError::KeyNotFound is returned instead of Ok(None) to
signify that the key is not present.
pull/1/head
Alessandro Decina 4 years ago
parent fd142e467c
commit 635dcd44b9

@ -59,13 +59,16 @@ impl<T: Deref<Target = Map>, K: Pod, V: Pod> HashMap<T, K, V> {
}
/// Returns a copy of the value associated with the key.
pub unsafe fn get(&self, key: &K, flags: u64) -> Result<Option<V>, MapError> {
pub unsafe fn get(&self, key: &K, flags: u64) -> Result<V, MapError> {
let fd = self.inner.deref().fd_or_err()?;
bpf_map_lookup_elem(fd, key, flags).map_err(|(code, io_error)| MapError::SyscallError {
let value = bpf_map_lookup_elem(fd, key, flags).map_err(|(code, io_error)| {
MapError::SyscallError {
call: "bpf_map_lookup_elem".to_owned(),
code,
io_error,
})
}
})?;
value.ok_or(MapError::KeyNotFound)
}
/// An iterator visiting all key-value pairs in arbitrary order. The
@ -98,7 +101,7 @@ impl<T: Deref<Target = Map>, K: Pod, V: Pod> IterableMap<K, V> for HashMap<T, K,
self.inner.deref().fd_or_err()
}
unsafe fn get(&self, key: &K) -> Result<Option<V>, MapError> {
unsafe fn get(&self, key: &K) -> Result<V, MapError> {
HashMap::get(self, key, 0)
}
}
@ -379,7 +382,10 @@ mod tests {
};
let hm = HashMap::<_, u32, u32>::new(&map).unwrap();
assert!(matches!(unsafe { hm.get(&1, 0) }, Ok(None)));
assert!(matches!(
unsafe { hm.get(&1, 0) },
Err(MapError::KeyNotFound)
));
}
fn bpf_key<T: Copy>(attr: &bpf_attr) -> Option<T> {

@ -29,8 +29,8 @@ use crate::{
/// const WAKEUPS: u8 = 2;
///
/// let mut hm = PerCpuHashMap::<_, u8, u32>::try_from(bpf.map("COUNTERS")?)?;
/// let cpu_ids = unsafe { hm.get(&CPU_IDS, 0)?.unwrap() };
/// let wakeups = unsafe { hm.get(&WAKEUPS, 0)?.unwrap() };
/// let cpu_ids = unsafe { hm.get(&CPU_IDS, 0)? };
/// let wakeups = unsafe { hm.get(&WAKEUPS, 0)? };
/// for (cpu_id, wakeups) in cpu_ids.iter().zip(wakeups.iter()) {
/// println!("cpu {} woke up {} times", cpu_id, wakeups);
/// }
@ -63,15 +63,16 @@ impl<T: Deref<Target = Map>, K: Pod, V: Pod> PerCpuHashMap<T, K, V> {
}
/// Returns a slice of values - one for each CPU - associated with the key.
pub unsafe fn get(&self, key: &K, flags: u64) -> Result<Option<PerCpuValues<V>>, MapError> {
pub unsafe fn get(&self, key: &K, flags: u64) -> Result<PerCpuValues<V>, MapError> {
let fd = self.inner.deref().fd_or_err()?;
bpf_map_lookup_elem_per_cpu(fd, key, flags).map_err(|(code, io_error)| {
let values = bpf_map_lookup_elem_per_cpu(fd, key, flags).map_err(|(code, io_error)| {
MapError::SyscallError {
call: "bpf_map_lookup_elem".to_owned(),
code,
io_error,
}
})
})?;
values.ok_or(MapError::KeyNotFound)
}
/// An iterator visiting all key-value pairs in arbitrary order. The
@ -143,7 +144,7 @@ impl<T: Deref<Target = Map>, K: Pod, V: Pod> IterableMap<K, PerCpuValues<V>>
self.inner.deref().fd_or_err()
}
unsafe fn get(&self, key: &K) -> Result<Option<PerCpuValues<V>>, MapError> {
unsafe fn get(&self, key: &K) -> Result<PerCpuValues<V>, MapError> {
PerCpuHashMap::get(self, key, 0)
}
}

@ -83,6 +83,9 @@ pub enum MapError {
#[error("the index is {index} but `max_entries` is {max_entries}")]
OutOfBounds { index: u32, max_entries: u32 },
#[error("key not found")]
KeyNotFound,
#[error("the program is not loaded")]
ProgramNotLoaded,
@ -146,7 +149,7 @@ impl Map {
pub(crate) trait IterableMap<K: Pod, V> {
fn fd(&self) -> Result<RawFd, MapError>;
unsafe fn get(&self, key: &K) -> Result<Option<V>, MapError>;
unsafe fn get(&self, key: &K) -> Result<V, MapError>;
}
/// Iterator returned by `map.keys()`.
@ -225,8 +228,8 @@ impl<K: Pod, V> Iterator for MapIter<'_, K, V> {
Some(Ok(key)) => {
let value = unsafe { self.inner.map.get(&key) };
match value {
Ok(None) => continue,
Ok(Some(value)) => return Some(Ok((key, value))),
Ok(value) => return Some(Ok((key, value))),
Err(MapError::KeyNotFound) => continue,
Err(e) => return Some(Err(e)),
}
}

@ -46,7 +46,7 @@ impl<T: Deref<Target = Map>> ProgramArray<T> {
Ok(ProgramArray { inner: map })
}
pub unsafe fn get(&self, key: &u32, flags: u64) -> Result<Option<RawFd>, MapError> {
pub unsafe fn get(&self, key: &u32, flags: u64) -> Result<RawFd, MapError> {
let fd = self.inner.fd_or_err()?;
let fd = bpf_map_lookup_elem(fd, key, flags).map_err(|(code, io_error)| {
MapError::SyscallError {
@ -55,7 +55,7 @@ impl<T: Deref<Target = Map>> ProgramArray<T> {
io_error,
}
})?;
Ok(fd)
fd.ok_or(MapError::KeyNotFound)
}
pub unsafe fn iter<'coll>(&'coll self) -> MapIter<'coll, u32, RawFd> {
@ -133,7 +133,7 @@ impl<T: Deref<Target = Map>> IterableMap<u32, RawFd> for ProgramArray<T> {
self.inner.fd_or_err()
}
unsafe fn get(&self, index: &u32) -> Result<Option<RawFd>, MapError> {
unsafe fn get(&self, index: &u32) -> Result<RawFd, MapError> {
self.get(index, 0)
}
}

Loading…
Cancel
Save