mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-11 04:26:38 +00:00
Handle errors and crashes in VM differently to clean shutdown.
BUG=b:211704107 TEST=tools/dev_container tools/run_tests TEST=tools/dev_container tools/run_tests --target=vm:aarch64 Change-Id: I383be89becefe300d9dc94b7d67d35269c628a39 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3412772 Reviewed-by: Dmitry Torokhov <dtor@chromium.org> Auto-Submit: Andrew Walbran <qwandor@google.com> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Andrew Walbran <qwandor@google.com>
This commit is contained in:
parent
b28ae8e70f
commit
1a19c67e22
2 changed files with 26 additions and 6 deletions
26
src/linux.rs
26
src/linux.rs
|
@ -2477,6 +2477,7 @@ fn run_vcpu<V>(
|
|||
mut mmio_bus: devices::Bus,
|
||||
exit_evt: Event,
|
||||
reset_evt: Event,
|
||||
crash_evt: Event,
|
||||
requires_pvclock_ctrl: bool,
|
||||
from_main_tube: mpsc::Receiver<VcpuControl>,
|
||||
use_hypervisor_signals: bool,
|
||||
|
@ -2561,6 +2562,7 @@ where
|
|||
let final_event = match exit_reason {
|
||||
ExitState::Stop => exit_evt,
|
||||
ExitState::Reset => reset_evt,
|
||||
ExitState::Crash => crash_evt,
|
||||
};
|
||||
if let Err(e) = final_event.write(1) {
|
||||
error!(
|
||||
|
@ -2615,13 +2617,13 @@ where
|
|||
Ok(m) => m,
|
||||
Err(mpsc::RecvError) => {
|
||||
error!("Failed to read from main tube in vcpu");
|
||||
return ExitState::Stop;
|
||||
return ExitState::Crash;
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(mpsc::TryRecvError::Disconnected) => {
|
||||
error!("Failed to read from main tube in vcpu");
|
||||
return ExitState::Stop;
|
||||
return ExitState::Crash;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2762,7 +2764,7 @@ where
|
|||
hardware_entry_failure_reason,
|
||||
}) => {
|
||||
error!("vcpu hw run failure: {:#x}", hardware_entry_failure_reason);
|
||||
return ExitState::Stop;
|
||||
return ExitState::Crash;
|
||||
}
|
||||
Ok(VcpuExit::SystemEventShutdown) => {
|
||||
info!("system shutdown event on vcpu {}", cpu_id);
|
||||
|
@ -2786,7 +2788,7 @@ where
|
|||
if let Some(ref ch) = to_gdb_tube {
|
||||
if let Err(e) = ch.send(msg) {
|
||||
error!("failed to notify breakpoint to GDB thread: {}", e);
|
||||
return ExitState::Stop;
|
||||
return ExitState::Crash;
|
||||
}
|
||||
}
|
||||
run_mode = VmRunMode::Breakpoint;
|
||||
|
@ -2798,7 +2800,7 @@ where
|
|||
libc::EAGAIN => {}
|
||||
_ => {
|
||||
error!("vcpu hit unknown error: {}", e);
|
||||
return ExitState::Stop;
|
||||
return ExitState::Crash;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
@ -2810,7 +2812,7 @@ where
|
|||
// attempting to handle pause requests.
|
||||
if let Err(e) = clear_signal(SIGRTMIN() + 0) {
|
||||
error!("failed to clear pending signal: {}", e);
|
||||
return ExitState::Stop;
|
||||
return ExitState::Crash;
|
||||
}
|
||||
} else {
|
||||
vcpu.set_immediate_exit(false);
|
||||
|
@ -2915,6 +2917,7 @@ fn setup_vm_components(cfg: &Config) -> Result<VmComponents> {
|
|||
pub enum ExitState {
|
||||
Reset,
|
||||
Stop,
|
||||
Crash,
|
||||
}
|
||||
|
||||
pub fn run_config(cfg: Config) -> Result<ExitState> {
|
||||
|
@ -3135,6 +3138,7 @@ where
|
|||
|
||||
let exit_evt = Event::new().context("failed to create event")?;
|
||||
let reset_evt = Event::new().context("failed to create event")?;
|
||||
let crash_evt = Event::new().context("failed to create event")?;
|
||||
let mut sys_allocator = Arch::create_system_allocator(&vm);
|
||||
|
||||
// Allocate the ramoops region first. AArch64::build_vm() assumes this.
|
||||
|
@ -3329,6 +3333,7 @@ where
|
|||
usb_control_tube,
|
||||
exit_evt,
|
||||
reset_evt,
|
||||
crash_evt,
|
||||
sigchld_fd,
|
||||
Arc::clone(&map_request),
|
||||
gralloc,
|
||||
|
@ -3473,6 +3478,7 @@ fn run_control<V: VmArch + 'static, Vcpu: VcpuArch + 'static>(
|
|||
#[cfg(feature = "usb")] usb_control_tube: Tube,
|
||||
exit_evt: Event,
|
||||
reset_evt: Event,
|
||||
crash_evt: Event,
|
||||
sigchld_fd: SignalFd,
|
||||
map_request: Arc<Mutex<Option<ExternalMapping>>>,
|
||||
mut gralloc: RutabagaGralloc,
|
||||
|
@ -3482,6 +3488,7 @@ fn run_control<V: VmArch + 'static, Vcpu: VcpuArch + 'static>(
|
|||
enum Token {
|
||||
Exit,
|
||||
Reset,
|
||||
Crash,
|
||||
Suspend,
|
||||
ChildSignal,
|
||||
IrqFd { index: IrqEventIndex },
|
||||
|
@ -3496,6 +3503,7 @@ fn run_control<V: VmArch + 'static, Vcpu: VcpuArch + 'static>(
|
|||
let wait_ctx = WaitContext::build_with(&[
|
||||
(&exit_evt, Token::Exit),
|
||||
(&reset_evt, Token::Reset),
|
||||
(&crash_evt, Token::Crash),
|
||||
(&linux.suspend_evt, Token::Suspend),
|
||||
(&sigchld_fd, Token::ChildSignal),
|
||||
])
|
||||
|
@ -3594,6 +3602,7 @@ fn run_control<V: VmArch + 'static, Vcpu: VcpuArch + 'static>(
|
|||
(*linux.mmio_bus).clone(),
|
||||
exit_evt.try_clone().context("failed to clone event")?,
|
||||
reset_evt.try_clone().context("failed to clone event")?,
|
||||
crash_evt.try_clone().context("failed to clone event")?,
|
||||
linux.vm.check_capability(VmCap::PvClockSuspend),
|
||||
from_main_channel,
|
||||
use_hypervisor_signals,
|
||||
|
@ -3662,6 +3671,11 @@ fn run_control<V: VmArch + 'static, Vcpu: VcpuArch + 'static>(
|
|||
exit_state = ExitState::Reset;
|
||||
break 'wait;
|
||||
}
|
||||
Token::Crash => {
|
||||
info!("vcpu crashed");
|
||||
exit_state = ExitState::Crash;
|
||||
break 'wait;
|
||||
}
|
||||
Token::Suspend => {
|
||||
info!("VM requested suspend");
|
||||
linux.suspend_evt.read().unwrap();
|
||||
|
|
|
@ -2450,6 +2450,7 @@ enum CommandStatus {
|
|||
Success,
|
||||
VmReset,
|
||||
VmStop,
|
||||
VmCrash,
|
||||
}
|
||||
|
||||
fn run_vm(args: std::env::Args) -> std::result::Result<CommandStatus, ()> {
|
||||
|
@ -2740,6 +2741,10 @@ iommu=on|off - indicates whether to enable virtio IOMMU for this device"),
|
|||
info!("crosvm has exited normally due to reset request");
|
||||
Ok(CommandStatus::VmReset)
|
||||
}
|
||||
Ok(platform::ExitState::Crash) => {
|
||||
info!("crosvm has exited due to a VM crash");
|
||||
Ok(CommandStatus::VmCrash)
|
||||
}
|
||||
Err(e) => {
|
||||
error!("crosvm has exited with error: {:#}", e);
|
||||
Err(())
|
||||
|
@ -3395,6 +3400,7 @@ fn main() {
|
|||
let exit_code = match crosvm_main() {
|
||||
Ok(CommandStatus::Success | CommandStatus::VmStop) => 0,
|
||||
Ok(CommandStatus::VmReset) => 32,
|
||||
Ok(CommandStatus::VmCrash) => 33,
|
||||
Err(_) => 1,
|
||||
};
|
||||
std::process::exit(exit_code);
|
||||
|
|
Loading…
Reference in a new issue