mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-23 14:15:28 +00:00
qemu: Consolidate disk blockjob variables into a structure
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@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
f5eadd1d92
commit
89a877b312
@ -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:
|
||||
*
|
||||
@ -161,7 +172,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:
|
||||
@ -177,7 +188,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:
|
||||
@ -214,22 +225,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;
|
||||
@ -252,11 +262,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;
|
||||
}
|
||||
|
||||
|
||||
@ -275,5 +285,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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -1063,6 +1063,11 @@ qemuDomainDiskPrivateNew(void)
|
||||
if (!(priv = virObjectNew(qemuDomainDiskPrivateClass)))
|
||||
return NULL;
|
||||
|
||||
if (VIR_ALLOC(priv->blockjob) < 0) {
|
||||
virObjectUnref(priv);
|
||||
priv = NULL;
|
||||
}
|
||||
|
||||
return (virObjectPtr) priv;
|
||||
}
|
||||
|
||||
@ -1071,10 +1076,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;
|
||||
@ -9248,7 +9253,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);
|
||||
@ -9277,7 +9283,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)
|
||||
|
@ -30,6 +30,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"
|
||||
@ -389,13 +390,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 */
|
||||
|
@ -4717,7 +4717,7 @@ processBlockJobEvent(virQEMUDriverPtr driver,
|
||||
int status)
|
||||
{
|
||||
virDomainDiskDefPtr disk;
|
||||
qemuDomainDiskPrivatePtr diskPriv;
|
||||
qemuBlockJobDataPtr job;
|
||||
|
||||
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
|
||||
return;
|
||||
@ -4732,10 +4732,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);
|
||||
|
||||
@ -17342,7 +17342,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",
|
||||
@ -17449,7 +17449,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;
|
||||
@ -17873,7 +17873,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",
|
||||
@ -18273,7 +18273,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;
|
||||
|
@ -927,7 +927,7 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
|
||||
virQEMUDriverPtr driver = opaque;
|
||||
struct qemuProcessEvent *processEvent = NULL;
|
||||
virDomainDiskDefPtr disk;
|
||||
qemuDomainDiskPrivatePtr diskPriv;
|
||||
qemuBlockJobDataPtr job;
|
||||
char *data = NULL;
|
||||
|
||||
virObjectLock(vm);
|
||||
@ -937,14 +937,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 */
|
||||
|
Loading…
Reference in New Issue
Block a user