]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Consolidate disk blockjob variables into a structure
authorPeter Krempa <pkrempa@redhat.com>
Wed, 17 Oct 2018 06:57:08 +0000 (08:57 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Thu, 17 Jan 2019 16:12:50 +0000 (17:12 +0100)
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>
src/qemu/qemu_blockjob.c
src/qemu/qemu_blockjob.h
src/qemu/qemu_domain.c
src/qemu/qemu_domain.h
src/qemu/qemu_driver.c
src/qemu/qemu_process.c

index 763a28de5b546588fa900d2b667c091d3605dfed..61bd58ee227640aa4b74c6d475572a78863ed7c3 100644 (file)
 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;
 }
index 0b28a6fa57c680920d1770562913e622bd1edfb0..178541417281fdfabbe7e7980a7fd4b348e541e1 100644 (file)
 # 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,
index 6f5e3bd826e828c0e5fb93ec5c5fb9e964c6719f..aa8fe111470ad2294ca7bbdbc8294a5be06e17d6 100644 (file)
@@ -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)
index a837b8a731b163316b99e751ecabce1d7100acf9..0119de515a1351e47243b521721ee999ab38a431 100644 (file)
@@ -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 */
index b9a92642dfa7e8fb8c425ff5897e65d4837db7e8..1c8dfbc6232cac81af0ba39aea00eaeab8b8006f 100644 (file)
@@ -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;
index aad6c125529a86766a0b97c4b3fc1259aa056af4..16c2e1d770b6cc28e46c5b40b7148e2e3eb6b95d 100644 (file)
@@ -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 */