mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
main: reset tty if starting the VM fails
When I refactored this to centralise resetting the tty into
DeviceManager::drop, I tested that the tty was reset if an error
happened on the vmm thread, but not on the main thread. It turns out
that if an error happened on the main thread, the process would just
exit, so drop handlers on other threads wouldn't get run.
To fix this, I've changed start_vmm() to write to the VMM's exit
eventfd and then join the thread if an error happens after the vmm
thread is started.
Fixes: b6feae0a ("vmm: only touch the tty flags if it's being used")
Signed-off-by: Alyssa Ross <hi@alyssa.is>
This commit is contained in:
committed by
Rob Bradford
parent
c90a0ffff6
commit
21d40d7489
@@ -288,6 +288,7 @@ pub fn start_vmm_thread(
|
||||
#[cfg(feature = "guest_debug")] debug_path: Option<PathBuf>,
|
||||
#[cfg(feature = "guest_debug")] debug_event: EventFd,
|
||||
#[cfg(feature = "guest_debug")] vm_debug_event: EventFd,
|
||||
exit_event: EventFd,
|
||||
seccomp_action: &SeccompAction,
|
||||
hypervisor: Arc<dyn hypervisor::Hypervisor>,
|
||||
) -> Result<thread::JoinHandle<Result<()>>> {
|
||||
@@ -308,9 +309,8 @@ pub fn start_vmm_thread(
|
||||
.map_err(Error::CreateSeccompFilter)?;
|
||||
|
||||
let vmm_seccomp_action = seccomp_action.clone();
|
||||
let exit_evt = EventFd::new(EFD_NONBLOCK).map_err(Error::EventFdCreate)?;
|
||||
let thread = {
|
||||
let exit_evt = exit_evt.try_clone().map_err(Error::EventFdClone)?;
|
||||
let exit_event = exit_event.try_clone().map_err(Error::EventFdClone)?;
|
||||
thread::Builder::new()
|
||||
.name("vmm".to_string())
|
||||
.spawn(move || {
|
||||
@@ -328,7 +328,7 @@ pub fn start_vmm_thread(
|
||||
vm_debug_event,
|
||||
vmm_seccomp_action,
|
||||
hypervisor,
|
||||
exit_evt,
|
||||
exit_event,
|
||||
)?;
|
||||
|
||||
vmm.setup_signal_handler()?;
|
||||
@@ -349,7 +349,7 @@ pub fn start_vmm_thread(
|
||||
http_api_event,
|
||||
api_sender,
|
||||
seccomp_action,
|
||||
exit_evt,
|
||||
exit_event,
|
||||
hypervisor_type,
|
||||
)?;
|
||||
} else if let Some(http_fd) = http_fd {
|
||||
@@ -358,7 +358,7 @@ pub fn start_vmm_thread(
|
||||
http_api_event,
|
||||
api_sender,
|
||||
seccomp_action,
|
||||
exit_evt,
|
||||
exit_event,
|
||||
hypervisor_type,
|
||||
)?;
|
||||
}
|
||||
|
||||
@@ -314,10 +314,10 @@ impl VmState {
|
||||
fn valid_transition(self, new_state: VmState) -> Result<()> {
|
||||
match self {
|
||||
VmState::Created => match new_state {
|
||||
VmState::Created | VmState::Shutdown => {
|
||||
Err(Error::InvalidStateTransition(self, new_state))
|
||||
VmState::Created => Err(Error::InvalidStateTransition(self, new_state)),
|
||||
VmState::Running | VmState::Paused | VmState::BreakPoint | VmState::Shutdown => {
|
||||
Ok(())
|
||||
}
|
||||
VmState::Running | VmState::Paused | VmState::BreakPoint => Ok(()),
|
||||
},
|
||||
|
||||
VmState::Running => match new_state {
|
||||
@@ -2694,7 +2694,7 @@ mod tests {
|
||||
// Check the transitions from Created
|
||||
assert!(state.valid_transition(VmState::Created).is_err());
|
||||
assert!(state.valid_transition(VmState::Running).is_ok());
|
||||
assert!(state.valid_transition(VmState::Shutdown).is_err());
|
||||
assert!(state.valid_transition(VmState::Shutdown).is_ok());
|
||||
assert!(state.valid_transition(VmState::Paused).is_ok());
|
||||
assert!(state.valid_transition(VmState::BreakPoint).is_ok());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user