Răsfoiți Sursa

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.
Alessandro Decina 4 ani în urmă
părinte
comite
635dcd44b9

+ 14 - 8
aya/src/maps/hash_map/hash_map.rs

@@ -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 {
-            call: "bpf_map_lookup_elem".to_owned(),
-            code,
-            io_error,
-        })
+        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> {

+ 7 - 6
aya/src/maps/hash_map/per_cpu_hash_map.rs

@@ -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)
     }
 }

+ 6 - 3
aya/src/maps/mod.rs

@@ -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)),
                     }
                 }

+ 3 - 3
aya/src/maps/program_array.rs

@@ -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)
     }
 }