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 mut map = Map { obj, fd: None };
let fd = map.create()?; let fd = map.create()?;
if !map.obj.data.is_empty() && map.obj.name != ".bss" { 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) bpf_map_update_elem_ptr(fd, &0 as *const _, map.obj.data.as_ptr(), 0).map_err(
.map_err(|(code, io_error)| MapError::UpdateElementError { code, io_error })?; |(code, io_error)| MapError::SyscallError {
call: "bpf_map_update_elem".to_owned(),
code,
io_error,
},
)?;
} }
maps.push(map); 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> { pub unsafe fn get(&self, key: &K, flags: u64) -> Result<Option<V>, MapError> {
let fd = self.inner.deref().fd_or_err()?; let fd = self.inner.deref().fd_or_err()?;
bpf_map_lookup_elem(fd, key, flags) bpf_map_lookup_elem(fd, key, flags).map_err(|(code, io_error)| MapError::SyscallError {
.map_err(|(code, io_error)| MapError::LookupElementError { code, io_error }) call: "bpf_map_lookup_elem".to_owned(),
code,
io_error,
})
} }
pub unsafe fn iter<'coll>(&'coll self) -> MapIter<'coll, K, V> { 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> { 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> { pub fn insert(&mut self, key: K, value: V, flags: u64) -> Result<(), MapError> {
let fd = self.inner.deref_mut().fd_or_err()?; let fd = self.inner.deref_mut().fd_or_err()?;
bpf_map_update_elem(fd, &key, &value, flags) bpf_map_update_elem(fd, &key, &value, flags).map_err(|(code, io_error)| {
.map_err(|(code, io_error)| MapError::UpdateElementError { code, io_error })?; MapError::SyscallError {
call: "bpf_map_update_elem".to_owned(),
code,
io_error,
}
})?;
Ok(()) Ok(())
} }
pub unsafe fn pop(&mut self, key: &K) -> Result<Option<V>, MapError> { pub unsafe fn pop(&mut self, key: &K) -> Result<Option<V>, MapError> {
let fd = self.inner.deref_mut().fd_or_err()?; let fd = self.inner.deref_mut().fd_or_err()?;
bpf_map_lookup_and_delete_elem(fd, key) bpf_map_lookup_and_delete_elem(fd, key).map_err(|(code, io_error)| MapError::SyscallError {
.map_err(|(code, io_error)| MapError::LookupAndDeleteElementError { code, io_error }) call: "bpf_map_lookup_and_delete_elem".to_owned(),
code,
io_error,
})
} }
pub fn remove(&mut self, key: &K) -> Result<(), MapError> { pub fn remove(&mut self, key: &K) -> Result<(), MapError> {
let fd = self.inner.deref_mut().fd_or_err()?; let fd = self.inner.deref_mut().fd_or_err()?;
bpf_map_delete_elem(fd, key) bpf_map_delete_elem(fd, key)
.map(|_| ()) .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!( assert!(matches!(
hm.insert(1, 42, 0), 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!( assert!(matches!(
hm.remove(&1), 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!( assert!(matches!(
unsafe { hm.get(&1, 0) }, 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!( assert!(matches!(
unsafe { hm.pop(&1) }, 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(Ok(20))));
assert!(matches!( assert!(matches!(
keys.next(), keys.next(),
Some(Err(MapError::GetNextKeyError { .. })) Some(Err(MapError::SyscallError { call, .. })) if call == "bpf_map_get_next_key"
)); ));
assert!(matches!(keys.next(), None)); assert!(matches!(keys.next(), None));
} }
@ -593,7 +608,7 @@ mod tests {
assert!(matches!(iter.next(), Some(Ok((20, 200))))); assert!(matches!(iter.next(), Some(Ok((20, 200)))));
assert!(matches!( assert!(matches!(
iter.next(), iter.next(),
Some(Err(MapError::GetNextKeyError { .. })) Some(Err(MapError::SyscallError { call, .. })) if call == "bpf_map_get_next_key"
)); ));
assert!(matches!(iter.next(), None)); assert!(matches!(iter.next(), None));
} }
@ -631,7 +646,7 @@ mod tests {
assert!(matches!(iter.next(), Some(Ok((10, 100))))); assert!(matches!(iter.next(), Some(Ok((10, 100)))));
assert!(matches!( assert!(matches!(
iter.next(), 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(), Some(Ok((30, 300)))));
assert!(matches!(iter.next(), None)); assert!(matches!(iter.next(), None));

@ -54,22 +54,12 @@ pub enum MapError {
#[error("the program is not loaded")] #[error("the program is not loaded")]
ProgramNotLoaded, ProgramNotLoaded,
#[error("the BPF_MAP_UPDATE_ELEM syscall failed with code {code} io_error {io_error}")] #[error("the `{call}` syscall failed with code {code} io_error {io_error}")]
UpdateElementError { code: i64, io_error: io::Error }, SyscallError {
call: String,
#[error("the BPF_MAP_LOOKUP_ELEM syscall failed with code {code} io_error {io_error}")] code: i64,
LookupElementError { code: i64, io_error: io::Error }, 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("map `{name}` is borrowed mutably")] #[error("map `{name}` is borrowed mutably")]
BorrowError { name: String }, BorrowError { name: String },
@ -170,7 +160,11 @@ impl<K: Pod, V: Pod> Iterator for MapKeys<'_, K, V> {
} }
Err((code, io_error)) => { Err((code, io_error)) => {
self.err = true; 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> { pub unsafe fn get(&self, key: &u32, flags: u64) -> Result<Option<RawFd>, MapError> {
let fd = self.inner.fd_or_err()?; let fd = self.inner.fd_or_err()?;
let fd = bpf_map_lookup_elem(fd, key, flags) let fd = bpf_map_lookup_elem(fd, key, flags).map_err(|(code, io_error)| {
.map_err(|(code, io_error)| MapError::LookupElementError { code, io_error })?; MapError::SyscallError {
call: "bpf_map_lookup_elem".to_owned(),
code,
io_error,
}
})?;
Ok(fd) Ok(fd)
} }
@ -79,16 +84,26 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>> ProgramArray<T> {
self.check_bounds(index)?; self.check_bounds(index)?;
let prog_fd = program.fd().ok_or(MapError::ProgramNotLoaded)?; let prog_fd = program.fd().ok_or(MapError::ProgramNotLoaded)?;
bpf_map_update_elem(fd, &index, &prog_fd, flags) bpf_map_update_elem(fd, &index, &prog_fd, flags).map_err(|(code, io_error)| {
.map_err(|(code, io_error)| MapError::UpdateElementError { code, io_error })?; MapError::SyscallError {
call: "bpf_map_update_elem".to_owned(),
code,
io_error,
}
})?;
Ok(()) Ok(())
} }
pub unsafe fn pop(&mut self, index: &u32) -> Result<Option<RawFd>, MapError> { pub unsafe fn pop(&mut self, index: &u32) -> Result<Option<RawFd>, MapError> {
let fd = self.inner.fd_or_err()?; let fd = self.inner.fd_or_err()?;
self.check_bounds(*index)?; self.check_bounds(*index)?;
bpf_map_lookup_and_delete_elem(fd, index) bpf_map_lookup_and_delete_elem(fd, index).map_err(|(code, io_error)| {
.map_err(|(code, io_error)| MapError::LookupAndDeleteElementError { 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> { 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)?; self.check_bounds(*index)?;
bpf_map_delete_elem(fd, index) bpf_map_delete_elem(fd, index)
.map(|_| ()) .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