Refresh the state of the jobs and process any events that might have
happened while libvirt was not running.
The job state processing requires some care to figure out if a job
needs to be bumped.t
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
src/qemu/qemu_blockjob.c | 57 ++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_blockjob.h | 4 +++
src/qemu/qemu_process.c | 7 ++++-
3 files changed, 67 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c
index 6aa8b1df51..8631db7986 100644
--- a/src/qemu/qemu_blockjob.c
+++ b/src/qemu/qemu_blockjob.c
@@ -222,6 +222,63 @@ qemuBlockJobIsRunning(qemuBlockJobDataPtr job)
}
+int
+qemuBlockJobRefreshJobs(virQEMUDriverPtr driver,
+ virDomainObjPtr vm)
+{
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+ qemuMonitorJobInfoPtr *jobinfo = NULL;
+ size_t njobinfo = 0;
+ qemuBlockJobDataPtr job = NULL;
+ qemuBlockjobState newstate;
+ size_t i;
+ int ret = -1;
+ int rc;
+
+ qemuDomainObjEnterMonitor(driver, vm);
+
+ rc = qemuMonitorGetJobInfo(priv->mon, &jobinfo, &njobinfo);
+
+ if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
+ goto cleanup;
+
+ for (i = 0; i < njobinfo; i++) {
+ if (!(job = virHashLookup(priv->blockjobs, jobinfo[i]->id))) {
+ VIR_DEBUG("ignoring untracked job '%s'",
jobinfo[i]->id);
+ continue;
+ }
+
+ newstate = qemuBlockjobConvertMonitorStatus(jobinfo[i]->status);
+ if (newstate == QEMU_BLOCKJOB_STATE_LAST)
+ continue;
+
+ if (newstate != job->state) {
+ if ((job->state == QEMU_BLOCKJOB_STATE_FAILED ||
+ job->state == QEMU_BLOCKJOB_STATE_COMPLETED)) {
+ /* preserve the old state but allow the job to be bumped to
+ * execute the finishing steps */
+ job->newstate = job->state;
+ } else {
+ job->newstate = newstate;
+ }
+ }
+
+ /* qemuBlockJobUpdate checks whether something is needed */
+ qemuBlockJobUpdate(vm, job, QEMU_ASYNC_JOB_NONE);
+ job = NULL; /* job may have become invalid here */
+ }
+
+ ret = 0;
+
+ cleanup:
+ for (i = 0; i < njobinfo; i++)
+ qemuMonitorJobInfoFree(jobinfo[i]);
+ VIR_FREE(jobinfo);
+
+ return ret;
+}
+
+
/**
* qemuBlockJobEmitEvents:
*
diff --git a/src/qemu/qemu_blockjob.h b/src/qemu/qemu_blockjob.h
index 9a2d047d03..6e86c78a9b 100644
--- a/src/qemu/qemu_blockjob.h
+++ b/src/qemu/qemu_blockjob.h
@@ -105,6 +105,10 @@ void
qemuBlockJobStartupFinalize(virDomainObjPtr vm,
qemuBlockJobDataPtr job);
+int
+qemuBlockJobRefreshJobs(virQEMUDriverPtr driver,
+ virDomainObjPtr vm);
+
int qemuBlockJobUpdate(virDomainObjPtr vm,
qemuBlockJobDataPtr job,
int asyncJob);
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index fb687a1fd9..75edced15d 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7895,7 +7895,12 @@ static int
qemuProcessRefreshBlockjobs(virQEMUDriverPtr driver,
virDomainObjPtr vm)
{
- return qemuProcessRefreshLegacyBlockjobs(driver, vm);
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+
+ if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV))
+ return qemuBlockJobRefreshJobs(driver, vm);
+ else
+ return qemuProcessRefreshLegacyBlockjobs(driver, vm);
}
--
2.19.2