aya: maps: group syscall errors into MapError::SyscallError

pull/1/head
Alessandro Decina 4 years ago
parent f9554d6db5
commit 563ce46118

@ -95,8 +95,13 @@ impl Bpf {
let mut map = Map { obj, fd: None };
let fd = map.create()?;
if !map.obj.data.is_empty() && map.obj.name != ".bss" {
bpf_map_update_elem_ptr(fd, &0 as *const _, map.obj.data.as_ptr(), 0)
.map_err(|(code, io_error)| MapError::UpdateElementError { code, io_error })?;
bpf_map_update_elem_ptr(fd, &0 as *const _, map.obj.data.as_ptr(), 0).map_err(
|(code, io_error)| MapError::SyscallError {
call: "bpf_map_update_elem".to_owned(),
code,
io_error,
},
)?;
}
maps.push(map);
}

@ -56,8 +56,11 @@ impl<T: Deref<Target = Map>, K: Pod, V: Pod> HashMap<T, K, V> {
pub unsafe fn get(&self, key: &K, flags: u64) -> Result<Option<V>, MapError> {
let fd = self.inner.deref().fd_or_err()?;
bpf_map_lookup_elem(fd, key, flags)
.map_err(|(code, io_error)| MapError::LookupElementError { code, io_error })
bpf_map_lookup_elem(fd, key, flags).map_err(|(code, io_error)| MapError::SyscallError {
call: "bpf_map_lookup_elem".to_owned(),
code,
io_error,
})
}
pub unsafe fn iter<'coll>(&'coll self) -> MapIter<'coll, K, V> {
@ -72,22 +75,34 @@ impl<T: Deref<Target = Map>, K: Pod, V: Pod> HashMap<T, K, V> {
impl<T: DerefMut<Target = Map>, K: Pod, V: Pod> HashMap<T, K, V> {
pub fn insert(&mut self, key: K, value: V, flags: u64) -> Result<(), MapError> {
let fd = self.inner.deref_mut().fd_or_err()?;
bpf_map_update_elem(fd, &key, &value, flags)
.map_err(|(code, io_error)| MapError::UpdateElementError { code, io_error })?;
bpf_map_update_elem(fd, &key, &value, flags).map_err(|(code, io_error)| {
MapError::SyscallError {
call: "bpf_map_update_elem".to_owned(),
code,
io_error,
}
})?;
Ok(())
}
pub unsafe fn pop(&mut self, key: &K) -> Result<Option<V>, MapError> {
let fd = self.inner.deref_mut().fd_or_err()?;
bpf_map_lookup_and_delete_elem(fd, key)
.map_err(|(code, io_error)| MapError::LookupAndDeleteElementError { code, io_error })
bpf_map_lookup_and_delete_elem(fd, key).map_err(|(code, io_error)| MapError::SyscallError {
call: "bpf_map_lookup_and_delete_elem".to_owned(),
code,
io_error,
})
}
pub fn remove(&mut self, key: &K) -> Result<(), MapError> {
let fd = self.inner.deref_mut().fd_or_err()?;
bpf_map_delete_elem(fd, key)
.map(|_| ())
.map_err(|(code, io_error)| MapError::DeleteElementError { code, io_error })
.map_err(|(code, io_error)| MapError::SyscallError {
call: "bpf_map_delete_elem".to_owned(),
code,
io_error,
})
}
}
@ -268,7 +283,7 @@ mod tests {
assert!(matches!(
hm.insert(1, 42, 0),
Err(MapError::UpdateElementError { code: -1, io_error }) if io_error.raw_os_error() == Some(EFAULT)
Err(MapError::SyscallError { call, code: -1, io_error }) if call == "bpf_map_update_elem" && io_error.raw_os_error() == Some(EFAULT)
));
}
@ -303,7 +318,7 @@ mod tests {
assert!(matches!(
hm.remove(&1),
Err(MapError::DeleteElementError { code: -1, io_error }) if io_error.raw_os_error() == Some(EFAULT)
Err(MapError::SyscallError { call, code: -1, io_error }) if call == "bpf_map_delete_elem" && io_error.raw_os_error() == Some(EFAULT)
));
}
@ -337,7 +352,7 @@ mod tests {
assert!(matches!(
unsafe { hm.get(&1, 0) },
Err(MapError::LookupElementError { code: -1, io_error }) if io_error.raw_os_error() == Some(EFAULT)
Err(MapError::SyscallError { call, code: -1, io_error }) if call == "bpf_map_lookup_elem" && io_error.raw_os_error() == Some(EFAULT)
));
}
@ -370,7 +385,7 @@ mod tests {
assert!(matches!(
unsafe { hm.pop(&1) },
Err(MapError::LookupAndDeleteElementError { code: -1, io_error }) if io_error.raw_os_error() == Some(EFAULT)
Err(MapError::SyscallError { call, code: -1, io_error }) if call == "bpf_map_lookup_and_delete_elem" && io_error.raw_os_error() == Some(EFAULT)
));
}
@ -499,7 +514,7 @@ mod tests {
assert!(matches!(keys.next(), Some(Ok(20))));
assert!(matches!(
keys.next(),
Some(Err(MapError::GetNextKeyError { .. }))
Some(Err(MapError::SyscallError { call, .. })) if call == "bpf_map_get_next_key"
));
assert!(matches!(keys.next(), None));
}
@ -593,7 +608,7 @@ mod tests {
assert!(matches!(iter.next(), Some(Ok((20, 200)))));
assert!(matches!(
iter.next(),
Some(Err(MapError::GetNextKeyError { .. }))
Some(Err(MapError::SyscallError { call, .. })) if call == "bpf_map_get_next_key"
));
assert!(matches!(iter.next(), None));
}
@ -631,7 +646,7 @@ mod tests {
assert!(matches!(iter.next(), Some(Ok((10, 100)))));
assert!(matches!(
iter.next(),
Some(Err(MapError::LookupElementError { .. }))
Some(Err(MapError::SyscallError { call, .. })) if call == "bpf_map_lookup_elem"
));
assert!(matches!(iter.next(), Some(Ok((30, 300)))));
assert!(matches!(iter.next(), None));

@ -54,22 +54,12 @@ pub enum MapError {
#[error("the program is not loaded")]
ProgramNotLoaded,
#[error("the BPF_MAP_UPDATE_ELEM syscall failed with code {code} io_error {io_error}")]
UpdateElementError { code: i64, io_error: io::Error },
#[error("the BPF_MAP_LOOKUP_ELEM syscall failed with code {code} io_error {io_error}")]
LookupElementError { code: i64, io_error: io::Error },
#[error("the BPF_MAP_DELETE_ELEM syscall failed with code {code} io_error {io_error}")]
DeleteElementError { code: i64, io_error: io::Error },
#[error(
"the BPF_MAP_LOOKUP_AND_DELETE_ELEM syscall failed with code {code} io_error {io_error}"
)]
LookupAndDeleteElementError { code: i64, io_error: io::Error },
#[error("the BPF_MAP_GET_NEXT_KEY syscall failed with code {code} io_error {io_error}")]
GetNextKeyError { code: i64, io_error: io::Error },
#[error("the `{call}` syscall failed with code {code} io_error {io_error}")]
SyscallError {
call: String,
code: i64,
io_error: io::Error,
},
#[error("map `{name}` is borrowed mutably")]
BorrowError { name: String },
@ -170,7 +160,11 @@ impl<K: Pod, V: Pod> Iterator for MapKeys<'_, K, V> {
}
Err((code, io_error)) => {
self.err = true;
return Some(Err(MapError::GetNextKeyError { code, io_error }));
return Some(Err(MapError::SyscallError {
call: "bpf_map_get_next_key".to_owned(),
code,
io_error,
}));
}
}
}

@ -45,8 +45,13 @@ impl<T: Deref<Target = Map>> ProgramArray<T> {
pub unsafe fn get(&self, key: &u32, flags: u64) -> Result<Option<RawFd>, MapError> {
let fd = self.inner.fd_or_err()?;
let fd = bpf_map_lookup_elem(fd, key, flags)
.map_err(|(code, io_error)| MapError::LookupElementError { code, io_error })?;
let fd = bpf_map_lookup_elem(fd, key, flags).map_err(|(code, io_error)| {
MapError::SyscallError {
call: "bpf_map_lookup_elem".to_owned(),
code,
io_error,
}
})?;
Ok(fd)
}
@ -79,16 +84,26 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>> ProgramArray<T> {
self.check_bounds(index)?;
let prog_fd = program.fd().ok_or(MapError::ProgramNotLoaded)?;
bpf_map_update_elem(fd, &index, &prog_fd, flags)
.map_err(|(code, io_error)| MapError::UpdateElementError { code, io_error })?;
bpf_map_update_elem(fd, &index, &prog_fd, flags).map_err(|(code, io_error)| {
MapError::SyscallError {
call: "bpf_map_update_elem".to_owned(),
code,
io_error,
}
})?;
Ok(())
}
pub unsafe fn pop(&mut self, index: &u32) -> Result<Option<RawFd>, MapError> {
let fd = self.inner.fd_or_err()?;
self.check_bounds(*index)?;
bpf_map_lookup_and_delete_elem(fd, index)
.map_err(|(code, io_error)| MapError::LookupAndDeleteElementError { code, io_error })
bpf_map_lookup_and_delete_elem(fd, index).map_err(|(code, io_error)| {
MapError::SyscallError {
call: "bpf_map_lookup_and_delete_elem".to_owned(),
code,
io_error,
}
})
}
pub fn remove(&mut self, index: &u32) -> Result<(), MapError> {
@ -96,7 +111,11 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>> ProgramArray<T> {
self.check_bounds(*index)?;
bpf_map_delete_elem(fd, index)
.map(|_| ())
.map_err(|(code, io_error)| MapError::DeleteElementError { code, io_error })
.map_err(|(code, io_error)| MapError::SyscallError {
call: "bpf_map_delete_elem".to_owned(),
code,
io_error,
})
}
}

Loading…
Cancel
Save