1
0
mirror of https://review.coreboot.org/flashrom.git synced 2025-08-20 05:21:43 +02:00

CHROMIUM: avl_tool: more gracefully handle termination by SIGINT

Since interrupting the test process may be dangerous (leaving the flash
in an inconsistent state), we'll catch SIGINT and print a warning the
first time, also using it as a signal that we should stop at a
convenient time. Any following SIGINT will be handled as normal (killing
the process).

BUG=b:143251344
TEST=Run tool and verify it exits after a test with a single ^C, exits
     immediately given two.
BRANCH=None

Original-Cq-Depend: chromium:2059548
Original-Change-Id: Ib8a7799cba6dbca57dc7f1d3c87521f132c21818
Original-Signed-off-by: Peter Marheine <pmarheine@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/flashrom/+/2050050
Original-Tested-by: Edward O'Callaghan <quasisec@chromium.org>
Original-Reviewed-by: Edward O'Callaghan <quasisec@chromium.org>

Change-Id: If43aea0580fcc7e698daad2ffe085a3c9da5bc41
Signed-off-by: Edward O'Callaghan <quasisec@google.com>
Reviewed-on: https://review.coreboot.org/c/flashrom/+/49915
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
This commit is contained in:
Peter Marheine
2020-02-12 15:37:28 +11:00
committed by Edward O'Callaghan
parent 4e31838eb1
commit 32aa933b1d
4 changed files with 51 additions and 1 deletions

View File

@@ -42,6 +42,7 @@ use clap::{App, Arg};
use flashrom::FlashChip;
use flashrom_tester::{tester, tests};
use std::path::PathBuf;
use std::sync::atomic::AtomicBool;
pub mod built_info {
include!(concat!(env!("OUT_DIR"), "/built.rs"));
@@ -136,8 +137,45 @@ fn main() {
print_layout,
output_format,
test_names,
Some(handle_sigint()),
) {
eprintln!("Failed to run tests: {:?}", e);
std::process::exit(1);
}
}
/// Catch exactly one SIGINT, printing a message in response and setting a flag.
///
/// The returned value is false by default, becoming true after a SIGINT is
/// trapped.
///
/// Once a signal is trapped, the default behavior is restored (terminating
/// the process) for future signals.
fn handle_sigint() -> &'static AtomicBool {
use nix::libc::c_int;
use nix::sys::signal::{self, SigHandler, Signal};
use std::sync::atomic::Ordering;
unsafe {
let _ = signal::signal(Signal::SIGINT, SigHandler::Handler(sigint_handler));
}
static TERMINATE_FLAG: AtomicBool = AtomicBool::new(false);
extern "C" fn sigint_handler(_: c_int) {
const STDERR_FILENO: c_int = 2;
static MESSAGE: &[u8] = b"
WARNING: terminating tests prematurely may leave Flash in an inconsistent state,
rendering your machine unbootable. Testing will end on completion of the current
test, or press ^C again to exit immediately (possibly bricking your machine).
";
// Use raw write() because signal-safety is a very hard problem
let _ = nix::unistd::write(STDERR_FILENO, MESSAGE);
unsafe {
let _ = signal::signal(Signal::SIGINT, SigHandler::SigDfl);
}
TERMINATE_FLAG.store(true, Ordering::Release);
}
&TERMINATE_FLAG
}