In case when a user starts a block copy operation with VIR_DOMAIN_BLOCK_COPY_SHALLOW and VIR_DOMAIN_BLOCK_COPY_REUSE_EXT and both the reused image and the original disk have a backing image libvirt specifically does not insert the backing image until after the job is asked to be completed via virBlockJobAbort with VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT. This is so that management applications can copy the backing image on the background. Now when a user aborts the block job instead of cancelling it we'd ignore the fact that we didn't insert the backing image yet and the cancellation would result into a 'blockdev-del' of a invalid node name and thus an 'error' severity entry in the log. To solve this issue we use the same conditions when the backing image addition is avoided to remove the internal state for them prior to the call to unplug the mirror destination. Reported-by: Kashyap Chamarthy <kchamart@xxxxxxxxxx> Signed-off-by: Peter Krempa <pkrempa@xxxxxxxxxx> --- src/qemu/qemu_blockjob.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) 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); -- 2.35.1