@ -3,7 +3,7 @@ use crate::{
obj ::{ btf ::BtfType , copy_instructions } ,
Btf ,
} ;
use libc ::{ c_char , c_long , close , ENOENT };
use libc ::{ c_char , c_long , close , ENOENT , ENOSPC };
use std ::{
cmp ::{ self , min } ,
@ -78,19 +78,21 @@ pub(crate) struct BpfLoadProgramAttrs<'a> {
pub ( crate ) attach_btf_obj_fd : Option < u32 > ,
pub ( crate ) attach_btf_id : Option < u32 > ,
pub ( crate ) attach_prog_fd : Option < RawFd > ,
pub ( crate ) log : & ' a mut VerifierLog ,
pub ( crate ) func_info_rec_size : usize ,
pub ( crate ) func_info : FuncSecInfo ,
pub ( crate ) line_info_rec_size : usize ,
pub ( crate ) line_info : LineSecInfo ,
}
pub ( crate ) fn bpf_load_program ( aya_attr : BpfLoadProgramAttrs ) -> SysResult {
pub ( crate ) fn bpf_load_program (
aya_attr : & BpfLoadProgramAttrs ,
logger : & mut VerifierLog ,
) -> SysResult {
let mut attr = unsafe { mem ::zeroed ::< bpf_attr > ( ) } ;
let u = unsafe { & mut attr . __bindgen_anon_3 } ;
if let Some ( prog_name ) = aya_attr . name {
if let Some ( prog_name ) = & aya_attr . name {
let mut name : [ c_char ; 16 ] = [ 0 ; 16 ] ;
let name_bytes = prog_name . to_bytes ( ) ;
let len = min ( name . len ( ) , name_bytes . len ( ) ) ;
@ -127,7 +129,7 @@ pub(crate) fn bpf_load_program(aya_attr: BpfLoadProgramAttrs) -> SysResult {
u . func_info_rec_size = aya_attr . func_info_rec_size as u32 ;
}
}
let log_buf = aya_attr. log. buf ( ) ;
let log_buf = logger . buf ( ) ;
if log_buf . capacity ( ) > 0 {
u . log_level = 7 ;
u . log_buf = log_buf . as_mut_ptr ( ) as u64 ;
@ -443,7 +445,7 @@ pub(crate) fn bpf_raw_tracepoint_open(name: Option<&CStr>, prog_fd: RawFd) -> Sy
sys_bpf ( bpf_cmd ::BPF_RAW_TRACEPOINT_OPEN , & attr )
}
pub ( crate ) fn bpf_load_btf ( raw_btf : & [ u8 ] , log : & mut VerifierLog ) -> Result < RawFd , io ::Error > {
pub ( crate ) fn bpf_load_btf ( raw_btf : & [ u8 ] , log : & mut VerifierLog ) -> SysResult {
let mut attr = unsafe { mem ::zeroed ::< bpf_attr > ( ) } ;
let u = unsafe { & mut attr . __bindgen_anon_7 } ;
u . btf = raw_btf . as_ptr ( ) as * const _ as u64 ;
@ -454,10 +456,7 @@ pub(crate) fn bpf_load_btf(raw_btf: &[u8], log: &mut VerifierLog) -> Result<RawF
u . btf_log_buf = log_buf . as_mut_ptr ( ) as u64 ;
u . btf_log_size = log_buf . capacity ( ) as u32 ;
}
match sys_bpf ( bpf_cmd ::BPF_BTF_LOAD , & attr ) {
Ok ( v ) = > Ok ( v as RawFd ) ,
Err ( ( _ , err ) ) = > Err ( err ) ,
}
sys_bpf ( bpf_cmd ::BPF_BTF_LOAD , & attr )
}
pub ( crate ) fn bpf_btf_get_fd_by_id ( id : u32 ) -> Result < RawFd , io ::Error > {
@ -733,3 +732,37 @@ pub(crate) fn is_btf_type_tag_supported() -> bool {
pub fn sys_bpf ( cmd : bpf_cmd , attr : & bpf_attr ) -> SysResult {
syscall ( Syscall ::Bpf { cmd , attr } )
}
pub ( crate ) fn retry_with_verifier_logs < F > (
max_retries : usize ,
log : & mut VerifierLog ,
f : F ,
) -> SysResult
where
F : Fn ( & mut VerifierLog ) -> SysResult ,
{
// 1. Try the syscall
let ret = f ( log ) ;
if ret . is_ok ( ) {
return ret ;
}
// 2. Grow the log buffer so we can capture verifier output
// Retry this up to max_retries times
log . grow ( ) ;
let mut retries = 0 ;
loop {
let ret = f ( log ) ;
match ret {
Err ( ( v , io_error ) ) if retries = = 0 | | io_error . raw_os_error ( ) = = Some ( ENOSPC ) = > {
if retries = = max_retries {
return Err ( ( v , io_error ) ) ;
}
retries + = 1 ;
log . grow ( ) ;
}
r = > return r ,
}
}
}