[PATCH v3 3/5] qemu: Track domain quiesced status

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Adds an quiesced flag into qemuDomainObjPrivate that tracks whether guest
filesystems of the domain is quiesced or not.

It also modify error code from qemuDomainSnapshotFSFreeze and
qemuDomainSnapshotFSThaw, so that a caller can know whether the command is
actually sent to the guest agent. If the error is caused before sending a
freeze command, a counterpart thaw command shouldn't be sent either, not to
thaw the guest unexpectedly by error handling code.

Signed-off-by: Tomoki Sekiyama <tomoki.sekiyama@xxxxxxx>
---
 src/qemu/qemu_domain.c |    5 ++++
 src/qemu/qemu_domain.h |    2 +
 src/qemu/qemu_driver.c |   66 +++++++++++++++++++++++++++++++++++++++---------
 3 files changed, 60 insertions(+), 13 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 7d375e5..1fb1652 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -357,6 +357,9 @@ qemuDomainObjPrivateXMLFormat(virBufferPtr buf, void *data)
         virBufferAddLit(buf, "</devices>\n");
     }
 
+    if (priv->quiesced)
+        virBufferAddLit(buf, "<quiesced/>\n");
+
     return 0;
 }
 
@@ -518,6 +521,8 @@ qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt, void *data)
     }
     VIR_FREE(nodes);
 
+    priv->quiesced = virXPathBoolean("boolean(./quiesced)", ctxt) == 1;
+
     return 0;
 
 error:
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index b2830c4..5fb1665 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -176,6 +176,8 @@ struct _qemuDomainObjPrivate {
     char **qemuDevices; /* NULL-terminated list of devices aliases known to QEMU */
 
     bool hookRun;  /* true if there was a hook run over this domain */
+
+    bool quiesced; /* true if the domain filesystems are quiesced */
 };
 
 typedef enum {
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 2707bec..bd469ba 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -12005,31 +12005,60 @@ cleanup:
 }
 
 
+/* Return -1 if request is not sent to agent due to misconfig, -2 if request
+ * is sent but failed, and number of frozen filesystems on success. */
 static int
-qemuDomainSnapshotFSFreeze(virDomainObjPtr vm) {
+qemuDomainSnapshotFSFreeze(virQEMUDriverPtr driver, virDomainObjPtr vm) {
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    virQEMUDriverConfigPtr cfg;
     int freezed;
 
     if (!qemuDomainAgentAvailable(priv, true))
         return -1;
 
+    if (priv->quiesced) {
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                       _("domain is already quiesced"));
+        return -1;
+    }
+
     qemuDomainObjEnterAgent(vm);
     freezed = qemuAgentFSFreeze(priv->agent);
     qemuDomainObjExitAgent(vm);
 
-    return freezed;
+    if (freezed >= 0)
+        priv->quiesced = true;
+
+    cfg = virQEMUDriverGetConfig(driver);
+    if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0) {
+        virObjectUnref(cfg);
+        return -2;
+    }
+    virObjectUnref(cfg);
+
+    return freezed < 0 ? -2 : freezed;
 }
 
+/* Return -1 if request is not sent to agent due to misconfig, -2 if request
+ * is send but failed, and number of thawed filesystems on success. */
 static int
-qemuDomainSnapshotFSThaw(virDomainObjPtr vm, bool report)
+qemuDomainSnapshotFSThaw(virQEMUDriverPtr driver,
+                         virDomainObjPtr vm, bool report)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    virQEMUDriverConfigPtr cfg;
     int thawed;
     virErrorPtr err = NULL;
 
     if (!qemuDomainAgentAvailable(priv, report))
         return -1;
 
+    if (!priv->quiesced && report) {
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                       _("domain is not quiesced"));
+        return -1;
+    }
+
     qemuDomainObjEnterAgent(vm);
     if (!report)
         err = virSaveLastError();
@@ -12038,8 +12067,18 @@ qemuDomainSnapshotFSThaw(virDomainObjPtr vm, bool report)
         virSetError(err);
     qemuDomainObjExitAgent(vm);
 
+    if (thawed >= 0)
+        priv->quiesced = false;
+
+    cfg = virQEMUDriverGetConfig(driver);
+    if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0) {
+        virObjectUnref(cfg);
+        return -2;
+    }
+    virObjectUnref(cfg);
+
     virFreeError(err);
-    return thawed;
+    return thawed < 0 ? -2 : thawed;
 }
 
 /* The domain is expected to be locked and inactive. */
@@ -13014,17 +13053,18 @@ qemuDomainSnapshotCreateActiveExternal(virConnectPtr conn,
         goto cleanup;
 
     /* If quiesce was requested, then issue a freeze command, and a
-     * counterpart thaw command, no matter what.  The command will
-     * fail if the guest is paused or the guest agent is not
-     * running.  */
+     * counterpart thaw command when the it is actually sent to agent.
+     * The command will fail if the guest is paused or the guest agent
+     * is not running, or is already quiesced.  */
     if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE) {
-        if (qemuDomainSnapshotFSFreeze(vm) < 0) {
-            /* helper reported the error */
-            thaw = -1;
+        int freeze = qemuDomainSnapshotFSFreeze(driver, vm);
+        if (freeze < 0) {
+            /* the helper reported the error */
+            if (freeze == -2)
+                thaw = -1; /* the command is sent but agent failed */
             goto endjob;
-        } else {
-            thaw = 1;
         }
+        thaw = 1;
     }
 
     /* We need to track what state the guest is in, since taking the
@@ -13165,7 +13205,7 @@ endjob:
         goto cleanup;
     }
     if (vm && thaw != 0 &&
-        qemuDomainSnapshotFSThaw(vm, thaw > 0) < 0) {
+        qemuDomainSnapshotFSThaw(driver, vm, thaw > 0) < 0) {
         /* helper reported the error, if it was needed */
         if (thaw > 0)
             ret = -1;

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]