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