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 | 66 +++++++++++++++++++++++++++++++++++++++++
4 files changed, 93 insertions(+)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 7845889dec..9467d0fd32 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -13711,6 +13711,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 a243bdc80e..0a2973aba9 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -485,6 +485,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,
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f62d153c03..0c38a61adc 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4747,6 +4747,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)
@@ -4842,6 +4862,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 255a5acc13..fb687a1fd9 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -981,6 +981,71 @@ 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;
+ qemuBlockjobState 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;
+ }
+
+ jobnewstate = qemuBlockjobConvertMonitorStatus(status);
+
+ if (jobnewstate == 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);
+ VIR_STEAL_PTR(processEvent->data, job);
+
+ if (virThreadPoolSendJob(driver->workerPool, 0, processEvent) < 0) {
+ ignore_value(virObjectUnref(vm));
+ goto cleanup;
+ }
+
+ processEvent = NULL;
+ }
+
+ cleanup:
+ qemuProcessEventFree(processEvent);
+ virObjectUnref(job);
+ virObjectUnlock(vm);
+ return 0;
+}
+
+
static int
qemuProcessHandleGraphics(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
@@ -1735,6 +1800,7 @@ static qemuMonitorCallbacks monitorCallbacks = {
.domainIOError = qemuProcessHandleIOError,
.domainGraphics = qemuProcessHandleGraphics,
.domainBlockJob = qemuProcessHandleBlockJob,
+ .jobStatusChange = qemuProcessHandleJobStatusChange,
.domainTrayChange = qemuProcessHandleTrayChange,
.domainPMWakeup = qemuProcessHandlePMWakeup,
.domainPMSuspend = qemuProcessHandlePMSuspend,
--
2.19.2