[libvirt] [PATCH 4/9] qemu: Introduce qemuProcessBeginStopJob

Jiri Denemark jdenemar at redhat.com
Tue Feb 16 14:36:56 UTC 2016


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 at redhat.com>
---
 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




More information about the libvir-list mailing list