diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c index 718e311213e84251b2d8e6a3275d8ae6d61b1d02..498e2a716f54c60ec537c515cd998338cb9766d0 100644 --- a/src/qemu/qemu_blockjob.c +++ b/src/qemu/qemu_blockjob.c @@ -1004,6 +1004,44 @@ qemuBlockJobProcessEventCompletedPull(virQEMUDriverPtr driver, } +/** + * qemuBlockJobDeleteImages: + * @driver: qemu driver object + * @vm: domain object + * @disk: disk object that the chain to be deleted is associated with + * @top: top snapshot of the chain to be deleted + * + * Helper for removing snapshot images. Intended for callers like + * qemuBlockJobProcessEventCompletedCommit() and + * qemuBlockJobProcessEventCompletedActiveCommit() as it relies on adjustments + * these functions perform on the 'backingStore' chain to function correctly. + * + * TODO look into removing backing store for non-local snapshots too + */ +static void +qemuBlockJobDeleteImages(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainDiskDefPtr disk, + virStorageSourcePtr top) +{ + virStorageSourcePtr p = top; + g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); + uid_t uid; + gid_t gid; + + for (; p != NULL; p = p->backingStore) { + if (virStorageSourceGetActualType(p) == VIR_STORAGE_TYPE_FILE) { + + qemuDomainGetImageIds(cfg, vm, p, disk->src, &uid, &gid); + + if (virFileRemove(p->path, uid, gid) < 0) { + VIR_WARN("Unable to remove snapshot image file '%s' (%s)", + p->path, g_strerror(errno)); + } + } + } +} + /** * qemuBlockJobProcessEventCompletedCommit: * @driver: qemu driver object @@ -1070,6 +1108,10 @@ qemuBlockJobProcessEventCompletedCommit(virQEMUDriverPtr driver, job->data.commit.topparent->backingStore = job->data.commit.base; qemuBlockJobEventProcessConcludedRemoveChain(driver, vm, asyncJob, job->data.commit.top); + + if (job->data.commit.deleteCommittedImages) + qemuBlockJobDeleteImages(driver, vm, job->disk, job->data.commit.top); + virObjectUnref(job->data.commit.top); job->data.commit.top = NULL; @@ -1160,6 +1202,10 @@ qemuBlockJobProcessEventCompletedActiveCommit(virQEMUDriverPtr driver, job->disk->src->readonly = job->data.commit.top->readonly; qemuBlockJobEventProcessConcludedRemoveChain(driver, vm, asyncJob, job->data.commit.top); + + if (job->data.commit.deleteCommittedImages) + qemuBlockJobDeleteImages(driver, vm, job->disk, job->data.commit.top); + virObjectUnref(job->data.commit.top); job->data.commit.top = NULL; /* the mirror element does not serve functional purpose for the commit job */