|
|
@ -93,7 +93,7 @@ pub enum ProgramError {
|
|
|
|
#[error("the program is not attached")]
|
|
|
|
#[error("the program is not attached")]
|
|
|
|
NotAttached,
|
|
|
|
NotAttached,
|
|
|
|
|
|
|
|
|
|
|
|
#[error("the BPF_PROG_LOAD syscall failed: {io_error}\nVerifier output:\n{verifier_log}")]
|
|
|
|
#[error("the BPF_PROG_LOAD syscall failed. Verifier output: {verifier_log}")]
|
|
|
|
LoadError {
|
|
|
|
LoadError {
|
|
|
|
#[source]
|
|
|
|
#[source]
|
|
|
|
io_error: io::Error,
|
|
|
|
io_error: io::Error,
|
|
|
@ -248,11 +248,12 @@ impl VerifierLog {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn grow(&mut self) {
|
|
|
|
fn grow(&mut self) {
|
|
|
|
self.buf.reserve(cmp::max(
|
|
|
|
let len = cmp::max(
|
|
|
|
MIN_LOG_BUF_SIZE,
|
|
|
|
MIN_LOG_BUF_SIZE,
|
|
|
|
cmp::min(MAX_LOG_BUF_SIZE, self.buf.capacity() * 3),
|
|
|
|
cmp::min(MAX_LOG_BUF_SIZE, self.buf.capacity() * 10),
|
|
|
|
));
|
|
|
|
);
|
|
|
|
self.buf.resize(self.buf.capacity(), 0);
|
|
|
|
self.buf.resize(len, 0);
|
|
|
|
|
|
|
|
self.reset();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn reset(&mut self) {
|
|
|
|
fn reset(&mut self) {
|
|
|
@ -271,6 +272,7 @@ impl VerifierLog {
|
|
|
|
.iter()
|
|
|
|
.iter()
|
|
|
|
.position(|b| *b == 0)
|
|
|
|
.position(|b| *b == 0)
|
|
|
|
.unwrap_or(self.buf.len() - 1);
|
|
|
|
.unwrap_or(self.buf.len() - 1);
|
|
|
|
|
|
|
|
self.buf[pos] = 0;
|
|
|
|
self.buf.truncate(pos + 1);
|
|
|
|
self.buf.truncate(pos + 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -295,11 +297,10 @@ fn load_program(prog_type: bpf_prog_type, data: &mut ProgramData) -> Result<(),
|
|
|
|
..
|
|
|
|
..
|
|
|
|
} = obj;
|
|
|
|
} = obj;
|
|
|
|
|
|
|
|
|
|
|
|
let mut ret = Ok(-1);
|
|
|
|
|
|
|
|
let mut log_buf = VerifierLog::new();
|
|
|
|
let mut log_buf = VerifierLog::new();
|
|
|
|
for i in 0..3 {
|
|
|
|
let mut retries = 0;
|
|
|
|
log_buf.reset();
|
|
|
|
let mut ret;
|
|
|
|
|
|
|
|
loop {
|
|
|
|
ret = bpf_load_program(
|
|
|
|
ret = bpf_load_program(
|
|
|
|
prog_type,
|
|
|
|
prog_type,
|
|
|
|
instructions,
|
|
|
|
instructions,
|
|
|
@ -312,11 +313,14 @@ fn load_program(prog_type: bpf_prog_type, data: &mut ProgramData) -> Result<(),
|
|
|
|
*fd = Some(*prog_fd as RawFd);
|
|
|
|
*fd = Some(*prog_fd as RawFd);
|
|
|
|
return Ok(());
|
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Err((_, io_error)) if i == 0 || io_error.raw_os_error() == Some(ENOSPC) => {
|
|
|
|
Err((_, io_error)) if retries == 0 || io_error.raw_os_error() == Some(ENOSPC) => {
|
|
|
|
|
|
|
|
if retries == 10 {
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
retries += 1;
|
|
|
|
log_buf.grow();
|
|
|
|
log_buf.grow();
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => break,
|
|
|
|
Err(_) => break,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -324,7 +328,10 @@ fn load_program(prog_type: bpf_prog_type, data: &mut ProgramData) -> Result<(),
|
|
|
|
log_buf.truncate();
|
|
|
|
log_buf.truncate();
|
|
|
|
return Err(ProgramError::LoadError {
|
|
|
|
return Err(ProgramError::LoadError {
|
|
|
|
io_error,
|
|
|
|
io_error,
|
|
|
|
verifier_log: log_buf.as_c_str().unwrap().to_string_lossy().to_string(),
|
|
|
|
verifier_log: log_buf
|
|
|
|
|
|
|
|
.as_c_str()
|
|
|
|
|
|
|
|
.map(|s| s.to_string_lossy().to_string())
|
|
|
|
|
|
|
|
.unwrap_or_else(|| "[none]".to_owned()),
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|