When destroying a domain we need to make sure we will be able to start a job no matter what other operations are running or even stuck in a job. This is done by killing the domain before starting the destroy job. Let's introduce qemuProcessBeginStopJob which combines killing a domain and starting a job in a single API which can be called everywhere we need a job to stop a domain. Signed-off-by: Jiri Denemark <jdenemar@xxxxxxxxxx> --- src/qemu/qemu_driver.c | 43 ++++++++++--------------------------------- src/qemu/qemu_process.c | 39 +++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_process.h | 4 ++++ 3 files changed, 53 insertions(+), 33 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 2bbc724..1770f81 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -2272,44 +2272,21 @@ qemuDomainDestroyFlags(virDomainPtr dom, if (virDomainDestroyFlagsEnsureACL(dom->conn, vm->def) < 0) goto cleanup; + if (qemuProcessBeginStopJob(driver, vm, QEMU_JOB_DESTROY, + !(flags & VIR_DOMAIN_DESTROY_GRACEFUL)) < 0) + goto cleanup; + + if (!virDomainObjIsActive(vm)) { + virReportError(VIR_ERR_OPERATION_INVALID, + "%s", _("domain is not running")); + goto endjob; + } + qemuDomainSetFakeReboot(driver, vm, false); 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) - goto cleanup; - - priv->beingDestroyed = false; - - if (!virDomainObjIsActive(vm)) { - virReportError(VIR_ERR_OPERATION_INVALID, - "%s", _("domain is not running")); - goto endjob; - } - qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_DESTROYED, stopFlags); event = virDomainEventLifecycleNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED, diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 6a44073..2f9df7c 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -5348,6 +5348,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 b16919d..69be99e 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, -- 2.7.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list