[PATCHv3 03.5/43] snapshot: fine-tune qemu snapshot revert states

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

 



For a system checkpoint of a running or paused domain, it's fairly
easy to honor new flags for altering which state to use after the
revert.  For an inactive snapshot, the revert has to be done while
there is no qemu process, so do back-to-back transitions; this also
lets us revert to inactive snapshots even for transient domains.

* src/qemu/qemu_driver.c (qemuDomainRevertToSnapshot): Support new
flags.
---
 src/qemu/qemu_driver.c |   59 +++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 51 insertions(+), 8 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 6f6447e..094455f 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -8857,7 +8857,8 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
     qemuDomainObjPrivatePtr priv;
     int rc;

-    virCheckFlags(0, -1);
+    virCheckFlags(VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING |
+                  VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED, -1);

     /* We have the following transitions, which create the following events:
      * 1. inactive -> inactive: none
@@ -8889,6 +8890,17 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
         goto cleanup;
     }

+    if (!vm->persistent &&
+        snap->def->state != VIR_DOMAIN_RUNNING &&
+        snap->def->state != VIR_DOMAIN_PAUSED &&
+        (flags & (VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING |
+                  VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED)) == 0) {
+        qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                        _("transient domain needs to request run or pause "
+                          "to revert to inactive snapshot"));
+        goto cleanup;
+    }
+
     if (vm->current_snapshot) {
         vm->current_snapshot->def->current = false;
         if (qemuDomainSnapshotWriteMetadata(vm, vm->current_snapshot,
@@ -8962,7 +8974,9 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
         }

         /* Touch up domain state.  */
-        if (snap->def->state == VIR_DOMAIN_PAUSED) {
+        if (!(flags & VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING) &&
+            (snap->def->state == VIR_DOMAIN_PAUSED ||
+             (flags & VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED))) {
             /* Transitions 3, 6, 9 */
             virDomainObjSetState(vm, VIR_DOMAIN_PAUSED,
                                  VIR_DOMAIN_PAUSED_FROM_SNAPSHOT);
@@ -9015,20 +9029,49 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
             event = virDomainEventNewFromObj(vm,
                                              VIR_DOMAIN_EVENT_STOPPED,
                                              detail);
+        }
+
+        if (qemuDomainSnapshotRevertInactive(vm, snap) < 0) {
             if (!vm->persistent) {
-                /* XXX For transient domains, enforce that one of the
-                 * flags is set to get domain running again. For now,
-                 * reverting to offline on a transient domain ends up
-                 * killing the domain, without reverting any disk state. */
                 if (qemuDomainObjEndJob(driver, vm) > 0)
                     virDomainRemoveInactive(&driver->domains, vm);
                 vm = NULL;
                 goto cleanup;
             }
+            goto endjob;
         }

-        if (qemuDomainSnapshotRevertInactive(vm, snap) < 0)
-            goto endjob;
+        if (flags & (VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING |
+                     VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED)) {
+            /* Flush first event, now do transition 2 or 3 */
+            bool paused = (flags & VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED) != 0;
+
+            if (event)
+                qemuDomainEventQueue(driver, event);
+            rc = qemuProcessStart(snapshot->domain->conn, driver, vm, NULL,
+                                  paused, false, -1, NULL, NULL,
+                                  VIR_VM_OP_CREATE);
+            virDomainAuditStart(vm, "from-snapshot", rc >= 0);
+            if (rc < 0) {
+                if (!vm->persistent) {
+                    if (qemuDomainObjEndJob(driver, vm) > 0)
+                        virDomainRemoveInactive(&driver->domains, vm);
+                    vm = NULL;
+                    goto cleanup;
+                }
+                goto endjob;
+            }
+            detail = VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT;
+            event = virDomainEventNewFromObj(vm,
+                                             VIR_DOMAIN_EVENT_STARTED,
+                                             detail);
+            if (paused) {
+                detail = VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT;
+                event2 = virDomainEventNewFromObj(vm,
+                                                  VIR_DOMAIN_EVENT_SUSPENDED,
+                                                  detail);
+            }
+        }
     }

     ret = 0;
-- 
1.7.4.4

--
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]