Block job state was widely untracked by libvirt across restarts which was allowed by a stateless block job finishing handler which discarded disk state and redetected it. This is undesirable since we'll need to track more information for individual blockjobs due to -blockdev integration requirements. In case of legacy blockjobs we can recover whether the job is present at reconnect time by querying qemu. Adding tracking whether a job is present will allow simplification of the non-shared-storage cancellation code. Signed-off-by: Peter Krempa <pkrempa@xxxxxxxxxx> --- src/qemu/qemu_process.c | 67 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 3fccbc79bb..471e11115f 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -7755,6 +7755,70 @@ qemuProcessRefreshCPU(virQEMUDriverPtr driver, } +static int +qemuProcessRefreshLegacyBlockjob(void *payload, + const void *name, + void *opaque) +{ + const char *jobname = name; + virDomainObjPtr vm = opaque; + qemuMonitorBlockJobInfoPtr info = payload; + virDomainDiskDefPtr disk; + qemuDomainDiskPrivatePtr diskPriv; + qemuBlockJobDataPtr job; + + if (!(disk = qemuProcessFindDomainDiskByAliasOrQOM(vm, jobname, jobname))) { + VIR_DEBUG("could not find disk for block job '%s'", jobname); + return 0; + } + + diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk); + job = diskPriv->blockjob; + + if (disk->mirror) { + if (info->ready == 1 || + (info->ready == -1 && info->end == info->cur)) + disk->mirrorState = VIR_DOMAIN_BLOCK_JOB_READY; + } + + job->started = true; + job->status = -1; + + return 0; +} + + +static int +qemuProcessRefreshLegacyBlockjobs(virQEMUDriverPtr driver, + virDomainObjPtr vm) +{ + virHashTablePtr blockJobs = NULL; + int ret = -1; + + qemuDomainObjEnterMonitor(driver, vm); + blockJobs = qemuMonitorGetAllBlockJobInfo(qemuDomainGetMonitor(vm)); + if (qemuDomainObjExitMonitor(driver, vm) < 0 || !blockJobs) + goto cleanup; + + if (virHashForEach(blockJobs, qemuProcessRefreshLegacyBlockjob, vm) < 0) + goto cleanup; + + ret = 0; + + cleanup: + virHashFree(blockJobs); + return ret; +} + + +static int +qemuProcessRefreshBlockjobs(virQEMUDriverPtr driver, + virDomainObjPtr vm) +{ + return qemuProcessRefreshLegacyBlockjobs(driver, vm); +} + + struct qemuProcessReconnectData { virQEMUDriverPtr driver; virDomainObjPtr obj; @@ -7958,6 +8022,9 @@ qemuProcessReconnect(void *opaque) qemuBlockNodeNamesDetect(driver, obj, QEMU_ASYNC_JOB_NONE) < 0) goto error; + if (qemuProcessRefreshBlockjobs(driver, obj) < 0) + goto error; + if (qemuRefreshVirtioChannelState(driver, obj, QEMU_ASYNC_JOB_NONE) < 0) goto error; -- 2.19.2 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list