diff --git a/src/bpf.rs b/src/bpf.rs index 95718c42..e4221de3 100644 --- a/src/bpf.rs +++ b/src/bpf.rs @@ -1,4 +1,7 @@ -use std::collections::HashMap; +use std::{ + cell::{Ref, RefCell, RefMut}, + collections::HashMap, +}; use thiserror::Error; @@ -45,7 +48,7 @@ unsafe impl object::Pod for bpf_map_def {} #[derive(Debug)] pub struct Bpf { - maps: HashMap, + maps: HashMap>, programs: HashMap, } @@ -91,18 +94,18 @@ impl Bpf { Ok(Bpf { maps: maps .drain(..) - .map(|map| (map.obj.name.clone(), map)) + .map(|map| (map.obj.name.clone(), RefCell::new(map))) .collect(), programs, }) } - pub fn map(&self, name: &str) -> Option<&Map> { - self.maps.get(name) + pub fn map(&self, name: &str) -> Option> { + self.maps.get(name).map(|cell| cell.borrow()) } - pub fn map_mut(&mut self, name: &str) -> Option<&mut Map> { - self.maps.get_mut(name) + pub fn map_mut(&self, name: &str) -> Option> { + self.maps.get(name).map(|cell| cell.borrow_mut()) } pub fn program(&self, name: &str) -> Option<&Program> { diff --git a/src/maps/hash_map.rs b/src/maps/hash_map.rs index 7ae4662e..3607b8fd 100644 --- a/src/maps/hash_map.rs +++ b/src/maps/hash_map.rs @@ -1,4 +1,10 @@ -use std::{convert::TryFrom, marker::PhantomData, mem}; +use std::{ + cell::{Ref, RefMut}, + convert::TryFrom, + marker::PhantomData, + mem, + ops::{Deref, DerefMut}, +}; use crate::{ generated::bpf_map_type::BPF_MAP_TYPE_HASH, @@ -10,15 +16,15 @@ use crate::{ Pod, RawFd, }; -pub struct HashMap, K, V> { +pub struct HashMap, K, V> { inner: T, _k: PhantomData, _v: PhantomData, } -impl, K: Pod, V: Pod> HashMap { +impl, K: Pod, V: Pod> HashMap { pub fn new(map: T) -> Result, MapError> { - let inner = map.as_ref(); + let inner = map.deref(); let map_type = inner.obj.def.map_type; if map_type != BPF_MAP_TYPE_HASH { return Err(MapError::InvalidMapType { @@ -45,7 +51,7 @@ impl, K: Pod, V: Pod> HashMap { } pub unsafe fn get(&self, key: &K, flags: u64) -> Result, MapError> { - let fd = self.inner.as_ref().fd_or_err()?; + let fd = self.inner.deref().fd_or_err()?; bpf_map_lookup_elem(fd, key, flags) .map_err(|(code, io_error)| MapError::LookupElementFailed { code, io_error }) } @@ -59,31 +65,31 @@ impl, K: Pod, V: Pod> HashMap { } } -impl + AsMut, K: Pod, V: Pod> HashMap { +impl, K: Pod, V: Pod> HashMap { pub fn insert(&mut self, key: K, value: V, flags: u64) -> Result<(), MapError> { - let fd = self.inner.as_ref().fd_or_err()?; + let fd = self.inner.deref_mut().fd_or_err()?; bpf_map_update_elem(fd, &key, &value, flags) .map_err(|(code, io_error)| MapError::UpdateElementFailed { code, io_error })?; Ok(()) } pub unsafe fn pop(&mut self, key: &K) -> Result, MapError> { - let fd = self.inner.as_ref().fd_or_err()?; + let fd = self.inner.deref_mut().fd_or_err()?; bpf_map_lookup_and_delete_elem(fd, key) .map_err(|(code, io_error)| MapError::LookupAndDeleteElementFailed { code, io_error }) } pub fn remove(&mut self, key: &K) -> Result<(), MapError> { - let fd = self.inner.as_ref().fd_or_err()?; + let fd = self.inner.deref_mut().fd_or_err()?; bpf_map_delete_elem(fd, key) .map(|_| ()) .map_err(|(code, io_error)| MapError::DeleteElementFailed { code, io_error }) } } -impl, K: Pod, V: Pod> IterableMap for HashMap { +impl, K: Pod, V: Pod> IterableMap for HashMap { fn fd(&self) -> Result { - self.inner.as_ref().fd_or_err() + self.inner.deref().fd_or_err() } unsafe fn get(&self, key: &K) -> Result, MapError> { @@ -91,6 +97,22 @@ impl, K: Pod, V: Pod> IterableMap for HashMap { } } +impl<'a, K: Pod, V: Pod> TryFrom> for HashMap, K, V> { + type Error = MapError; + + fn try_from(inner: Ref<'a, Map>) -> Result, K, V>, MapError> { + HashMap::new(inner) + } +} + +impl<'a, K: Pod, V: Pod> TryFrom> for HashMap, K, V> { + type Error = MapError; + + fn try_from(inner: RefMut<'a, Map>) -> Result, K, V>, MapError> { + HashMap::new(inner) + } +} + impl<'a, K: Pod, V: Pod> TryFrom<&'a Map> for HashMap<&'a Map, K, V> { type Error = MapError; diff --git a/src/maps/perf_map.rs b/src/maps/perf_map.rs index d23dc99b..26628bea 100644 --- a/src/maps/perf_map.rs +++ b/src/maps/perf_map.rs @@ -1,7 +1,10 @@ use std::{ + cell::RefMut, convert::TryFrom, ffi::c_void, - fs, io, mem, ptr, slice, + fs, io, mem, + ops::DerefMut, + ptr, slice, str::FromStr, sync::atomic::{self, AtomicPtr, Ordering}, }; @@ -277,18 +280,18 @@ pub enum PerfMapError { }, } -pub struct PerfMap<'map> { - map: &'map Map, +pub struct PerfMap> { + map: T, cpu_fds: Vec<(u32, RawFd)>, buffers: Vec>, } -impl<'map> PerfMap<'map> { +impl> PerfMap { pub fn new( - map: &'map Map, + map: T, cpu_ids: Option>, page_count: Option, - ) -> Result, PerfMapError> { + ) -> Result, PerfMapError> { let map_type = map.obj.def.map_type; if map_type != BPF_MAP_TYPE_PERF_EVENT_ARRAY { return Err(MapError::InvalidMapType { @@ -345,11 +348,19 @@ impl<'map> PerfMap<'map> { } } -impl<'inner> TryFrom<&'inner Map> for PerfMap<'inner> { +impl<'a> TryFrom> for PerfMap> { type Error = PerfMapError; - fn try_from(inner: &'inner Map) -> Result, PerfMapError> { - PerfMap::new(inner, None, None) + fn try_from(a: RefMut<'a, Map>) -> Result>, PerfMapError> { + PerfMap::new(a, None, None) + } +} + +impl<'a> TryFrom<&'a mut Map> for PerfMap<&'a mut Map> { + type Error = PerfMapError; + + fn try_from(a: &'a mut Map) -> Result, PerfMapError> { + PerfMap::new(a, None, None) } }