mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
vmm: add guest exit event path
Introduce a dedicated guest_exit_evt and a matching epoll dispatch path for guest-triggered shutdowns. This series is needed because managment software such as libvirt may still need the Cloud Hypervisor process to stay alive after the guest has shut down. Today a guest-triggered shutdown can make the VMM disappear immediately, which means the managment software can lose track of the VM run-state. This must only apply to guest-triggered shutdowns. Fatal error paths and other internal exit paths must keep using the existing VMM exit handling. For now GuestExit still calls vmm_shutdown(), so this commit only adds the separate plumbing and keeps the current behavior unchanged. On-behalf-of: SAP leander.kohler@sap.com Signed-off-by: Leander Kohler <leander.kohler@cyberus-technology.de>
This commit is contained in:
committed by
Rob Bradford
parent
dc0e003be0
commit
c698075157
@@ -1080,6 +1080,7 @@ pub struct DeviceManager {
|
||||
// Exit event
|
||||
exit_evt: EventFd,
|
||||
reset_evt: EventFd,
|
||||
guest_exit_evt: EventFd,
|
||||
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||
id_to_dev_info: HashMap<(DeviceType, String), MmioDeviceInfo>,
|
||||
@@ -1206,6 +1207,7 @@ impl DeviceManager {
|
||||
cpu_manager: Arc<Mutex<CpuManager>>,
|
||||
exit_evt: EventFd,
|
||||
reset_evt: EventFd,
|
||||
guest_exit_evt: EventFd,
|
||||
seccomp_action: SeccompAction,
|
||||
numa_nodes: NumaNodes,
|
||||
activate_evt: &EventFd,
|
||||
@@ -1402,6 +1404,7 @@ impl DeviceManager {
|
||||
device_tree,
|
||||
exit_evt,
|
||||
reset_evt,
|
||||
guest_exit_evt,
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||
id_to_dev_info: HashMap::new(),
|
||||
seccomp_action,
|
||||
@@ -1519,6 +1522,9 @@ impl DeviceManager {
|
||||
self.exit_evt
|
||||
.try_clone()
|
||||
.map_err(DeviceManagerError::EventFd)?,
|
||||
self.guest_exit_evt
|
||||
.try_clone()
|
||||
.map_err(DeviceManagerError::EventFd)?,
|
||||
)?;
|
||||
}
|
||||
|
||||
@@ -1889,6 +1895,7 @@ impl DeviceManager {
|
||||
interrupt_manager: &dyn InterruptManager<GroupConfig = LegacyIrqGroupConfig>,
|
||||
reset_evt: EventFd,
|
||||
exit_evt: EventFd,
|
||||
_guest_exit_evt: EventFd,
|
||||
) -> DeviceManagerResult<Option<Arc<Mutex<devices::AcpiGedDevice>>>> {
|
||||
let vcpus_kill_signalled = self
|
||||
.cpu_manager
|
||||
|
||||
@@ -250,6 +250,7 @@ pub enum EpollDispatch {
|
||||
Api = 2,
|
||||
ActivateVirtioDevices = 3,
|
||||
Debug = 4,
|
||||
GuestExit = 5,
|
||||
Unknown,
|
||||
}
|
||||
|
||||
@@ -262,6 +263,7 @@ impl From<u64> for EpollDispatch {
|
||||
2 => Api,
|
||||
3 => ActivateVirtioDevices,
|
||||
4 => Debug,
|
||||
5 => GuestExit,
|
||||
_ => Unknown,
|
||||
}
|
||||
}
|
||||
@@ -608,6 +610,7 @@ pub struct Vmm {
|
||||
epoll: EpollContext,
|
||||
exit_evt: EventFd,
|
||||
reset_evt: EventFd,
|
||||
guest_exit_evt: EventFd,
|
||||
api_evt: EventFd,
|
||||
#[cfg(feature = "guest_debug")]
|
||||
debug_evt: EventFd,
|
||||
@@ -781,6 +784,7 @@ impl Vmm {
|
||||
) -> Result<Self> {
|
||||
let mut epoll = EpollContext::new().map_err(Error::Epoll)?;
|
||||
let reset_evt = EventFd::new(EFD_NONBLOCK).map_err(Error::EventFdCreate)?;
|
||||
let guest_exit_evt = EventFd::new(EFD_NONBLOCK).map_err(Error::EventFdCreate)?;
|
||||
let activate_evt = EventFd::new(EFD_NONBLOCK).map_err(Error::EventFdCreate)?;
|
||||
|
||||
epoll
|
||||
@@ -791,6 +795,10 @@ impl Vmm {
|
||||
.add_event(&reset_evt, EpollDispatch::Reset)
|
||||
.map_err(Error::Epoll)?;
|
||||
|
||||
epoll
|
||||
.add_event(&guest_exit_evt, EpollDispatch::GuestExit)
|
||||
.map_err(Error::Epoll)?;
|
||||
|
||||
epoll
|
||||
.add_event(&activate_evt, EpollDispatch::ActivateVirtioDevices)
|
||||
.map_err(Error::Epoll)?;
|
||||
@@ -808,6 +816,7 @@ impl Vmm {
|
||||
epoll,
|
||||
exit_evt,
|
||||
reset_evt,
|
||||
guest_exit_evt,
|
||||
api_evt,
|
||||
#[cfg(feature = "guest_debug")]
|
||||
debug_evt,
|
||||
@@ -1109,6 +1118,9 @@ impl Vmm {
|
||||
let reset_evt = self.reset_evt.try_clone().map_err(|e| {
|
||||
MigratableError::MigrateReceive(anyhow!("Error cloning reset EventFd: {e}"))
|
||||
})?;
|
||||
let guest_exit_evt = self.guest_exit_evt.try_clone().map_err(|e| {
|
||||
MigratableError::MigrateReceive(anyhow!("Error cloning guest exit EventFd: {e}"))
|
||||
})?;
|
||||
#[cfg(feature = "guest_debug")]
|
||||
let debug_evt = self.vm_debug_evt.try_clone().map_err(|e| {
|
||||
MigratableError::MigrateReceive(anyhow!("Error cloning debug EventFd: {e}"))
|
||||
@@ -1128,6 +1140,7 @@ impl Vmm {
|
||||
hypervisor_vm,
|
||||
exit_evt,
|
||||
reset_evt,
|
||||
guest_exit_evt,
|
||||
#[cfg(feature = "guest_debug")]
|
||||
debug_evt,
|
||||
&self.seccomp_action,
|
||||
@@ -1569,6 +1582,10 @@ impl Vmm {
|
||||
|
||||
let exit_evt = self.exit_evt.try_clone().map_err(VmError::EventFdClone)?;
|
||||
let reset_evt = self.reset_evt.try_clone().map_err(VmError::EventFdClone)?;
|
||||
let guest_exit_evt = self
|
||||
.guest_exit_evt
|
||||
.try_clone()
|
||||
.map_err(VmError::EventFdClone)?;
|
||||
#[cfg(feature = "guest_debug")]
|
||||
let debug_evt = self
|
||||
.vm_debug_evt
|
||||
@@ -1583,6 +1600,7 @@ impl Vmm {
|
||||
vm_config,
|
||||
exit_evt,
|
||||
reset_evt,
|
||||
guest_exit_evt,
|
||||
#[cfg(feature = "guest_debug")]
|
||||
debug_evt,
|
||||
&self.seccomp_action,
|
||||
@@ -1667,6 +1685,13 @@ impl Vmm {
|
||||
self.reset_evt.read().map_err(Error::EventFdRead)?;
|
||||
self.vm_reboot().map_err(Error::VmReboot)?;
|
||||
}
|
||||
EpollDispatch::GuestExit => {
|
||||
info!("VM guest exit event");
|
||||
self.guest_exit_evt.read().map_err(Error::EventFdRead)?;
|
||||
self.vmm_shutdown().map_err(Error::VmmShutdown)?;
|
||||
|
||||
break 'outer;
|
||||
}
|
||||
EpollDispatch::ActivateVirtioDevices => {
|
||||
if let Some(ref vm) = self.vm {
|
||||
let count = self.activate_evt.read().map_err(Error::EventFdRead)?;
|
||||
@@ -1775,6 +1800,10 @@ impl RequestHandler for Vmm {
|
||||
if self.vm.is_none() {
|
||||
let exit_evt = self.exit_evt.try_clone().map_err(VmError::EventFdClone)?;
|
||||
let reset_evt = self.reset_evt.try_clone().map_err(VmError::EventFdClone)?;
|
||||
let guest_exit_evt = self
|
||||
.guest_exit_evt
|
||||
.try_clone()
|
||||
.map_err(VmError::EventFdClone)?;
|
||||
#[cfg(feature = "guest_debug")]
|
||||
let vm_debug_evt = self
|
||||
.vm_debug_evt
|
||||
@@ -1790,6 +1819,7 @@ impl RequestHandler for Vmm {
|
||||
Arc::clone(vm_config),
|
||||
exit_evt,
|
||||
reset_evt,
|
||||
guest_exit_evt,
|
||||
#[cfg(feature = "guest_debug")]
|
||||
vm_debug_evt,
|
||||
&self.seccomp_action,
|
||||
@@ -1955,6 +1985,10 @@ impl RequestHandler for Vmm {
|
||||
|
||||
let exit_evt = self.exit_evt.try_clone().map_err(VmError::EventFdClone)?;
|
||||
let reset_evt = self.reset_evt.try_clone().map_err(VmError::EventFdClone)?;
|
||||
let guest_exit_evt = self
|
||||
.guest_exit_evt
|
||||
.try_clone()
|
||||
.map_err(VmError::EventFdClone)?;
|
||||
#[cfg(feature = "guest_debug")]
|
||||
let debug_evt = self
|
||||
.vm_debug_evt
|
||||
@@ -1980,6 +2014,7 @@ impl RequestHandler for Vmm {
|
||||
config,
|
||||
exit_evt,
|
||||
reset_evt,
|
||||
guest_exit_evt,
|
||||
#[cfg(feature = "guest_debug")]
|
||||
debug_evt,
|
||||
&self.seccomp_action,
|
||||
|
||||
@@ -536,6 +536,7 @@ impl Vm {
|
||||
vm: Arc<dyn hypervisor::Vm>,
|
||||
exit_evt: EventFd,
|
||||
reset_evt: EventFd,
|
||||
guest_exit_evt: EventFd,
|
||||
#[cfg(feature = "guest_debug")] vm_debug_evt: EventFd,
|
||||
seccomp_action: &SeccompAction,
|
||||
hypervisor: Arc<dyn hypervisor::Hypervisor>,
|
||||
@@ -604,6 +605,7 @@ impl Vm {
|
||||
cpu_manager.clone(),
|
||||
exit_evt.try_clone().map_err(Error::EventFdClone)?,
|
||||
reset_evt,
|
||||
guest_exit_evt,
|
||||
seccomp_action.clone(),
|
||||
numa_nodes.clone(),
|
||||
&activate_evt,
|
||||
@@ -790,6 +792,7 @@ impl Vm {
|
||||
cpu_manager: Arc<Mutex<cpu::CpuManager>>,
|
||||
exit_evt: EventFd,
|
||||
reset_evt: EventFd,
|
||||
guest_exit_evt: EventFd,
|
||||
seccomp_action: SeccompAction,
|
||||
numa_nodes: NumaNodes,
|
||||
activate_evt: &EventFd,
|
||||
@@ -812,6 +815,7 @@ impl Vm {
|
||||
cpu_manager,
|
||||
exit_evt,
|
||||
reset_evt,
|
||||
guest_exit_evt,
|
||||
seccomp_action,
|
||||
numa_nodes,
|
||||
activate_evt,
|
||||
@@ -1247,6 +1251,7 @@ impl Vm {
|
||||
vm_config: Arc<Mutex<VmConfig>>,
|
||||
exit_evt: EventFd,
|
||||
reset_evt: EventFd,
|
||||
guest_exit_evt: EventFd,
|
||||
#[cfg(feature = "guest_debug")] vm_debug_evt: EventFd,
|
||||
seccomp_action: &SeccompAction,
|
||||
hypervisor: Arc<dyn hypervisor::Hypervisor>,
|
||||
@@ -1319,6 +1324,7 @@ impl Vm {
|
||||
vm,
|
||||
exit_evt,
|
||||
reset_evt,
|
||||
guest_exit_evt,
|
||||
#[cfg(feature = "guest_debug")]
|
||||
vm_debug_evt,
|
||||
seccomp_action,
|
||||
|
||||
Reference in New Issue
Block a user