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

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



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


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