Merge pull request #801 from aya-rs/kill-kernel-on-soft-lockup

xtask: terminate QEMU on "BUG: soft lockup"
pull/803/head
Tamir Duberstein 1 year ago committed by GitHub
commit 4bb52ad34c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -456,20 +456,30 @@ pub fn run(opts: Options) -> Result<()> {
let stderr = stderr.take().unwrap(); let stderr = stderr.take().unwrap();
let stderr = BufReader::new(stderr); let stderr = BufReader::new(stderr);
fn terminate_if_contains_kernel_panic( const TERMINATE_AFTER_COUNT: &[(&str, usize)] =
line: &str, &[("end Kernel panic", 0), ("watchdog: BUG: soft lockup", 1)];
stdin: &Arc<Mutex<ChildStdin>>, let mut counts = [0; TERMINATE_AFTER_COUNT.len()];
) -> anyhow::Result<()> {
if line.contains("end Kernel panic") { let mut terminate_if_kernel_hang =
println!("kernel panic detected; terminating QEMU"); move |line: &str, stdin: &Arc<Mutex<ChildStdin>>| -> anyhow::Result<()> {
if let Some(i) = TERMINATE_AFTER_COUNT
.iter()
.position(|(marker, _)| line.contains(marker))
{
counts[i] += 1;
let (marker, max) = TERMINATE_AFTER_COUNT[i];
if counts[i] > max {
println!("{marker} detected > {max} times; terminating QEMU");
let mut stdin = stdin.lock().unwrap(); let mut stdin = stdin.lock().unwrap();
stdin stdin
.write_all(&[0x01, b'x']) .write_all(&[0x01, b'x'])
.context("failed to write to stdin")?; .context("failed to write to stdin")?;
println!("waiting for QEMU to terminate"); println!("waiting for QEMU to terminate");
} }
Ok(())
} }
Ok(())
};
let stderr = { let stderr = {
let stdin = stdin.clone(); let stdin = stdin.clone();
@ -478,8 +488,7 @@ pub fn run(opts: Options) -> Result<()> {
for line in stderr.lines() { for line in stderr.lines() {
let line = line.context("failed to read line from stderr")?; let line = line.context("failed to read line from stderr")?;
eprintln!("{}", line); eprintln!("{}", line);
// Try to get QEMU to exit on kernel panic; otherwise it might hang indefinitely. terminate_if_kernel_hang(&line, &stdin)?;
terminate_if_contains_kernel_panic(&line, &stdin)?;
} }
anyhow::Ok(()) anyhow::Ok(())
}) })
@ -490,8 +499,7 @@ pub fn run(opts: Options) -> Result<()> {
for line in stdout.lines() { for line in stdout.lines() {
let line = line.context("failed to read line from stdout")?; let line = line.context("failed to read line from stdout")?;
println!("{}", line); println!("{}", line);
// Try to get QEMU to exit on kernel panic; otherwise it might hang indefinitely. terminate_if_kernel_hang(&line, &stdin)?;
terminate_if_contains_kernel_panic(&line, &stdin)?;
// The init program will print "init: success" or "init: failure" to indicate // The init program will print "init: success" or "init: failure" to indicate
// the outcome of running the binaries it found in /bin. // the outcome of running the binaries it found in /bin.
if let Some(line) = line.strip_prefix("init: ") { if let Some(line) = line.strip_prefix("init: ") {

Loading…
Cancel
Save