Struct qemuDomainDiskPrivate was holding multiple variables connected to a disk block job. Consolidate them into a new struct qemuBlockJobData. This will also allow simpler extensions to the block job mechanisms. Signed-off-by: Peter Krempa <pkrempa@xxxxxxxxxx> --- src/qemu/qemu_blockjob.c | 36 +++++++++++++++++++++++------------- src/qemu/qemu_blockjob.h | 15 +++++++++++++++ src/qemu/qemu_domain.c | 12 +++++++++--- src/qemu/qemu_domain.h | 9 ++------- src/qemu/qemu_driver.c | 16 ++++++++-------- src/qemu/qemu_process.c | 15 ++++++++------- 6 files changed, 65 insertions(+), 38 deletions(-) diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c index 1b6d16cbb9..b1a30b1edb 100644 --- a/src/qemu/qemu_blockjob.c +++ b/src/qemu/qemu_blockjob.c @@ -42,6 +42,17 @@ VIR_LOG_INIT("qemu.qemu_blockjob"); +void +qemuBlockJobDataFree(qemuBlockJobDataPtr job) +{ + if (!job) + return; + + VIR_FREE(job->errmsg); + VIR_FREE(job); +} + + /** * qemuBlockJobEmitEvents: * @@ -160,7 +171,7 @@ qemuBlockJobEventProcess(virQEMUDriverPtr driver, virStorageSourceBackingStoreClear(disk->src); ignore_value(qemuDomainDetermineDiskChain(driver, vm, disk, true)); ignore_value(qemuBlockNodeNamesDetect(driver, vm, asyncJob)); - diskPriv->blockjob = false; + diskPriv->blockjob->started = false; break; case VIR_DOMAIN_BLOCK_JOB_READY: @@ -176,7 +187,7 @@ qemuBlockJobEventProcess(virQEMUDriverPtr driver, } disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_NONE; disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN; - diskPriv->blockjob = false; + diskPriv->blockjob->started = false; break; case VIR_DOMAIN_BLOCK_JOB_LAST: @@ -213,22 +224,21 @@ qemuBlockJobUpdateDisk(virDomainObjPtr vm, virDomainDiskDefPtr disk, char **error) { - qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk); + qemuBlockJobDataPtr job = QEMU_DOMAIN_DISK_PRIVATE(disk)->blockjob; qemuDomainObjPrivatePtr priv = vm->privateData; - int status = diskPriv->blockJobStatus; + int status = job->status; if (error) *error = NULL; if (status != -1) { qemuBlockJobEventProcess(priv->driver, vm, disk, asyncJob, - diskPriv->blockJobType, - diskPriv->blockJobStatus); - diskPriv->blockJobStatus = -1; + job->type, status); + job->status = -1; if (error) - VIR_STEAL_PTR(*error, diskPriv->blockJobError); + VIR_STEAL_PTR(*error, job->errmsg); else - VIR_FREE(diskPriv->blockJobError); + VIR_FREE(job->errmsg); } return status; @@ -251,11 +261,11 @@ qemuBlockJobUpdateDisk(virDomainObjPtr vm, void qemuBlockJobSyncBeginDisk(virDomainDiskDefPtr disk) { - qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk); + qemuBlockJobDataPtr job = QEMU_DOMAIN_DISK_PRIVATE(disk)->blockjob; VIR_DEBUG("disk=%s", disk->dst); - diskPriv->blockJobSync = true; - diskPriv->blockJobStatus = -1; + job->synchronous = true; + job->status = -1; } @@ -274,5 +284,5 @@ qemuBlockJobSyncEndDisk(virDomainObjPtr vm, { VIR_DEBUG("disk=%s", disk->dst); qemuBlockJobUpdateDisk(vm, asyncJob, disk, NULL); - QEMU_DOMAIN_DISK_PRIVATE(disk)->blockJobSync = false; + QEMU_DOMAIN_DISK_PRIVATE(disk)->blockjob->synchronous = false; } diff --git a/src/qemu/qemu_blockjob.h b/src/qemu/qemu_blockjob.h index 0c440757f2..1479c6f720 100644 --- a/src/qemu/qemu_blockjob.h +++ b/src/qemu/qemu_blockjob.h @@ -25,6 +25,21 @@ # include "internal.h" # include "qemu_conf.h" + +typedef struct _qemuBlockJobData qemuBlockJobData; +typedef qemuBlockJobData *qemuBlockJobDataPtr; + +struct _qemuBlockJobData { + bool started; + int type; + int status; + char *errmsg; + bool synchronous; /* API call is waiting for this job */ +}; + +void +qemuBlockJobDataFree(qemuBlockJobDataPtr job); + int qemuBlockJobUpdateDisk(virDomainObjPtr vm, int asyncJob, virDomainDiskDefPtr disk, diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 1eb0e31df0..5a64231f95 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1062,6 +1062,11 @@ qemuDomainDiskPrivateNew(void) if (!(priv = virObjectNew(qemuDomainDiskPrivateClass))) return NULL; + if (VIR_ALLOC(priv->blockjob) < 0) { + virObjectUnref(priv); + priv = NULL; + } + return (virObjectPtr) priv; } @@ -1070,10 +1075,10 @@ qemuDomainDiskPrivateDispose(void *obj) { qemuDomainDiskPrivatePtr priv = obj; - VIR_FREE(priv->blockJobError); virStorageSourceFree(priv->migrSource); VIR_FREE(priv->qomName); VIR_FREE(priv->nodeCopyOnRead); + qemuBlockJobDataFree(priv->blockjob); } static virClassPtr qemuDomainStorageSourcePrivateClass; @@ -9255,7 +9260,8 @@ qemuDomainDiskBlockJobIsActive(virDomainDiskDefPtr disk) return true; } - if (diskPriv->blockjob) { + if (diskPriv->blockjob && + diskPriv->blockjob->started) { virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("disk '%s' already in active block job"), disk->dst); @@ -9284,7 +9290,7 @@ qemuDomainHasBlockjob(virDomainObjPtr vm, virDomainDiskDefPtr disk = vm->def->disks[i]; qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk); - if (!copy_only && diskPriv->blockjob) + if (!copy_only && diskPriv->blockjob && diskPriv->blockjob->started) return true; if (disk->mirror && disk->mirrorJob == VIR_DOMAIN_BLOCK_JOB_TYPE_COPY) diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 53b5ea1678..a03950e77b 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -32,6 +32,7 @@ # include "snapshot_conf.h" # include "qemu_monitor.h" # include "qemu_agent.h" +# include "qemu_blockjob.h" # include "qemu_conf.h" # include "qemu_capabilities.h" # include "qemu_migration_params.h" @@ -388,13 +389,7 @@ struct _qemuDomainDiskPrivate { /* ideally we want a smarter way to interlock block jobs on single qemu disk * in the future, but for now we just disallow any concurrent job on a * single disk */ - bool blockjob; - - /* for some synchronous block jobs, we need to notify the owner */ - int blockJobType; /* type of the block job from the event */ - int blockJobStatus; /* status of the finished block job */ - char *blockJobError; /* block job completed event error */ - bool blockJobSync; /* the block job needs synchronized termination */ + qemuBlockJobDataPtr blockjob; bool migrating; /* the disk is being migrated */ virStorageSourcePtr migrSource; /* disk source object used for NBD migration */ diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 1b2a2d70ec..d06eabb265 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -4716,7 +4716,7 @@ processBlockJobEvent(virQEMUDriverPtr driver, int status) { virDomainDiskDefPtr disk; - qemuDomainDiskPrivatePtr diskPriv; + qemuBlockJobDataPtr job; if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) return; @@ -4731,10 +4731,10 @@ processBlockJobEvent(virQEMUDriverPtr driver, goto endjob; } - diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk); + job = QEMU_DOMAIN_DISK_PRIVATE(disk)->blockjob; - diskPriv->blockJobType = type; - diskPriv->blockJobStatus = status; + job->type = type; + job->status = status; qemuBlockJobUpdateDisk(vm, QEMU_ASYNC_JOB_NONE, disk, NULL); @@ -17294,7 +17294,7 @@ qemuDomainBlockPullCommon(virQEMUDriverPtr driver, if (ret < 0) goto endjob; - QEMU_DOMAIN_DISK_PRIVATE(disk)->blockjob = true; + QEMU_DOMAIN_DISK_PRIVATE(disk)->blockjob->started = true; if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0) VIR_WARN("Unable to save status on vm %s after state change", @@ -17401,7 +17401,7 @@ qemuDomainBlockJobAbort(virDomainPtr dom, if (!async) { qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk); qemuBlockJobUpdateDisk(vm, QEMU_ASYNC_JOB_NONE, disk, NULL); - while (diskPriv->blockjob) { + while (diskPriv->blockjob->started) { if (virDomainObjWait(vm) < 0) { ret = -1; goto endjob; @@ -17825,7 +17825,7 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm, disk->mirror = mirror; mirror = NULL; disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_COPY; - QEMU_DOMAIN_DISK_PRIVATE(disk)->blockjob = true; + QEMU_DOMAIN_DISK_PRIVATE(disk)->blockjob->started = true; if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0) VIR_WARN("Unable to save status on vm %s after state change", @@ -18225,7 +18225,7 @@ qemuDomainBlockCommit(virDomainPtr dom, } if (ret == 0) { - QEMU_DOMAIN_DISK_PRIVATE(disk)->blockjob = true; + QEMU_DOMAIN_DISK_PRIVATE(disk)->blockjob->started = true; mirror = NULL; } else { disk->mirror = NULL; diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 2f8e19d29d..72725fcdf1 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -926,7 +926,7 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED, virQEMUDriverPtr driver = opaque; struct qemuProcessEvent *processEvent = NULL; virDomainDiskDefPtr disk; - qemuDomainDiskPrivatePtr diskPriv; + qemuBlockJobDataPtr job; char *data = NULL; virObjectLock(vm); @@ -936,14 +936,15 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED, if (!(disk = qemuProcessFindDomainDiskByAliasOrQOM(vm, diskAlias, NULL))) goto error; - diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk); - if (diskPriv->blockJobSync) { + job = QEMU_DOMAIN_DISK_PRIVATE(disk)->blockjob; + + if (job->synchronous) { /* We have a SYNC API waiting for this event, dispatch it back */ - diskPriv->blockJobType = type; - diskPriv->blockJobStatus = status; - VIR_FREE(diskPriv->blockJobError); - ignore_value(VIR_STRDUP_QUIET(diskPriv->blockJobError, error)); + job->type = type; + job->status = status; + VIR_FREE(job->errmsg); + ignore_value(VIR_STRDUP_QUIET(job->errmsg, error)); virDomainObjBroadcast(vm); } else { /* there is no waiting SYNC API, dispatch the update to a thread */ -- 2.19.2 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list