[libvirt] [PATCHv3 4/5] snapshot: support revert-and-create branching in qemu

Eric Blake eblake at redhat.com
Wed Nov 21 00:36:58 UTC 2012


First cut at allowing snapshot branch creation.  For now, the code
requires that the snapshot be created but not activated (thus leaving
the user on the original branch); this is because activating the
new branch will require shared code with revert.  Of course, until
we allow reverting to a snapshot branch, this functionality feels
more like a write-only interface (we can create the snapshot but not
use it); but one thing at a time.

* src/qemu/qemu_driver.c (qemuDomainSnapshotCreateXML): Support
new flag.
(qemuDomainSnapshotPrepare): Likewise.
---
 src/qemu/qemu_driver.c | 47 +++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 41 insertions(+), 6 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f5bbc52..a17ab62 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -10901,7 +10901,8 @@ qemuDomainSnapshotPrepare(virDomainObjPtr vm, virDomainSnapshotDefPtr def,
     qemuDomainObjPrivatePtr priv = vm->privateData;

     if (def->state == VIR_DOMAIN_DISK_SNAPSHOT &&
-        reuse && !qemuCapsGet(priv->caps, QEMU_CAPS_TRANSACTION)) {
+        reuse && !qemuCapsGet(priv->caps, QEMU_CAPS_TRANSACTION) &&
+        !(*flags & VIR_DOMAIN_SNAPSHOT_CREATE_BRANCH)) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                        _("reuse is not supported with this QEMU binary"));
         goto cleanup;
@@ -11015,7 +11016,8 @@ qemuDomainSnapshotPrepare(virDomainObjPtr vm, virDomainSnapshotDefPtr def,
     if (external && !active)
         *flags |= VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY;

-    if (def->state != VIR_DOMAIN_DISK_SNAPSHOT && active) {
+    if (def->state != VIR_DOMAIN_DISK_SNAPSHOT && active &&
+        !(*flags & VIR_DOMAIN_SNAPSHOT_CREATE_BRANCH)) {
         if (external == 1 ||
             qemuCapsGet(priv->caps, QEMU_CAPS_TRANSACTION)) {
             *flags |= VIR_DOMAIN_SNAPSHOT_CREATE_ATOMIC;
@@ -11464,7 +11466,8 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
                   VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT |
                   VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE |
                   VIR_DOMAIN_SNAPSHOT_CREATE_ATOMIC |
-                  VIR_DOMAIN_SNAPSHOT_CREATE_LIVE, NULL);
+                  VIR_DOMAIN_SNAPSHOT_CREATE_LIVE |
+                  VIR_DOMAIN_SNAPSHOT_CREATE_BRANCH, NULL);

     if ((flags & VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE) &&
         !(flags & VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY)) {
@@ -11473,12 +11476,15 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
         return NULL;
     }

-    if (((flags & VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE) &&
+    if (((flags & (VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE |
+                   VIR_DOMAIN_SNAPSHOT_CREATE_BRANCH)) &&
          !(flags & VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT)) ||
         (flags & VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA))
         update_current = false;
     if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE)
         parse_flags |= VIR_DOMAIN_SNAPSHOT_PARSE_REDEFINE;
+    else if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_BRANCH)
+        parse_flags |= VIR_DOMAIN_SNAPSHOT_PARSE_BRANCH;

     qemuDriverLock(driver);
     virUUIDFormat(domain->uuid, uuidstr);
@@ -11519,7 +11525,8 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
     if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_LIVE &&
         (!virDomainObjIsActive(vm) ||
          def->memory != VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL ||
-         flags & VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE)) {
+         flags & (VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE |
+                  VIR_DOMAIN_SNAPSHOT_CREATE_BRANCH))) {
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
                        _("live snapshot creation is supported only "
                          "with external checkpoints"));
@@ -11636,6 +11643,22 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
                                             align_match) < 0)
                 goto cleanup;
         }
+    } else if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_BRANCH) {
+        /* XXX For now, we require that the new branch is not current
+         * (getting that to work will require sharing code with
+         * snapshot revert for (re-)starting the domain with correct
+         * events).  */
+        if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT) {
+            virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+                           _("branch snapshot creation does not yet support "
+                             "the current flag"));
+            goto cleanup;
+        }
+        /* def->dom was already populated, and the disks aligned; but
+         * we still need to check that we can create the new disk
+         * wrappers.  */
+        if (qemuDomainSnapshotPrepare(vm, def, &flags) < 0)
+            goto cleanup;
     } else {
         /* Easiest way to clone inactive portion of vm->def is via
          * conversion in and back out of xml.  */
@@ -11678,7 +11701,8 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
     if (update_current)
         snap->def->current = true;
     if (vm->current_snapshot) {
-        if (!(flags & VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE)) {
+        if (!(flags & (VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE |
+                       VIR_DOMAIN_SNAPSHOT_CREATE_BRANCH))) {
             snap->def->parent = strdup(vm->current_snapshot->def->name);
             if (snap->def->parent == NULL) {
                 virReportOOMError();
@@ -11699,6 +11723,17 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
         /* XXX Should we validate that the redefined snapshot even
          * makes sense, such as checking that qemu-img recognizes the
          * snapshot name in at least one of the domain's disks?  */
+    } else if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_BRANCH) {
+        /* Whether or not the domain is online or the snapshot was
+         * from a running state, we reuse the offline creation code to
+         * create the new qcow2 files.  */
+        bool reuse = !!(flags & VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT);
+
+        if (qemuDomainSnapshotCreateInactiveExternal(driver, vm, snap,
+                                                     reuse) < 0)
+            goto cleanup;
+        /* XXX Figure out how to support _CURRENT by reusing code from
+         * revert to swap over to the just-created snapshot.  */
     } else if (virDomainObjIsActive(vm)) {
         if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY ||
             snap->def->memory == VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL) {
-- 
1.7.11.7




More information about the libvir-list mailing list