From: Peter Krempa <[email protected]> Some guest OSes (e.g. windows) can do an internal crash dump and reboot after a crash. They unfortunately notify the OS before doing the crash dump though so we need a new possibility for the <on_crash> action to keep the VM as is.
This patch introduces 'preserve-running' mode for on_crash and wires it up into the qemu driver. Signed-off-by: Peter Krempa <[email protected]> --- docs/formatdomain.rst | 3 ++ include/libvirt/libvirt-domain.h | 1 + src/conf/domain_conf.c | 2 ++ src/conf/schemas/domaincommon.rng | 2 ++ src/libxl/libxl_conf.c | 1 + src/libxl/libxl_domain.c | 3 ++ src/qemu/qemu_driver.c | 34 ++++++++++++++++++- src/qemu/qemu_process.c | 18 ++++++++++ .../async-teardown.x86_64-latest.xml | 2 +- tests/qemuxmlconfdata/async-teardown.xml | 2 +- tests/qemuxmlconftest.c | 1 + tools/virsh-domain.c | 3 +- 12 files changed, 68 insertions(+), 4 deletions(-) diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index a861f9f177..fa5b62200b 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -2044,6 +2044,9 @@ The ``on_crash`` event supports these additional actions :since:`since 0.8.4`. ``coredump-restart`` The crashed domain's core will be dumped, and then the domain will be restarted with the same configuration +``preserve-running`` + The crashed domain will continue to run. This is useful if the guest OS can + do an internal crash dump and reboot itself. :since:`Since 12.6.0` :since:`Since 3.9.0`, the lifecycle events can be configured via the `virDomainSetLifecycleAction <html/libvirt-libvirt-domain.html#virDomainSetLifecycleAction>`__ diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index 5b67f8f897..f4dfe9fb1a 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -8228,6 +8228,7 @@ typedef enum { VIR_DOMAIN_LIFECYCLE_ACTION_PRESERVE = 3, /* (Since: 3.9.0) */ VIR_DOMAIN_LIFECYCLE_ACTION_COREDUMP_DESTROY = 4, /* (Since: 3.9.0) */ VIR_DOMAIN_LIFECYCLE_ACTION_COREDUMP_RESTART = 5, /* (Since: 3.9.0) */ + VIR_DOMAIN_LIFECYCLE_ACTION_PRESERVE_RUNNING = 6, /* (Since: 12.6.0) */ # ifdef VIR_ENUM_SENTINELS VIR_DOMAIN_LIFECYCLE_ACTION_LAST /* (Since: 3.9.0) */ diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index ab5138acbc..45235d74bc 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -303,6 +303,7 @@ VIR_ENUM_IMPL(virDomainLifecycleAction, "preserve", "coredump-destroy", "coredump-restart", + "preserve-running", ); VIR_ENUM_IMPL(virDomainLockFailure, @@ -5534,6 +5535,7 @@ virDomainDefLifecycleActionAllowed(virDomainLifecycle type, return true; case VIR_DOMAIN_LIFECYCLE_ACTION_COREDUMP_DESTROY: case VIR_DOMAIN_LIFECYCLE_ACTION_COREDUMP_RESTART: + case VIR_DOMAIN_LIFECYCLE_ACTION_PRESERVE_RUNNING: break; } break; diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng index 121e4e06a6..81ffbfc2fa 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -5035,6 +5035,7 @@ destroy: The domain is cleaned up restart: A new domain is started in place of the old one preserve: The domain will remain in memory until it is destroyed manually + preserve-running: Keep the domain as is, let the guest handle the crash. rename-restart: a variant of the previous one but where the old domain is renamed before being saved to allow a restart coredump-destroy: The crashed domain's core will be dumped, and then the @@ -5051,6 +5052,7 @@ <value>rename-restart</value> <value>coredump-destroy</value> <value>coredump-restart</value> + <value>preserve-running</value> </choice> </define> <!-- diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c index d25b92b4de..3bb5c1e591 100644 --- a/src/libxl/libxl_conf.c +++ b/src/libxl/libxl_conf.c @@ -111,6 +111,7 @@ libxlActionFromVirLifecycle(virDomainLifecycleAction action) case VIR_DOMAIN_LIFECYCLE_ACTION_COREDUMP_RESTART: return LIBXL_ACTION_ON_SHUTDOWN_COREDUMP_RESTART; + case VIR_DOMAIN_LIFECYCLE_ACTION_PRESERVE_RUNNING: case VIR_DOMAIN_LIFECYCLE_ACTION_LAST: break; } diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c index c6717e31cf..51dc3edcc2 100644 --- a/src/libxl/libxl_domain.c +++ b/src/libxl/libxl_domain.c @@ -509,6 +509,7 @@ libxlDomainShutdownThread(void *opaque) case VIR_DOMAIN_LIFECYCLE_ACTION_PRESERVE: case VIR_DOMAIN_LIFECYCLE_ACTION_COREDUMP_DESTROY: case VIR_DOMAIN_LIFECYCLE_ACTION_COREDUMP_RESTART: + case VIR_DOMAIN_LIFECYCLE_ACTION_PRESERVE_RUNNING: case VIR_DOMAIN_LIFECYCLE_ACTION_LAST: goto endjob; } @@ -529,6 +530,7 @@ libxlDomainShutdownThread(void *opaque) goto endjob; case VIR_DOMAIN_LIFECYCLE_ACTION_PRESERVE: case VIR_DOMAIN_LIFECYCLE_ACTION_LAST: + case VIR_DOMAIN_LIFECYCLE_ACTION_PRESERVE_RUNNING: goto endjob; case VIR_DOMAIN_LIFECYCLE_ACTION_COREDUMP_DESTROY: libxlDomainAutoCoreDump(driver, vm); @@ -557,6 +559,7 @@ libxlDomainShutdownThread(void *opaque) case VIR_DOMAIN_LIFECYCLE_ACTION_PRESERVE: case VIR_DOMAIN_LIFECYCLE_ACTION_COREDUMP_DESTROY: case VIR_DOMAIN_LIFECYCLE_ACTION_COREDUMP_RESTART: + case VIR_DOMAIN_LIFECYCLE_ACTION_PRESERVE_RUNNING: case VIR_DOMAIN_LIFECYCLE_ACTION_LAST: goto endjob; } diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index b83225cf38..44b41726fb 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -3644,6 +3644,11 @@ processGuestPanicEvent(virQEMUDriver *driver, qemuDomainSaveStatus(vm); break; + case VIR_DOMAIN_LIFECYCLE_ACTION_PRESERVE_RUNNING: + virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, VIR_DOMAIN_RUNNING_CRASHED); + qemuDomainSaveStatus(vm); + break; + case VIR_DOMAIN_LIFECYCLE_ACTION_LAST: break; } @@ -3661,6 +3666,8 @@ processGuestPanicEvent(virQEMUDriver *driver, VIR_DEBUG("Preserving lock state '%s'", NULLSTR(priv->lockState)); break; + case VIR_DOMAIN_LIFECYCLE_ACTION_PRESERVE_RUNNING: + /* we need to keep resources locked */ case VIR_DOMAIN_LIFECYCLE_ACTION_LAST: break; } @@ -3678,6 +3685,7 @@ processGuestPanicEvent(virQEMUDriver *driver, case VIR_DOMAIN_LIFECYCLE_ACTION_RESTART: case VIR_DOMAIN_LIFECYCLE_ACTION_PRESERVE: case VIR_DOMAIN_LIFECYCLE_ACTION_RESTART_RENAME: + case VIR_DOMAIN_LIFECYCLE_ACTION_PRESERVE_RUNNING: case VIR_DOMAIN_LIFECYCLE_ACTION_LAST: break; } @@ -3704,6 +3712,7 @@ processGuestPanicEvent(virQEMUDriver *driver, case VIR_DOMAIN_LIFECYCLE_ACTION_PRESERVE: case VIR_DOMAIN_LIFECYCLE_ACTION_RESTART_RENAME: + case VIR_DOMAIN_LIFECYCLE_ACTION_PRESERVE_RUNNING: case VIR_DOMAIN_LIFECYCLE_ACTION_LAST: break; } @@ -19591,13 +19600,36 @@ qemuDomainModifyLifecycleActionLive(virDomainObj *vm, case VIR_DOMAIN_LIFECYCLE_ACTION_RESTART_RENAME: case VIR_DOMAIN_LIFECYCLE_ACTION_COREDUMP_DESTROY: case VIR_DOMAIN_LIFECYCLE_ACTION_COREDUMP_RESTART: + case VIR_DOMAIN_LIFECYCLE_ACTION_PRESERVE_RUNNING: case VIR_DOMAIN_LIFECYCLE_ACTION_LAST: break; } break; - case VIR_DOMAIN_LIFECYCLE_POWEROFF: case VIR_DOMAIN_LIFECYCLE_CRASH: + if (vm->def->onCrash == action) + break; + + switch (vm->def->onCrash) { + case VIR_DOMAIN_LIFECYCLE_ACTION_PRESERVE_RUNNING: + panic = QEMU_MONITOR_ACTION_PANIC_NONE; + break; + + case VIR_DOMAIN_LIFECYCLE_ACTION_DESTROY: + case VIR_DOMAIN_LIFECYCLE_ACTION_RESTART: + case VIR_DOMAIN_LIFECYCLE_ACTION_PRESERVE: + case VIR_DOMAIN_LIFECYCLE_ACTION_RESTART_RENAME: + case VIR_DOMAIN_LIFECYCLE_ACTION_COREDUMP_DESTROY: + case VIR_DOMAIN_LIFECYCLE_ACTION_COREDUMP_RESTART: + panic = QEMU_MONITOR_ACTION_PANIC_PAUSE; + break; + + case VIR_DOMAIN_LIFECYCLE_ACTION_LAST: + break; + } + break; + + case VIR_DOMAIN_LIFECYCLE_POWEROFF: case VIR_DOMAIN_LIFECYCLE_LAST: break; } diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 8389819ee4..b2506edce0 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -8186,6 +8186,24 @@ qemuProcessSetupLifecycleActions(virDomainObj *vm, if (vm->def->onReboot == VIR_DOMAIN_LIFECYCLE_ACTION_DESTROY) reboot = QEMU_MONITOR_ACTION_REBOOT_SHUTDOWN; + switch (vm->def->onCrash) { + case VIR_DOMAIN_LIFECYCLE_ACTION_PRESERVE_RUNNING: + panic = QEMU_MONITOR_ACTION_PANIC_NONE; + break; + + case VIR_DOMAIN_LIFECYCLE_ACTION_DESTROY: + case VIR_DOMAIN_LIFECYCLE_ACTION_RESTART: + case VIR_DOMAIN_LIFECYCLE_ACTION_PRESERVE: + case VIR_DOMAIN_LIFECYCLE_ACTION_RESTART_RENAME: + case VIR_DOMAIN_LIFECYCLE_ACTION_COREDUMP_DESTROY: + case VIR_DOMAIN_LIFECYCLE_ACTION_COREDUMP_RESTART: + panic = QEMU_MONITOR_ACTION_PANIC_PAUSE; + break; + + case VIR_DOMAIN_LIFECYCLE_ACTION_LAST: + break; + } + if (shutdown == QEMU_MONITOR_ACTION_SHUTDOWN_KEEP && reboot == QEMU_MONITOR_ACTION_REBOOT_KEEP && watchdog == QEMU_MONITOR_ACTION_WATCHDOG_KEEP && diff --git a/tests/qemuxmlconfdata/async-teardown.x86_64-latest.xml b/tests/qemuxmlconfdata/async-teardown.x86_64-latest.xml index e98308a9b1..1c7c80ae8a 100644 --- a/tests/qemuxmlconfdata/async-teardown.x86_64-latest.xml +++ b/tests/qemuxmlconfdata/async-teardown.x86_64-latest.xml @@ -17,7 +17,7 @@ <clock offset='utc'/> <on_poweroff>destroy</on_poweroff> <on_reboot>restart</on_reboot> - <on_crash>destroy</on_crash> + <on_crash>preserve-running</on_crash> <devices> <emulator>/usr/bin/qemu-system-x86_64</emulator> <disk type='block' device='disk'> diff --git a/tests/qemuxmlconfdata/async-teardown.xml b/tests/qemuxmlconfdata/async-teardown.xml index 70c1eccc55..149b9ed16d 100644 --- a/tests/qemuxmlconfdata/async-teardown.xml +++ b/tests/qemuxmlconfdata/async-teardown.xml @@ -11,7 +11,7 @@ <clock offset='utc'/> <on_poweroff>destroy</on_poweroff> <on_reboot>restart</on_reboot> - <on_crash>destroy</on_crash> + <on_crash>preserve-running</on_crash> <features> <async-teardown enabled='yes'/> </features> diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c index df0b257cbe..f9e426f4eb 100644 --- a/tests/qemuxmlconftest.c +++ b/tests/qemuxmlconftest.c @@ -3193,6 +3193,7 @@ mymain(void) DO_TEST_CAPS_LATEST("crypto-builtin"); + /* this test case also tests 'preserve-running' onCrash action */ DO_TEST_CAPS_LATEST("async-teardown"); DO_TEST_CAPS_ARCH_LATEST("s390-async-teardown", "s390x"); DO_TEST_CAPS_ARCH_LATEST("s390-async-teardown-no-attrib", "s390x"); diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index aa4f2a7a48..0f177fb69a 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -6242,7 +6242,8 @@ VIR_ENUM_IMPL(virshDomainLifecycleAction, "rename-restart", "preserve", "coredump-destroy", - "coredump-restart"); + "coredump-restart", + "none"); static bool cmdSetLifecycleAction(vshControl *ctl, const vshCmd *cmd) -- 2.55.0
