mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
main: add --no-shutdown
Add a CLI-only --no-shutdown flag that keeps the VMM process alive after a guest-triggered shutdown. Management software may still need the Cloud Hypervisor process after the guest has powered off. Exposing this separately lets management software, for example libvirt, keep the VMM around in a way that is closer to QEMU. The flag only affects the GuestExit path. Fatal exits and other existing VMM shutdown paths remain 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
a159152e41
commit
005ce38ffd
@@ -373,6 +373,12 @@ fn get_cli_options_sorted(
|
|||||||
.num_args(1..)
|
.num_args(1..)
|
||||||
.action(ArgAction::Append)
|
.action(ArgAction::Append)
|
||||||
.group("vm-config"),
|
.group("vm-config"),
|
||||||
|
Arg::new("no-shutdown")
|
||||||
|
.long("no-shutdown")
|
||||||
|
.help("Do not exit the VMM when the guest shuts down")
|
||||||
|
.num_args(0)
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
|
.group("vmm-config"),
|
||||||
Arg::new("numa")
|
Arg::new("numa")
|
||||||
.long("numa")
|
.long("numa")
|
||||||
.help(NumaConfig::SYNTAX)
|
.help(NumaConfig::SYNTAX)
|
||||||
@@ -637,6 +643,7 @@ fn start_vmm(
|
|||||||
|
|
||||||
let exit_evt = EventFd::new(EFD_NONBLOCK).map_err(Error::CreateExitEventFd)?;
|
let exit_evt = EventFd::new(EFD_NONBLOCK).map_err(Error::CreateExitEventFd)?;
|
||||||
let landlock_enable = cmd_arguments.get_flag("landlock");
|
let landlock_enable = cmd_arguments.get_flag("landlock");
|
||||||
|
let no_shutdown = cmd_arguments.get_flag("no-shutdown");
|
||||||
|
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
let mut event_monitor = cmd_arguments
|
let mut event_monitor = cmd_arguments
|
||||||
@@ -733,6 +740,7 @@ fn start_vmm(
|
|||||||
exit_evt.try_clone().unwrap(),
|
exit_evt.try_clone().unwrap(),
|
||||||
&seccomp_action,
|
&seccomp_action,
|
||||||
hypervisor,
|
hypervisor,
|
||||||
|
no_shutdown,
|
||||||
landlock_enable,
|
landlock_enable,
|
||||||
)
|
)
|
||||||
.map_err(Error::StartVmmThread)?;
|
.map_err(Error::StartVmmThread)?;
|
||||||
|
|||||||
@@ -162,6 +162,10 @@ pub enum Error {
|
|||||||
#[error("Error rebooting VM")]
|
#[error("Error rebooting VM")]
|
||||||
VmReboot(#[source] VmError),
|
VmReboot(#[source] VmError),
|
||||||
|
|
||||||
|
/// Cannot shut the VM down
|
||||||
|
#[error("Error shutting down VM")]
|
||||||
|
VmShutdown(#[source] VmError),
|
||||||
|
|
||||||
/// Cannot create VMM thread
|
/// Cannot create VMM thread
|
||||||
#[error("Error spawning VMM thread")]
|
#[error("Error spawning VMM thread")]
|
||||||
VmmThreadSpawn(#[source] io::Error),
|
VmmThreadSpawn(#[source] io::Error),
|
||||||
@@ -449,6 +453,7 @@ pub fn start_vmm_thread(
|
|||||||
exit_event: EventFd,
|
exit_event: EventFd,
|
||||||
seccomp_action: &SeccompAction,
|
seccomp_action: &SeccompAction,
|
||||||
hypervisor: Arc<dyn hypervisor::Hypervisor>,
|
hypervisor: Arc<dyn hypervisor::Hypervisor>,
|
||||||
|
no_shutdown: bool,
|
||||||
landlock_enable: bool,
|
landlock_enable: bool,
|
||||||
) -> Result<VmmThreadHandle> {
|
) -> Result<VmmThreadHandle> {
|
||||||
#[cfg(feature = "guest_debug")]
|
#[cfg(feature = "guest_debug")]
|
||||||
@@ -488,6 +493,7 @@ pub fn start_vmm_thread(
|
|||||||
vmm_seccomp_action,
|
vmm_seccomp_action,
|
||||||
hypervisor,
|
hypervisor,
|
||||||
exit_event,
|
exit_event,
|
||||||
|
no_shutdown,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
vmm.setup_signal_handler(landlock_enable)?;
|
vmm.setup_signal_handler(landlock_enable)?;
|
||||||
@@ -627,6 +633,7 @@ pub struct Vmm {
|
|||||||
original_termios_opt: Arc<Mutex<Option<termios>>>,
|
original_termios_opt: Arc<Mutex<Option<termios>>>,
|
||||||
console_resize_pipe: Option<Arc<File>>,
|
console_resize_pipe: Option<Arc<File>>,
|
||||||
console_info: Option<ConsoleInfo>,
|
console_info: Option<ConsoleInfo>,
|
||||||
|
no_shutdown: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Just a wrapper for the data that goes into
|
/// Just a wrapper for the data that goes into
|
||||||
@@ -781,6 +788,7 @@ impl Vmm {
|
|||||||
seccomp_action: SeccompAction,
|
seccomp_action: SeccompAction,
|
||||||
hypervisor: Arc<dyn hypervisor::Hypervisor>,
|
hypervisor: Arc<dyn hypervisor::Hypervisor>,
|
||||||
exit_evt: EventFd,
|
exit_evt: EventFd,
|
||||||
|
no_shutdown: bool,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let mut epoll = EpollContext::new().map_err(Error::Epoll)?;
|
let mut epoll = EpollContext::new().map_err(Error::Epoll)?;
|
||||||
let reset_evt = EventFd::new(EFD_NONBLOCK).map_err(Error::EventFdCreate)?;
|
let reset_evt = EventFd::new(EFD_NONBLOCK).map_err(Error::EventFdCreate)?;
|
||||||
@@ -833,6 +841,7 @@ impl Vmm {
|
|||||||
original_termios_opt: Arc::new(Mutex::new(None)),
|
original_termios_opt: Arc::new(Mutex::new(None)),
|
||||||
console_resize_pipe: None,
|
console_resize_pipe: None,
|
||||||
console_info: None,
|
console_info: None,
|
||||||
|
no_shutdown,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1688,9 +1697,12 @@ impl Vmm {
|
|||||||
EpollDispatch::GuestExit => {
|
EpollDispatch::GuestExit => {
|
||||||
info!("VM guest exit event");
|
info!("VM guest exit event");
|
||||||
self.guest_exit_evt.read().map_err(Error::EventFdRead)?;
|
self.guest_exit_evt.read().map_err(Error::EventFdRead)?;
|
||||||
self.vmm_shutdown().map_err(Error::VmmShutdown)?;
|
if self.no_shutdown {
|
||||||
|
self.vm_shutdown().map_err(Error::VmShutdown)?;
|
||||||
break 'outer;
|
} else {
|
||||||
|
self.vmm_shutdown().map_err(Error::VmmShutdown)?;
|
||||||
|
break 'outer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
EpollDispatch::ActivateVirtioDevices => {
|
EpollDispatch::ActivateVirtioDevices => {
|
||||||
if let Some(ref vm) = self.vm {
|
if let Some(ref vm) = self.vm {
|
||||||
@@ -2630,6 +2642,7 @@ mod unit_tests {
|
|||||||
SeccompAction::Allow,
|
SeccompAction::Allow,
|
||||||
hypervisor::new().unwrap(),
|
hypervisor::new().unwrap(),
|
||||||
EventFd::new(EFD_NONBLOCK).unwrap(),
|
EventFd::new(EFD_NONBLOCK).unwrap(),
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user