In cases when the disk frontend was unplugged while a blockjob was
running the blockjob inherits the backing chain. When the blockjob is
then terminated we need to unplug the chain as it will not be used any
more.
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
src/qemu/qemu_blockjob.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c
index 70b223b29d..8a1cf6893b 100644
--- a/src/qemu/qemu_blockjob.c
+++ b/src/qemu/qemu_blockjob.c
@@ -537,6 +537,28 @@ qemuBlockJobEventProcessLegacy(virQEMUDriverPtr driver,
}
+static void
+qemuBlockJobEventProcessConcludedRemoveChain(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ qemuDomainAsyncJob asyncJob,
+ virStorageSourcePtr chain)
+{
+ VIR_AUTOPTR(qemuBlockStorageSourceChainData) data = NULL;
+
+ if (!(data = qemuBlockStorageSourceChainDetachPrepareBlockdev(chain)))
+ return;
+
+ if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+ return;
+
+ qemuBlockStorageSourceChainDetach(qemuDomainGetMonitor(vm), data);
+ if (qemuDomainObjExitMonitor(driver, vm) < 0)
+ return;
+
+ qemuDomainStorageSourceChainAccessRevoke(driver, vm, chain);
+}
+
+
static void
qemuBlockJobEventProcessConcludedTransition(qemuBlockJobDataPtr job,
virQEMUDriverPtr driver,
@@ -653,6 +675,16 @@ qemuBlockJobEventProcessConcluded(qemuBlockJobDataPtr job,
qemuBlockJobEventProcessConcludedTransition(job, driver, vm, asyncJob);
+ /* unplug the backing chains in case the job inherited them */
+ if (!job->disk) {
+ if (job->chain)
+ qemuBlockJobEventProcessConcludedRemoveChain(driver, vm, asyncJob,
+ job->chain);
+ if (job->mirrorChain)
+ qemuBlockJobEventProcessConcludedRemoveChain(driver, vm, asyncJob,
+ job->mirrorChain);
+ }
+
cleanup:
if (dismissed) {
qemuBlockJobUnregister(job, vm);
--
2.21.0