From: Peter Krempa Date: Fri, 29 Mar 2019 07:47:38 +0000 (+0100) Subject: qemu: blockjob: Unplug inherited storage chains when concluding blockjob X-Git-Tag: v5.6.0-rc1~123 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ae4b921f2aa464706a5944d95380ab6f5318fb6b;p=thirdparty%2Flibvirt.git qemu: blockjob: Unplug inherited storage chains when concluding blockjob 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 Reviewed-by: Ján Tomko --- diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c index d55eb48605..292610d089 100644 --- a/src/qemu/qemu_blockjob.c +++ b/src/qemu/qemu_blockjob.c @@ -536,6 +536,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, @@ -652,6 +674,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);