diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index b1f94bd24d..ffdbdb12db 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -2279,33 +2279,10 @@ qemuDomainDestroyFlags(virDomainPtr dom, if (priv->job.asyncJob == QEMU_ASYNC_JOB_MIGRATION_IN) stopFlags |= VIR_QEMU_PROCESS_STOP_MIGRATED; - /* We need to prevent monitor EOF callback from doing our work (and sending - * misleading events) while the vm is unlocked inside BeginJob/ProcessKill API - */ - priv->beingDestroyed = true; - - /* Although qemuProcessStop does this already, there may - * be an outstanding job active. We want to make sure we - * can kill the process even if a job is active. Killing - * it now means the job will be released - */ - if (flags & VIR_DOMAIN_DESTROY_GRACEFUL) { - if (qemuProcessKill(vm, 0) < 0) { - priv->beingDestroyed = false; - goto cleanup; - } - } else { - if (qemuProcessKill(vm, VIR_QEMU_PROCESS_KILL_FORCE) < 0) { - priv->beingDestroyed = false; - goto cleanup; - } - } - - if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_DESTROY) < 0) + if (qemuProcessBeginStopJob(driver, vm, QEMU_JOB_DESTROY, + !(flags & VIR_DOMAIN_DESTROY_GRACEFUL)) < 0) goto cleanup; - priv->beingDestroyed = false; - if (!virDomainObjIsActive(vm)) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("domain is not running")); diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index bc53c44524..fd301c3e1f 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -5403,6 +5403,45 @@ qemuProcessKill(virDomainObjPtr vm, unsigned int flags) } +/** + * qemuProcessBeginStopJob: + * + * Stop all current jobs by killing the domain and start a new one for + * qemuProcessStop. + */ +int +qemuProcessBeginStopJob(virQEMUDriverPtr driver, + virDomainObjPtr vm, + qemuDomainJob job, + bool forceKill) +{ + qemuDomainObjPrivatePtr priv = vm->privateData; + unsigned int killFlags = forceKill ? VIR_QEMU_PROCESS_KILL_FORCE : 0; + int ret = -1; + + /* We need to prevent monitor EOF callback from doing our work (and + * sending misleading events) while the vm is unlocked inside + * BeginJob/ProcessKill API + */ + priv->beingDestroyed = true; + + if (qemuProcessKill(vm, killFlags) < 0) + goto cleanup; + + /* Wake up anything waiting on domain condition */ + virDomainObjBroadcast(vm); + + if (qemuDomainObjBeginJob(driver, vm, job) < 0) + goto cleanup; + + ret = 0; + + cleanup: + priv->beingDestroyed = false; + return ret; +} + + void qemuProcessStop(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainShutoffReason reason, diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h index b16919d339..69be99e2e0 100644 --- a/src/qemu/qemu_process.h +++ b/src/qemu/qemu_process.h @@ -114,6 +114,10 @@ typedef enum { VIR_QEMU_PROCESS_STOP_NO_RELABEL = 1 << 1, } qemuProcessStopFlags; +int qemuProcessBeginStopJob(virQEMUDriverPtr driver, + virDomainObjPtr vm, + qemuDomainJob job, + bool forceKill); void qemuProcessStop(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainShutoffReason reason,