[PATCH RFC 51/51] qemu: process: Refresh -blockdev based blockjobs on reconnect to qemu

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxx>
---
 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

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list



[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux