Use the new storage driver APIs to delete snapshot backing files in case
of failure instead of directly relying on "unlink". This will help us in
the future when we will be adding network based storage without local
representation in the host.
---
Notes:
Version 5:
- no change, wasn't reviewed yet
src/qemu/qemu_driver.c | 32 +++++++++++++++++++++++---------
1 file changed, 23 insertions(+), 9 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 94844df..b94382d 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -94,6 +94,7 @@
#include "virstring.h"
#include "viraccessapicheck.h"
#include "viraccessapicheckqemu.h"
+#include "libvirt_private.h"
#define VIR_FROM_THIS VIR_FROM_QEMU
@@ -12629,7 +12630,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,
@@ -12647,6 +12649,7 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
int ret = -1;
int fd = -1;
bool need_unlink = false;
+ virStorageFilePtr snapfile = NULL;
if (snap->snapshot != VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -12666,6 +12669,9 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
virStorageFileFreeMetadata(disk->backingChain);
disk->backingChain = NULL;
+ if (!(snapfile = virStorageFileInitFromSnapshotDef(conn, snap)))
+ goto cleanup;
+
switch (snap->type) {
case VIR_DOMAIN_DISK_TYPE_BLOCK:
reuse = true;
@@ -12741,8 +12747,9 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
}
cleanup:
- if (need_unlink && unlink(source))
+ if (need_unlink && virStorageFileUnlink(snapfile))
VIR_WARN("unable to unlink just-created %s", source);
+ virStorageFileFree(snapfile);
VIR_FREE(device);
VIR_FREE(source);
VIR_FREE(persistSource);
@@ -12753,7 +12760,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,
@@ -12762,16 +12770,20 @@ qemuDomainSnapshotUndoSingleDiskActive(virQEMUDriverPtr driver,
{
char *source = NULL;
char *persistSource = NULL;
+ virStorageFilePtr diskfile = NULL;
struct stat st;
+ diskfile = virStorageFileInitFromDiskDef(conn, disk);
+
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)
+ if (need_unlink && diskfile &&
+ virStorageFileStat(diskfile, &st) == 0 && S_ISREG(st.st_mode)
&&
+ virStorageFileUnlink(diskfile) < 0)
VIR_WARN("Unable to remove just-created %s", disk->src);
/* Update vm in place to match changes. */
@@ -12789,13 +12801,15 @@ qemuDomainSnapshotUndoSingleDiskActive(virQEMUDriverPtr driver,
}
cleanup:
+ virStorageFileFree(diskfile);
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,
@@ -12843,7 +12857,7 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver,
persistDisk = vm->newDef->disks[indx];
}
- ret = qemuDomainSnapshotCreateSingleDiskActive(driver, vm,
+ ret = qemuDomainSnapshotCreateSingleDiskActive(conn, driver, vm,
&snap->def->disks[i],
vm->def->disks[i],
persistDisk, actions,
@@ -12889,7 +12903,7 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver,
}
- qemuDomainSnapshotUndoSingleDiskActive(driver, vm,
+ qemuDomainSnapshotUndoSingleDiskActive(conn, driver, vm,
snap->def->dom->disks[i],
vm->def->disks[i],
persistDisk,
@@ -13031,7 +13045,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.3