[libvirt] [PATCH v2 2/3] snapshots: Introduce VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE flag

Michal Privoznik mprivozn at redhat.com
Tue Jan 24 20:21:34 UTC 2012


With this flag, virDomainSnapshotCreate will use fs-freeze and
fs-thaw guest agent commands to quiesce guest's disks.
---
 include/libvirt/libvirt.h.in |    4 ++
 src/libvirt.c                |    6 +++
 src/qemu/qemu_driver.c       |   87 ++++++++++++++++++++++++++++++++++++++----
 3 files changed, 89 insertions(+), 8 deletions(-)

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 5e6e488..182065d 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -3125,6 +3125,10 @@ typedef enum {
                                                           system checkpoint */
     VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT   = (1 << 5), /* reuse any existing
                                                           external files */
+    VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE     = (1 << 6), /* use guest agent to
+                                                          quiesce all mounted
+                                                          file systems within
+                                                          the domain */
 } virDomainSnapshotCreateFlags;
 
 /* Take a snapshot of the current VM state */
diff --git a/src/libvirt.c b/src/libvirt.c
index 96ad3d5..722a2e2 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -16602,6 +16602,12 @@ virDomainSnapshotGetConnect(virDomainSnapshotPtr snapshot)
  * inconsistent (as if power had been pulled), and specifying this
  * with the VIR_DOMAIN_SNAPSHOT_CREATE_HALT flag risks data loss.
  *
+ * If @flags includes VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE, then the
+ * libvirt will attempt to use guest agent to freeze and thaw all
+ * file systems in use within domain OS. However, if the guest agent
+ * is not present, an error is thrown. Moreover, this flag requires
+ * VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY to be passed as well.
+ *
  * By default, if the snapshot involves external files, and any of the
  * destination files already exist as a regular file, the snapshot is
  * rejected to avoid losing contents of those files.  However, if
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index c81289a..ab69dca 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -9461,6 +9461,56 @@ static int qemuDomainSnapshotIsAllowed(virDomainObjPtr vm)
     return 1;
 }
 
+static int
+qemuDomainSnapshotFSFreeze(struct qemud_driver *driver,
+                           virDomainObjPtr vm) {
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    int freezed;
+
+    if (priv->agentError) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("QEMU guest agent is not "
+                          "available due to an error"));
+        return -1;
+    }
+    if (!priv->agent) {
+        qemuReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+                        _("QEMU guest agent is not configured"));
+        return -1;
+    }
+
+    qemuDomainObjEnterAgent(driver, vm);
+    freezed = qemuAgentFSFreeze(priv->agent);
+    qemuDomainObjExitAgent(driver, vm);
+
+    return freezed;
+}
+
+static int
+qemuDomainSnapshotFSThaw(struct qemud_driver *driver,
+                         virDomainObjPtr vm) {
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    int thawed;
+
+    if (priv->agentError) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("QEMU guest agent is not "
+                          "available due to an error"));
+        return -1;
+    }
+    if (!priv->agent) {
+        qemuReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+                        _("QEMU guest agent is not configured"));
+        return -1;
+    }
+
+    qemuDomainObjEnterAgent(driver, vm);
+    thawed = qemuAgentFSThaw(priv->agent);
+    qemuDomainObjExitAgent(driver, vm);
+
+    return thawed;
+}
+
 /* The domain is expected to be locked and inactive. */
 static int
 qemuDomainSnapshotCreateInactive(struct qemud_driver *driver,
@@ -9773,6 +9823,12 @@ qemuDomainSnapshotCreateDiskActive(virConnectPtr conn,
 
 
     if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
+        if ((flags & VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE) &&
+            (qemuDomainSnapshotFSFreeze(driver, vm) < 0)) {
+            /* helper reported the error */
+            goto endjob;
+        }
+
         /* In qemu, snapshot_blkdev on a single disk will pause cpus,
          * but this confuses libvirt since notifications are not given
          * when qemu resumes.  And for multiple disks, libvirt must
@@ -9840,13 +9896,20 @@ qemuDomainSnapshotCreateDiskActive(virConnectPtr conn,
     }
 
 cleanup:
-    if (resume && virDomainObjIsActive(vm) &&
-        qemuProcessStartCPUs(driver, vm, conn,
-                             VIR_DOMAIN_RUNNING_UNPAUSED,
-                             QEMU_ASYNC_JOB_NONE) < 0 &&
-        virGetLastError() == NULL) {
-        qemuReportError(VIR_ERR_OPERATION_FAILED, "%s",
-                        _("resuming after snapshot failed"));
+    if (resume && virDomainObjIsActive(vm)) {
+        if (qemuProcessStartCPUs(driver, vm, conn,
+                                 VIR_DOMAIN_RUNNING_UNPAUSED,
+                                 QEMU_ASYNC_JOB_NONE) < 0 &&
+            virGetLastError() == NULL) {
+            qemuReportError(VIR_ERR_OPERATION_FAILED, "%s",
+                            _("resuming after snapshot failed"));
+            goto endjob;
+        }
+
+        if ((flags & VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE) &&
+            qemuDomainSnapshotFSThaw(driver, vm) < 0) {
+            /* helper reported the error */
+        }
     }
 
     if (vm) {
@@ -9888,7 +9951,15 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
                   VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA |
                   VIR_DOMAIN_SNAPSHOT_CREATE_HALT |
                   VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY |
-                  VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT, NULL);
+                  VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT |
+                  VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE, NULL);
+
+    if ((flags & VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE) &&
+        !(flags & VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY)) {
+        qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                        _("quiesce requires disk-only"));
+        return NULL;
+    }
 
     if (((flags & VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE) &&
          !(flags & VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT)) ||
-- 
1.7.3.4




More information about the libvir-list mailing list