@ -42,7 +42,6 @@ impl<T: Borrow<MapData>, K: Pod, V: Pod> HashMap<T, K, V> {
pub ( crate ) fn new ( map : T ) -> Result < HashMap < T , K , V > , MapError > {
let data = map . borrow ( ) ;
check_kv_size ::< K , V > ( data ) ? ;
let _ = data . fd_or_err ( ) ? ;
Ok ( HashMap {
inner : map ,
@ -53,7 +52,7 @@ impl<T: Borrow<MapData>, K: Pod, V: Pod> HashMap<T, K, V> {
/// Returns a copy of the value associated with the key.
pub fn get ( & self , key : & K , flags : u64 ) -> Result < V , MapError > {
let fd = self . inner . borrow ( ) . fd _or_err( ) ? ;
let fd = self . inner . borrow ( ) . fd ;
let value = bpf_map_lookup_elem ( fd , key , flags ) . map_err ( | ( _ , io_error ) | SyscallError {
call : "bpf_map_lookup_elem" ,
io_error ,
@ -137,17 +136,24 @@ mod tests {
} )
}
fn new_map ( obj : obj ::Map ) -> MapData {
override_syscall ( | call | match call {
Syscall ::Bpf {
cmd : bpf_cmd ::BPF_MAP_CREATE ,
..
} = > Ok ( 1337 ) ,
call = > panic! ( "unexpected syscall {:?}" , call ) ,
} ) ;
MapData ::create ( obj , "foo" , None ) . unwrap ( )
}
fn sys_error ( value : i32 ) -> SysResult < c_long > {
Err ( ( - 1 , io ::Error ::from_raw_os_error ( value ) ) )
}
#[ test ]
fn test_wrong_key_size ( ) {
let map = MapData {
obj : new_obj_map ( ) ,
fd : None ,
pinned : false ,
} ;
let map = new_map ( new_obj_map ( ) ) ;
assert_matches ! (
HashMap ::< _ , u8 , u32 > ::new ( & map ) ,
Err ( MapError ::InvalidKeySize {
@ -159,11 +165,7 @@ mod tests {
#[ test ]
fn test_wrong_value_size ( ) {
let map = MapData {
obj : new_obj_map ( ) ,
fd : None ,
pinned : false ,
} ;
let map = new_map ( new_obj_map ( ) ) ;
assert_matches ! (
HashMap ::< _ , u32 , u16 > ::new ( & map ) ,
Err ( MapError ::InvalidValueSize {
@ -175,13 +177,8 @@ mod tests {
#[ test ]
fn test_try_from_wrong_map ( ) {
let map_data = MapData {
obj : new_obj_map ( ) ,
fd : None ,
pinned : false ,
} ;
let map = Map ::Array ( map_data ) ;
let map = new_map ( new_obj_map ( ) ) ;
let map = Map ::Array ( map ) ;
assert_matches ! (
HashMap ::< _ , u8 , u32 > ::try_from ( & map ) ,
Err ( MapError ::InvalidMapType { .. } )
@ -190,13 +187,8 @@ mod tests {
#[ test ]
fn test_try_from_wrong_map_values ( ) {
let map_data = MapData {
obj : new_obj_map ( ) ,
fd : None ,
pinned : false ,
} ;
let map = Map ::HashMap ( map_data ) ;
let map = new_map ( new_obj_map ( ) ) ;
let map = Map ::HashMap ( map ) ;
assert_matches ! (
HashMap ::< _ , u32 , u16 > ::try_from ( & map ) ,
Err ( MapError ::InvalidValueSize {
@ -206,47 +198,22 @@ mod tests {
) ;
}
#[ test ]
fn test_new_not_created ( ) {
let mut map = MapData {
obj : new_obj_map ( ) ,
fd : None ,
pinned : false ,
} ;
assert_matches ! (
HashMap ::< _ , u32 , u32 > ::new ( & mut map ) ,
Err ( MapError ::NotCreated { .. } )
) ;
}
#[ test ]
fn test_new_ok ( ) {
let mut map = MapData {
obj : new_obj_map ( ) ,
fd : Some ( 42 ) ,
pinned : false ,
} ;
assert! ( HashMap ::< _ , u32 , u32 > ::new ( & mut map ) . is_ok ( ) ) ;
let map = new_map ( new_obj_map ( ) ) ;
assert! ( HashMap ::< _ , u32 , u32 > ::new ( & map ) . is_ok ( ) ) ;
}
#[ test ]
fn test_try_from_ok ( ) {
let map_data = MapData {
obj : new_obj_map ( ) ,
fd : Some ( 42 ) ,
pinned : false ,
} ;
let map = Map ::HashMap ( map_data ) ;
let map = new_map ( new_obj_map ( ) ) ;
let map = Map ::HashMap ( map ) ;
assert! ( HashMap ::< _ , u32 , u32 > ::try_from ( & map ) . is_ok ( ) )
}
#[ test ]
fn test_try_from_ok_lru ( ) {
let map_data = MapData {
obj : obj ::Map ::Legacy ( LegacyMap {
let map = new_map ( obj ::Map ::Legacy ( LegacyMap {
def : bpf_map_def {
map_type : BPF_MAP_TYPE_LRU_HASH as u32 ,
key_size : 4 ,
@ -258,27 +225,19 @@ mod tests {
section_kind : BpfSectionKind ::Maps ,
symbol_index : None ,
data : Vec ::new ( ) ,
} ) ,
fd : Some ( 42 ) ,
pinned : false ,
} ;
let map = Map ::HashMap ( map_data ) ;
} ) ) ;
let map = Map ::HashMap ( map ) ;
assert! ( HashMap ::< _ , u32 , u32 > ::try_from ( & map ) . is_ok ( ) )
}
#[ test ]
fn test_insert_syscall_error ( ) {
override_syscall ( | _ | sys_error ( EFAULT ) ) ;
let mut map = MapData {
obj : new_obj_map ( ) ,
fd : Some ( 42 ) ,
pinned : false ,
} ;
let mut map = new_map ( new_obj_map ( ) ) ;
let mut hm = HashMap ::< _ , u32 , u32 > ::new ( & mut map ) . unwrap ( ) ;
override_syscall ( | _ | sys_error ( EFAULT ) ) ;
assert_matches ! (
hm . insert ( 1 , 42 , 0 ) ,
Err ( MapError ::SyscallError ( SyscallError { call : "bpf_map_update_elem" , io_error } ) ) if io_error . raw_os_error ( ) = = Some ( EFAULT )
@ -287,6 +246,9 @@ mod tests {
#[ test ]
fn test_insert_ok ( ) {
let mut map = new_map ( new_obj_map ( ) ) ;
let mut hm = HashMap ::< _ , u32 , u32 > ::new ( & mut map ) . unwrap ( ) ;
override_syscall ( | call | match call {
Syscall ::Bpf {
cmd : bpf_cmd ::BPF_MAP_UPDATE_ELEM ,
@ -295,18 +257,14 @@ mod tests {
_ = > sys_error ( EFAULT ) ,
} ) ;
let mut map = MapData {
obj : new_obj_map ( ) ,
fd : Some ( 42 ) ,
pinned : false ,
} ;
let mut hm = HashMap ::< _ , u32 , u32 > ::new ( & mut map ) . unwrap ( ) ;
assert! ( hm . insert ( 1 , 42 , 0 ) . is_ok ( ) ) ;
}
#[ test ]
fn test_insert_boxed_ok ( ) {
let mut map = new_map ( new_obj_map ( ) ) ;
let mut hm = HashMap ::< _ , u32 , u32 > ::new ( & mut map ) . unwrap ( ) ;
override_syscall ( | call | match call {
Syscall ::Bpf {
cmd : bpf_cmd ::BPF_MAP_UPDATE_ELEM ,
@ -315,27 +273,16 @@ mod tests {
_ = > sys_error ( EFAULT ) ,
} ) ;
let mut map = MapData {
obj : new_obj_map ( ) ,
fd : Some ( 42 ) ,
pinned : false ,
} ;
let mut hm = HashMap ::< _ , u32 , u32 > ::new ( & mut map ) . unwrap ( ) ;
assert! ( hm . insert ( Box ::new ( 1 ) , Box ::new ( 42 ) , 0 ) . is_ok ( ) ) ;
}
#[ test ]
fn test_remove_syscall_error ( ) {
override_syscall ( | _ | sys_error ( EFAULT ) ) ;
let mut map = MapData {
obj : new_obj_map ( ) ,
fd : Some ( 42 ) ,
pinned : false ,
} ;
let mut map = new_map ( new_obj_map ( ) ) ;
let mut hm = HashMap ::< _ , u32 , u32 > ::new ( & mut map ) . unwrap ( ) ;
override_syscall ( | _ | sys_error ( EFAULT ) ) ;
assert_matches ! (
hm . remove ( & 1 ) ,
Err ( MapError ::SyscallError ( SyscallError { call : "bpf_map_delete_elem" , io_error } ) ) if io_error . raw_os_error ( ) = = Some ( EFAULT )
@ -344,6 +291,9 @@ mod tests {
#[ test ]
fn test_remove_ok ( ) {
let mut map = new_map ( new_obj_map ( ) ) ;
let mut hm = HashMap ::< _ , u32 , u32 > ::new ( & mut map ) . unwrap ( ) ;
override_syscall ( | call | match call {
Syscall ::Bpf {
cmd : bpf_cmd ::BPF_MAP_DELETE_ELEM ,
@ -352,24 +302,13 @@ mod tests {
_ = > sys_error ( EFAULT ) ,
} ) ;
let mut map = MapData {
obj : new_obj_map ( ) ,
fd : Some ( 42 ) ,
pinned : false ,
} ;
let mut hm = HashMap ::< _ , u32 , u32 > ::new ( & mut map ) . unwrap ( ) ;
assert! ( hm . remove ( & 1 ) . is_ok ( ) ) ;
}
#[ test ]
fn test_get_syscall_error ( ) {
let map = new_map ( new_obj_map ( ) ) ;
override_syscall ( | _ | sys_error ( EFAULT ) ) ;
let map = MapData {
obj : new_obj_map ( ) ,
fd : Some ( 42 ) ,
pinned : false ,
} ;
let hm = HashMap ::< _ , u32 , u32 > ::new ( & map ) . unwrap ( ) ;
assert_matches ! (
@ -380,6 +319,7 @@ mod tests {
#[ test ]
fn test_get_not_found ( ) {
let map = new_map ( new_obj_map ( ) ) ;
override_syscall ( | call | match call {
Syscall ::Bpf {
cmd : bpf_cmd ::BPF_MAP_LOOKUP_ELEM ,
@ -387,11 +327,6 @@ mod tests {
} = > sys_error ( ENOENT ) ,
_ = > sys_error ( EFAULT ) ,
} ) ;
let map = MapData {
obj : new_obj_map ( ) ,
fd : Some ( 42 ) ,
pinned : false ,
} ;
let hm = HashMap ::< _ , u32 , u32 > ::new ( & map ) . unwrap ( ) ;
assert_matches ! ( hm . get ( & 1 , 0 ) , Err ( MapError ::KeyNotFound ) ) ;
@ -416,6 +351,7 @@ mod tests {
#[ test ]
fn test_keys_empty ( ) {
let map = new_map ( new_obj_map ( ) ) ;
override_syscall ( | call | match call {
Syscall ::Bpf {
cmd : bpf_cmd ::BPF_MAP_GET_NEXT_KEY ,
@ -423,11 +359,6 @@ mod tests {
} = > sys_error ( ENOENT ) ,
_ = > sys_error ( EFAULT ) ,
} ) ;
let map = MapData {
obj : new_obj_map ( ) ,
fd : Some ( 42 ) ,
pinned : false ,
} ;
let hm = HashMap ::< _ , u32 , u32 > ::new ( & map ) . unwrap ( ) ;
let keys = hm . keys ( ) . collect ::< Result < Vec < _ > , _ > > ( ) ;
assert_matches ! ( keys , Ok ( ks ) if ks . is_empty ( ) )
@ -463,6 +394,8 @@ mod tests {
// to support stable as well.
#[ cfg_attr(miri, ignore) ]
fn test_keys ( ) {
let map = new_map ( new_obj_map ( ) ) ;
override_syscall ( | call | match call {
Syscall ::Bpf {
cmd : bpf_cmd ::BPF_MAP_GET_NEXT_KEY ,
@ -471,11 +404,6 @@ mod tests {
_ = > sys_error ( EFAULT ) ,
} ) ;
let map = MapData {
obj : new_obj_map ( ) ,
fd : Some ( 42 ) ,
pinned : false ,
} ;
let hm = HashMap ::< _ , u32 , u32 > ::new ( & map ) . unwrap ( ) ;
let keys = hm . keys ( ) . collect ::< Result < Vec < _ > , _ > > ( ) . unwrap ( ) ;
@ -488,6 +416,7 @@ mod tests {
// to support stable as well.
#[ cfg_attr(miri, ignore) ]
fn test_keys_error ( ) {
let map = new_map ( new_obj_map ( ) ) ;
override_syscall ( | call | match call {
Syscall ::Bpf {
cmd : bpf_cmd ::BPF_MAP_GET_NEXT_KEY ,
@ -503,11 +432,6 @@ mod tests {
}
_ = > sys_error ( EFAULT ) ,
} ) ;
let map = MapData {
obj : new_obj_map ( ) ,
fd : Some ( 42 ) ,
pinned : false ,
} ;
let hm = HashMap ::< _ , u32 , u32 > ::new ( & map ) . unwrap ( ) ;
let mut keys = hm . keys ( ) ;
@ -529,6 +453,7 @@ mod tests {
// to support stable as well.
#[ cfg_attr(miri, ignore) ]
fn test_iter ( ) {
let map = new_map ( new_obj_map ( ) ) ;
override_syscall ( | call | match call {
Syscall ::Bpf {
cmd : bpf_cmd ::BPF_MAP_GET_NEXT_KEY ,
@ -540,11 +465,6 @@ mod tests {
} = > lookup_elem ( attr ) ,
_ = > sys_error ( EFAULT ) ,
} ) ;
let map = MapData {
obj : new_obj_map ( ) ,
fd : Some ( 42 ) ,
pinned : false ,
} ;
let hm = HashMap ::< _ , u32 , u32 > ::new ( & map ) . unwrap ( ) ;
let items = hm . iter ( ) . collect ::< Result < Vec < _ > , _ > > ( ) . unwrap ( ) ;
assert_eq! ( & items , & [ ( 10 , 100 ) , ( 20 , 200 ) , ( 30 , 300 ) ] )
@ -556,6 +476,7 @@ mod tests {
// to support stable as well.
#[ cfg_attr(miri, ignore) ]
fn test_iter_key_deleted ( ) {
let map = new_map ( new_obj_map ( ) ) ;
override_syscall ( | call | match call {
Syscall ::Bpf {
cmd : bpf_cmd ::BPF_MAP_GET_NEXT_KEY ,
@ -577,11 +498,6 @@ mod tests {
}
_ = > sys_error ( EFAULT ) ,
} ) ;
let map = MapData {
obj : new_obj_map ( ) ,
fd : Some ( 42 ) ,
pinned : false ,
} ;
let hm = HashMap ::< _ , u32 , u32 > ::new ( & map ) . unwrap ( ) ;
let items = hm . iter ( ) . collect ::< Result < Vec < _ > , _ > > ( ) . unwrap ( ) ;
@ -594,6 +510,7 @@ mod tests {
// to support stable as well.
#[ cfg_attr(miri, ignore) ]
fn test_iter_key_error ( ) {
let map = new_map ( new_obj_map ( ) ) ;
override_syscall ( | call | match call {
Syscall ::Bpf {
cmd : bpf_cmd ::BPF_MAP_GET_NEXT_KEY ,
@ -615,11 +532,6 @@ mod tests {
} = > lookup_elem ( attr ) ,
_ = > sys_error ( EFAULT ) ,
} ) ;
let map = MapData {
obj : new_obj_map ( ) ,
fd : Some ( 42 ) ,
pinned : false ,
} ;
let hm = HashMap ::< _ , u32 , u32 > ::new ( & map ) . unwrap ( ) ;
let mut iter = hm . iter ( ) ;
@ -641,6 +553,7 @@ mod tests {
// to support stable as well.
#[ cfg_attr(miri, ignore) ]
fn test_iter_value_error ( ) {
let map = new_map ( new_obj_map ( ) ) ;
override_syscall ( | call | match call {
Syscall ::Bpf {
cmd : bpf_cmd ::BPF_MAP_GET_NEXT_KEY ,
@ -662,11 +575,6 @@ mod tests {
}
_ = > sys_error ( EFAULT ) ,
} ) ;
let map = MapData {
obj : new_obj_map ( ) ,
fd : Some ( 42 ) ,
pinned : false ,
} ;
let hm = HashMap ::< _ , u32 , u32 > ::new ( & map ) . unwrap ( ) ;
let mut iter = hm . iter ( ) ;