Currently in qemuProcessHandleBlockJob we either offload blockjob event processing to the worker thread or notify another thread that waits for blockjob event and that thread processes the event. But sometimes after event is offloaded to the worker thread we need to process the event in a different thread. To be able to to do it let's always set newstate/errmsg and then let whatever thread is first process it. Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy@xxxxxxxxxxxxx> --- src/qemu/qemu_driver.c | 17 ++++------------- src/qemu/qemu_process.c | 20 ++++++++++++-------- 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 825bdd9..c06db3a 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -4118,9 +4118,7 @@ processSerialChangedEvent(virQEMUDriverPtr driver, static void processBlockJobEvent(virQEMUDriverPtr driver, virDomainObjPtr vm, - const char *diskAlias, - int type, - int status) + const char *diskAlias) { virDomainDiskDefPtr disk; g_autoptr(qemuBlockJobData) job = NULL; @@ -4139,14 +4137,10 @@ processBlockJobEvent(virQEMUDriverPtr driver, } if (!(job = qemuBlockJobDiskGetJob(disk))) { - VIR_DEBUG("creating new block job object for '%s'", diskAlias); - if (!(job = qemuBlockJobDiskNew(vm, disk, type, diskAlias))) - goto endjob; - job->state = QEMU_BLOCKJOB_STATE_RUNNING; + VIR_DEBUG("disk %s job not found", diskAlias); + goto endjob; } - job->newstate = status; - qemuBlockJobUpdate(vm, job, QEMU_ASYNC_JOB_NONE); endjob: @@ -4321,10 +4315,7 @@ static void qemuProcessEventHandler(void *data, void *opaque) processEvent->action); break; case QEMU_PROCESS_EVENT_BLOCK_JOB: - processBlockJobEvent(driver, vm, - processEvent->data, - processEvent->action, - processEvent->status); + processBlockJobEvent(driver, vm, processEvent->data); break; case QEMU_PROCESS_EVENT_JOB_STATUS_CHANGE: processJobStatusChangeEvent(driver, vm, processEvent->data); diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 6422881..4d63e7d 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -953,13 +953,19 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon G_GNUC_UNUSED, if (!(disk = qemuProcessFindDomainDiskByAliasOrQOM(vm, diskAlias, NULL))) goto cleanup; - job = qemuBlockJobDiskGetJob(disk); + if (!(job = qemuBlockJobDiskGetJob(disk))) { + VIR_DEBUG("creating new block job object for '%s'", diskAlias); + if (!(job = qemuBlockJobDiskNew(vm, disk, type, diskAlias))) + goto cleanup; + job->state = QEMU_BLOCKJOB_STATE_RUNNING; + } - if (job && job->synchronous) { - /* We have a SYNC API waiting for this event, dispatch it back */ - job->newstate = status; - VIR_FREE(job->errmsg); - job->errmsg = g_strdup(error); + job->newstate = status; + VIR_FREE(job->errmsg); + job->errmsg = g_strdup(error); + + /* We have a SYNC API waiting for this event, dispatch it back */ + if (job->synchronous) { virDomainObjBroadcast(vm); } else { /* there is no waiting SYNC API, dispatch the update to a thread */ @@ -969,8 +975,6 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon G_GNUC_UNUSED, data = g_strdup(diskAlias); processEvent->data = data; processEvent->vm = virObjectRef(vm); - processEvent->action = type; - processEvent->status = status; if (virThreadPoolSendJob(driver->workerPool, 0, processEvent) < 0) { virObjectUnref(vm); -- 1.8.3.1