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

[libvirt] [PATCHv4 48/51] snapshot: reject unimplemented disk snapshot features



My RFC for snapshot support [1] proposes several rules for when it is
safe to delete or revert to an external snapshot, predicated on
the existence of new API flags.  These will be incrementally added
in future patches, but until then, blindly mishandling a disk
snapshot risks corrupting internal state, so it is better to
outright reject the attempts until the other pieces are in place,
thus incrementally relaxing the restrictions added in this patch.

[1] https://www.redhat.com/archives/libvir-list/2011-August/msg00361.html

* src/qemu/qemu_driver.c (qemuDomainSnapshotCountExternal): New
function.
(qemuDomainUndefineFlags, qemuDomainSnapshotDelete): Use it to add
safety valve.
(qemuDomainRevertToSnapshot): Add safety valve.
---
 src/qemu/qemu_driver.c |   36 ++++++++++++++++++++++++++++++++++++
 1 files changed, 36 insertions(+), 0 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 19897c6..d4e9452 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1782,6 +1782,19 @@ qemuDomainSnapshotDiscardAll(void *payload,
         curr->err = err;
 }

+/* Count how many snapshots in a set have external disk snapshots.  */
+static void
+qemuDomainSnapshotCountExternal(void *payload,
+                                const void *name ATTRIBUTE_UNUSED,
+                                void *data)
+{
+    virDomainSnapshotObjPtr snap = payload;
+    int *count = data;
+
+    if (snap->def->state == VIR_DOMAIN_DISK_SNAPSHOT)
+        (*count)++;
+}
+
 static int
 qemuDomainDestroyFlags(virDomainPtr dom,
                        unsigned int flags)
@@ -9193,6 +9206,12 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
                           "to revert to inactive snapshot"));
         goto cleanup;
     }
+    if (snap->def->state == VIR_DOMAIN_DISK_SNAPSHOT) {
+        qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                        _("revert to external disk snapshot not supported "
+                          "yet"));
+        goto cleanup;
+    }

     if (vm->current_snapshot) {
         vm->current_snapshot->def->current = false;
@@ -9479,6 +9498,7 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
     struct snap_remove rem;
     struct snap_reparent rep;
     bool metadata_only = !!(flags & VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY);
+    int external = 0;

     virCheckFlags(VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN |
                   VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY |
@@ -9501,6 +9521,22 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
         goto cleanup;
     }

+    if (!(flags & VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY)) {
+        if (!(flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY) &&
+            snap->def->state == VIR_DOMAIN_DISK_SNAPSHOT)
+            external++;
+        if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN)
+            virDomainSnapshotForEachDescendant(&vm->snapshots, snap,
+                                               qemuDomainSnapshotCountExternal,
+                                               &external);
+        if (external) {
+            qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                            _("deletion of %d external disk snapshots not "
+                              "supported yet"), external);
+            goto cleanup;
+        }
+    }
+
     if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
         goto cleanup;

-- 
1.7.4.4


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