Google
  Web www.spinics.net

[PATCHv5 22/23] snapshot: implement new snapshot delete flags in qemu

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


Delete a mirrored snapshot by picking which of the two files in the
mirror to reopen.  This is not atomic, so we update the snapshot
in place as we iterate through each successful disk.  Since we limited
mirrored snapshots to transient domains, there is no persistent
configuration to update.  This mode implies deleting the snapshot
metadata but preserving the new file.

* src/qemu/qemu_driver.c (qemuDomainSnapshotDelete): Honor new
flags.
(qemuDomainSnapshotDeleteMirror): New helper function.
---
 src/qemu/qemu_driver.c |   85 +++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 81 insertions(+), 4 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 5b1ed87..4ce31a3 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -11283,6 +11283,66 @@ qemuDomainSnapshotReparentChildren(void *payload,
                                                rep->driver->snapshotDir);
 }

+/* Must be called while holding a job.  */
+static int
+qemuDomainSnapshotDeleteMirror(struct qemud_driver *driver,
+                               virDomainObjPtr vm,
+                               virDomainSnapshotObjPtr snap,
+                               bool pivot)
+{
+    int i;
+    int ret = 0;
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    char *device = NULL;
+    const char *dest;
+    char *file = NULL;
+
+    if (!virDomainObjIsActive(vm)) {
+        qemuReportError(VIR_ERR_OPERATION_INVALID,
+                        "%s", _("domain is not running"));
+        return -1;
+    }
+
+    qemuDomainObjEnterMonitorWithDriver(driver, vm);
+
+    for (i = 0; i < snap->def->ndisks; i++) {
+        if (!snap->def->disks[i].mirror)
+            continue;
+        VIR_FREE(device);
+        VIR_FREE(file);
+        dest = pivot ? snap->def->disks[i].mirror : snap->def->disks[i].file;
+        if (virAsprintf(&device, "drive-%s",
+                        vm->def->disks[i]->info.alias) < 0 ||
+            (file = strdup(dest)) == NULL) {
+            virReportOOMError();
+            break;
+        }
+        if (qemuMonitorDriveReopen(priv->mon, device, dest,
+                                   snap->def->disks[i].driverType) < 0)
+            break;
+        /* TODO: Release lock and reset label.  */
+
+        VIR_FREE(vm->def->disks[i]->src);
+        vm->def->disks[i]->src = file;
+        file = NULL;
+        if (pivot)
+            snap->def->disks[i].file = snap->def->disks[i].mirror;
+        snap->def->disks[i].mirror = NULL;
+    }
+    VIR_FREE(device);
+    VIR_FREE(file);
+    if (i < snap->def->ndisks)
+        ret = -1;
+
+    qemuDomainObjExitMonitorWithDriver(driver, vm);
+
+    if (ret < 0 &&
+        qemuDomainSnapshotWriteMetadata(vm, snap, driver->snapshotDir) < 0)
+        VIR_WARN("failed writing snapshot '%s' after partial mirror deletion",
+                 snap->def->name);
+    return ret;
+}
+
 static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
                                     unsigned int flags)
 {
@@ -11293,12 +11353,16 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
     char uuidstr[VIR_UUID_STRING_BUFLEN];
     struct qemu_snap_remove rem;
     struct snap_reparent rep;
-    bool metadata_only = !!(flags & VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY);
     int external = 0;
+    bool metadata_only = !!(flags & VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY);
+    bool mirror_abort = !!(flags & VIR_DOMAIN_SNAPSHOT_DELETE_MIRROR_ABORT);
+    bool mirror_pivot = !!(flags & VIR_DOMAIN_SNAPSHOT_DELETE_MIRROR_PIVOT);

     virCheckFlags(VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN |
                   VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY |
-                  VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY, -1);
+                  VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY |
+                  VIR_DOMAIN_SNAPSHOT_DELETE_MIRROR_ABORT |
+                  VIR_DOMAIN_SNAPSHOT_DELETE_MIRROR_PIVOT, -1);

     qemuDriverLock(driver);
     virUUIDFormat(snapshot->domain->uuid, uuidstr);
@@ -11323,12 +11387,21 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
                             _("domain has active disk mirrors"));
             goto cleanup;
         }
+        if (!(mirror_abort || mirror_pivot)) {
+            qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                            _("must specify whether to abort or pivot "
+                              "mirrors before deleting snapshot"));
+            goto cleanup;
+        }
+        metadata_only = true;
+        flags = 0;
+    } else if (mirror_abort || mirror_pivot) {
         qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
-                        _("deletion of active disk mirrors unimplemented"));
+                        _("snapshot has no disk mirrors"));
         goto cleanup;
     }

-    if (!(flags & VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY)) {
+    if (!metadata_only) {
         if (!(flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY) &&
             snap->def->state == VIR_DOMAIN_DISK_SNAPSHOT)
             external++;
@@ -11347,6 +11420,10 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
     if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
         goto cleanup;

+    if ((mirror_abort || mirror_pivot) &&
+        qemuDomainSnapshotDeleteMirror(driver, vm, snap, mirror_pivot) < 0)
+            goto endjob;
+
     if (flags & (VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN |
                  VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY)) {
         rem.driver = driver;
-- 
1.7.7.6

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list


[Virt Tools]     [Libvirt Users]     [Fedora Users]     [Fedora Legacy]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]

Powered by Linux

Google
  Web www.spinics.net