[libvirt] [PATCHv2 8/9] qemu: snapshot: Switch snapshot file deletion to the new storage API

Peter Krempa pkrempa at redhat.com
Thu Jan 16 13:14:37 UTC 2014


Use the new storage conversion APIs to delete garbage left behind after
a failed snapshot attempt using the storage driver.
---
 src/qemu/qemu_driver.c | 60 ++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 46 insertions(+), 14 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 7f01014..ede671a 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -12182,7 +12182,8 @@ cleanup:

 /* The domain is expected to hold monitor lock.  */
 static int
-qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
+qemuDomainSnapshotCreateSingleDiskActive(virConnectPtr conn,
+                                         virQEMUDriverPtr driver,
                                          virDomainObjPtr vm,
                                          virDomainSnapshotDiskDefPtr snap,
                                          virDomainDiskDefPtr disk,
@@ -12199,6 +12200,7 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
     int ret = -1;
     int fd = -1;
     bool need_unlink = false;
+    virStorageEphemeralPtr temppool = NULL;

     if (snap->snapshot != VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -12218,6 +12220,9 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
     virStorageFileFreeMetadata(disk->backingChain);
     disk->backingChain = NULL;

+    if (!(temppool = virStorageEphemeralFromSnapshotDiskDef(conn, snap)))
+        goto cleanup;
+
     switch (snap->type) {
     case VIR_DOMAIN_DISK_TYPE_BLOCK:
         reuse = true;
@@ -12276,8 +12281,16 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
     }

 cleanup:
-    if (need_unlink && unlink(source))
-        VIR_WARN("unable to unlink just-created %s", source);
+    if (need_unlink) {
+        if (virStorageVolDelete(temppool->vol, 0) < 0) {
+            char *path = virStorageVolGetPath(temppool->vol);
+            VIR_WARN("unable to remove just-created snapshot storage '%s'",
+                     NULLSTR(path));
+            VIR_FREE(path);
+        }
+    }
+
+    virStorageEphemeralFree(temppool);
     VIR_FREE(device);
     VIR_FREE(source);
     VIR_FREE(persistSource);
@@ -12288,7 +12301,8 @@ cleanup:
  * counterpart to qemuDomainSnapshotCreateSingleDiskActive, called
  * only on a failed transaction. */
 static void
-qemuDomainSnapshotUndoSingleDiskActive(virQEMUDriverPtr driver,
+qemuDomainSnapshotUndoSingleDiskActive(virConnectPtr conn,
+                                       virQEMUDriverPtr driver,
                                        virDomainObjPtr vm,
                                        virDomainDiskDefPtr origdisk,
                                        virDomainDiskDefPtr disk,
@@ -12297,17 +12311,33 @@ qemuDomainSnapshotUndoSingleDiskActive(virQEMUDriverPtr driver,
 {
     char *source = NULL;
     char *persistSource = NULL;
-    struct stat st;
+
+    virStorageEphemeralPtr temppool = NULL;

     if (VIR_STRDUP(source, origdisk->src) < 0 ||
         (persistDisk && VIR_STRDUP(persistSource, source) < 0))
         goto cleanup;

-    qemuDomainPrepareDiskChainElement(driver, vm, disk, disk->src,
-                                      VIR_DISK_CHAIN_NO_ACCESS);
-    if (need_unlink && stat(disk->src, &st) == 0 &&
-        S_ISREG(st.st_mode) && unlink(disk->src) < 0)
-        VIR_WARN("Unable to remove just-created %s", disk->src);
+    switch (origdisk->type) {
+    case VIR_DOMAIN_DISK_TYPE_BLOCK:
+    case -1: /* type was not provided in snapshot conf */
+    case VIR_DOMAIN_DISK_TYPE_FILE:
+        qemuDomainPrepareDiskChainElement(driver, vm, disk, disk->src,
+                                          VIR_DISK_CHAIN_NO_ACCESS);
+        break;
+
+    default:
+        break;
+    }
+
+    temppool = virStorageEphemeralFromDiskDef(conn, disk);
+
+    if (need_unlink && temppool &&
+        virStorageVolDelete(temppool->vol, 0) < 0) {
+        char *path = virStorageVolGetPath(temppool->vol);
+        VIR_WARN("Unable to remove just-created '%s'", NULLSTR(path));
+        VIR_FREE(path);
+    }

     /* Update vm in place to match changes.  */
     VIR_FREE(disk->src);
@@ -12324,13 +12354,15 @@ qemuDomainSnapshotUndoSingleDiskActive(virQEMUDriverPtr driver,
     }

 cleanup:
+    virStorageEphemeralFree(temppool);
     VIR_FREE(source);
     VIR_FREE(persistSource);
 }

 /* The domain is expected to be locked and active. */
 static int
-qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver,
+qemuDomainSnapshotCreateDiskActive(virConnectPtr conn,
+                                   virQEMUDriverPtr driver,
                                    virDomainObjPtr vm,
                                    virDomainSnapshotObjPtr snap,
                                    unsigned int flags,
@@ -12383,7 +12415,7 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver,
             }
         }

-        ret = qemuDomainSnapshotCreateSingleDiskActive(driver, vm,
+        ret = qemuDomainSnapshotCreateSingleDiskActive(conn, driver, vm,
                                                        &snap->def->disks[i],
                                                        vm->def->disks[i],
                                                        persistDisk, actions,
@@ -12412,7 +12444,7 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver,
                         persistDisk = vm->newDef->disks[indx];
                 }

-                qemuDomainSnapshotUndoSingleDiskActive(driver, vm,
+                qemuDomainSnapshotUndoSingleDiskActive(conn, driver, vm,
                                                        snap->def->dom->disks[i],
                                                        vm->def->disks[i],
                                                        persistDisk,
@@ -12555,7 +12587,7 @@ qemuDomainSnapshotCreateActiveExternal(virConnectPtr conn,
      *
      * Next we snapshot the disks.
      */
-    if ((ret = qemuDomainSnapshotCreateDiskActive(driver, vm, snap, flags,
+    if ((ret = qemuDomainSnapshotCreateDiskActive(conn, driver, vm, snap, flags,
                                                   QEMU_ASYNC_JOB_SNAPSHOT)) < 0)
         goto endjob;

-- 
1.8.5.2




More information about the libvir-list mailing list