From e1af17d93a10c19be9b9dcac171a3750f85f1418 Mon Sep 17 00:00:00 2001 From: Qiu Wenbo Date: Thu, 5 Dec 2019 11:27:40 +0800 Subject: [PATCH] vmm: Restore tty to canonical mode when SIGTERM or SIGINT received The tty mode remains raw mode when cloud-hypervisor is terminted by SIGTERM or SIGINT. The terminal is unusable due to echoing is disabled which is really annoying. Signed-off-by: Qiu Wenbo --- vmm/src/vm.rs | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index c5dc3ef47..6b4ff5876 100755 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -36,7 +36,7 @@ use kvm_ioctls::*; use linux_loader::cmdline::Cmdline; use linux_loader::loader::KernelLoader; -use signal_hook::{iterator::Signals, SIGWINCH}; +use signal_hook::{iterator::Signals, SIGINT, SIGTERM, SIGWINCH}; use std::ffi::CString; use std::fs::{File, OpenOptions}; use std::io; @@ -675,11 +675,23 @@ impl Vm { Ok(()) } - fn os_signal_handler(signals: Signals, console_input_clone: Arc) { + fn os_signal_handler(signals: Signals, console_input_clone: Arc, on_tty: bool) { for signal in signals.forever() { - if signal == SIGWINCH { - let (col, row) = get_win_size(); - console_input_clone.update_console_size(col, row); + match signal { + SIGWINCH => { + let (col, row) = get_win_size(); + console_input_clone.update_console_size(col, row); + } + SIGTERM | SIGINT => { + if on_tty { + io::stdin() + .lock() + .set_canon_mode() + .expect("failed to restore terminal mode"); + } + std::process::exit((signal != SIGTERM) as i32); + } + _ => (), } } } @@ -703,15 +715,16 @@ impl Vm { if self.devices.console().input_enabled() { let console = self.devices.console().clone(); - let signals = Signals::new(&[SIGWINCH]); + let signals = Signals::new(&[SIGWINCH, SIGINT, SIGTERM]); match signals { Ok(signals) => { self.signals = Some(signals.clone()); + let on_tty = self.on_tty; self.threads.push( thread::Builder::new() .name("signal_handler".to_string()) - .spawn(move || Vm::os_signal_handler(signals, console)) + .spawn(move || Vm::os_signal_handler(signals, console, on_tty)) .map_err(Error::SignalHandlerSpawn)?, ); }