Add support for handling the event either synchronously or
asynchronously using the event thread.
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
src/qemu/qemu_domain.c | 3 ++
src/qemu/qemu_domain.h | 1 +
src/qemu/qemu_driver.c | 23 +++++++++++++++
src/qemu/qemu_process.c | 63 +++++++++++++++++++++++++++++++++++++++++
4 files changed, 90 insertions(+)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 7162fca71b..13a90ab60b 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -14480,6 +14480,9 @@ qemuProcessEventFree(struct qemuProcessEvent *event)
case QEMU_PROCESS_EVENT_MONITOR_EOF:
VIR_FREE(event->data);
break;
+ case QEMU_PROCESS_EVENT_JOB_STATUS_CHANGE:
+ virObjectUnref(event->data);
+ break;
case QEMU_PROCESS_EVENT_PR_DISCONNECT:
case QEMU_PROCESS_EVENT_LAST:
break;
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index b42b205398..3ccea3177e 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -514,6 +514,7 @@ typedef enum {
QEMU_PROCESS_EVENT_NIC_RX_FILTER_CHANGED,
QEMU_PROCESS_EVENT_SERIAL_CHANGED,
QEMU_PROCESS_EVENT_BLOCK_JOB,
+ QEMU_PROCESS_EVENT_JOB_STATUS_CHANGE,
QEMU_PROCESS_EVENT_MONITOR_EOF,
QEMU_PROCESS_EVENT_PR_DISCONNECT,
QEMU_PROCESS_EVENT_RDMA_GID_STATUS_CHANGED,
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index a1dc2634ca..604beca155 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4717,6 +4717,26 @@ processBlockJobEvent(virQEMUDriverPtr driver,
}
+static void
+processJobStatusChangeEvent(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ qemuBlockJobDataPtr job)
+{
+ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
+ return;
+
+ if (!virDomainObjIsActive(vm)) {
+ VIR_DEBUG("Domain is not running");
+ goto endjob;
+ }
+
+ qemuBlockJobUpdate(vm, job, QEMU_ASYNC_JOB_NONE);
+
+ endjob:
+ qemuDomainObjEndJob(driver, vm);
+}
+
+
static void
processMonitorEOFEvent(virQEMUDriverPtr driver,
virDomainObjPtr vm)
@@ -4855,6 +4875,9 @@ static void qemuProcessEventHandler(void *data, void *opaque)
processEvent->action,
processEvent->status);
break;
+ case QEMU_PROCESS_EVENT_JOB_STATUS_CHANGE:
+ processJobStatusChangeEvent(driver, vm, processEvent->data);
+ break;
case QEMU_PROCESS_EVENT_MONITOR_EOF:
processMonitorEOFEvent(driver, vm);
break;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 4e24201674..416f4f5c9a 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -990,6 +990,68 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
}
+static int
+qemuProcessHandleJobStatusChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm,
+ const char *jobname,
+ int status,
+ void *opaque)
+{
+ virQEMUDriverPtr driver = opaque;
+ qemuDomainObjPrivatePtr priv;
+ struct qemuProcessEvent *processEvent = NULL;
+ qemuBlockJobDataPtr job = NULL;
+ int jobnewstate;
+
+ virObjectLock(vm);
+ priv = vm->privateData;
+
+ VIR_DEBUG("job '%s'(domain: %p,%s) state changed to
'%s'(%d)",
+ jobname, vm, vm->def->name,
+ qemuMonitorJobStatusTypeToString(status), status);
+
+ if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV)) {
+ VIR_DEBUG("job '%s' handled by old blockjob handler",
jobname);
+ goto cleanup;
+ }
+
+ if ((jobnewstate = qemuBlockjobConvertMonitorStatus(status)) ==
QEMU_BLOCKJOB_STATE_LAST)
+ goto cleanup;
+
+ if (!(job = virHashLookup(priv->blockjobs, jobname))) {
+ VIR_DEBUG("job '%s' not registered", jobname);
+ goto cleanup;
+ }
+
+ job->newstate = jobnewstate;
+
+ if (job->synchronous) {
+ VIR_DEBUG("job '%s' handled synchronously", jobname);
+ virDomainObjBroadcast(vm);
+ } else {
+ VIR_DEBUG("job '%s' handled by event thread", jobname);
+ if (VIR_ALLOC(processEvent) < 0)
+ goto cleanup;
+
+ processEvent->eventType = QEMU_PROCESS_EVENT_JOB_STATUS_CHANGE;
+ processEvent->vm = virObjectRef(vm);
+ processEvent->data = virObjectRef(job);
+
+ if (virThreadPoolSendJob(driver->workerPool, 0, processEvent) < 0) {
+ ignore_value(virObjectUnref(vm));
+ goto cleanup;
+ }
+
+ processEvent = NULL;
+ }
+
+ cleanup:
+ qemuProcessEventFree(processEvent);
+ virObjectUnlock(vm);
+ return 0;
+}
+
+
static int
qemuProcessHandleGraphics(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
@@ -1820,6 +1882,7 @@ static qemuMonitorCallbacks monitorCallbacks = {
.domainIOError = qemuProcessHandleIOError,
.domainGraphics = qemuProcessHandleGraphics,
.domainBlockJob = qemuProcessHandleBlockJob,
+ .jobStatusChange = qemuProcessHandleJobStatusChange,
.domainTrayChange = qemuProcessHandleTrayChange,
.domainPMWakeup = qemuProcessHandlePMWakeup,
.domainPMSuspend = qemuProcessHandlePMSuspend,
--
2.21.0