diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c index 726df95067..2442865b9b 100644 --- a/src/qemu/qemu_blockjob.c +++ b/src/qemu/qemu_blockjob.c @@ -1406,6 +1406,8 @@ qemuBlockJobProcessEventConcludedCopyAbort(virQEMUDriver *driver, qemuBlockJobData *job, qemuDomainAsyncJob asyncJob) { + qemuDomainObjPrivate *priv = vm->privateData; + VIR_DEBUG("copy job '%s' on VM '%s' aborted", job->name, vm->def->name); /* mirror may be NULL for copy job corresponding to migration */ @@ -1413,6 +1415,21 @@ qemuBlockJobProcessEventConcludedCopyAbort(virQEMUDriver *driver, !job->disk->mirror) return; + if (!job->jobflagsmissing) { + bool shallow = job->jobflags & VIR_DOMAIN_BLOCK_COPY_SHALLOW; + bool reuse = job->jobflags & VIR_DOMAIN_BLOCK_COPY_REUSE_EXT; + + /* In the special case of a shallow copy with reused image we don't + * hotplug the full chain when QEMU_CAPS_BLOCKDEV_SNAPSHOT_ALLOW_WRITE_ONLY + * is supported. Attempting to delete it would thus result in spurious + * errors as we'd attempt to blockdev-del images which were not added + * yet */ + if (reuse && shallow && + virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV_SNAPSHOT_ALLOW_WRITE_ONLY) && + virStorageSourceHasBacking(job->disk->mirror)) + g_clear_pointer(&job->disk->mirror->backingStore, virObjectUnref); + } + /* activeWrite bitmap is removed automatically here */ qemuBlockJobEventProcessConcludedRemoveChain(driver, vm, asyncJob, job->disk->mirror); g_clear_pointer(&job->disk->mirror, virObjectUnref);