From: Peter Krempa <[email protected]> 'qemuProcessShutdownOrReboot' may or may not kill the VM. In 'qemuProcessReconnect' if we decided that the VM was in a state requiring 'qemuProcessShutdownOrReboot' to be called we'd stop the reconnection unconditionally.
Now if the VM ought to undergo a fake reboot we really need to reconnect to the process because the process will be kept around for much longer. Make qemuProcessShutdownOrReboot return whether it killed the VM and continue the reconnection if it didn't. Signed-off-by: Peter Krempa <[email protected]> --- src/qemu/qemu_driver.c | 2 +- src/qemu/qemu_process.c | 25 +++++++++++++++++++++---- src/qemu/qemu_process.h | 3 ++- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 1f7e587f61..d99528724e 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -3557,7 +3557,7 @@ processGuestPanicEvent(virQEMUDriver *driver, case VIR_DOMAIN_LIFECYCLE_ACTION_RESTART: qemuDomainSetFakeReboot(vm, true); - qemuProcessShutdownOrReboot(vm); + ignore_value(qemuProcessShutdownOrReboot(vm)); break; case VIR_DOMAIN_LIFECYCLE_ACTION_PRESERVE: diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 45fc32a663..bbd9859ef4 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -597,7 +597,16 @@ qemuProcessFakeReboot(void *opaque) } -void +/** + * qemuProcessShutdownOrReboot: + * @vm: domain object + * + * Perform the appropriate action when the guest OS shuts down. This can be + * either fake reboot (the VM is reset started again) or the VM is terminated. + * + * The function returns true if the VM was terminated. + */ +bool qemuProcessShutdownOrReboot(virDomainObj *vm) { qemuDomainObjPrivate *priv = vm->privateData; @@ -620,9 +629,14 @@ qemuProcessShutdownOrReboot(virDomainObj *vm) qemuDomainSetFakeReboot(vm, false); virObjectUnref(vm); } + + return false; } else { ignore_value(qemuProcessKill(vm, VIR_QEMU_PROCESS_KILL_NOWAIT)); + return true; } + + return false; } @@ -714,7 +728,7 @@ qemuProcessHandleShutdown(qemuMonitor *mon G_GNUC_UNUSED, if (priv->agent) qemuAgentNotifyEvent(priv->agent, QEMU_AGENT_EVENT_SHUTDOWN); - qemuProcessShutdownOrReboot(vm); + ignore_value(qemuProcessShutdownOrReboot(vm)); unlock: virObjectUnlock(vm); @@ -9705,8 +9719,11 @@ qemuProcessReconnect(void *opaque) reason == VIR_DOMAIN_PAUSED_USER)) { VIR_DEBUG("Finishing shutdown sequence for domain %s", obj->def->name); - qemuProcessShutdownOrReboot(obj); - goto cleanup; + /* qemuProcessShutdownOrReboot returns 'true' if the VM was terminated. + * If the VM is kept (e.g. for fake reboot) we need to continue the + * reconnection */ + if (qemuProcessShutdownOrReboot(obj)) + goto cleanup; } /* if domain requests security driver we haven't loaded, report error, but diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h index 9f783790ac..426e11d79e 100644 --- a/src/qemu/qemu_process.h +++ b/src/qemu/qemu_process.h @@ -192,7 +192,8 @@ int qemuProcessKill(virDomainObj *vm, unsigned int flags); int qemuProcessFakeRebootViaRecreate(virDomainObj *vm, bool locked); -void qemuProcessShutdownOrReboot(virDomainObj *vm); +bool qemuProcessShutdownOrReboot(virDomainObj *vm) + G_GNUC_WARN_UNUSED_RESULT; void qemuProcessAutoDestroy(virDomainObj *dom, virConnectPtr conn); -- 2.51.1
