[libvirt] [PATCH v2 3/5] Move QEMU-only fields from virDomainDiskDef into privateData

Jiri Denemark jdenemar at redhat.com
Wed May 13 12:28:47 UTC 2015


Signed-off-by: Jiri Denemark <jdenemar at redhat.com>
---

Notes:
    Version 2:
    - new patch

 src/conf/domain_conf.c    |  6 -----
 src/conf/domain_conf.h    | 10 --------
 src/libvirt_private.syms  |  1 -
 src/qemu/qemu_blockjob.c  | 48 +++++++++++++++++++++----------------
 src/qemu/qemu_domain.c    | 61 +++++++++++++++++++++++++++++++++++++++++++----
 src/qemu/qemu_domain.h    | 21 ++++++++++++++++
 src/qemu/qemu_driver.c    | 11 +++++----
 src/qemu/qemu_migration.c |  6 +++--
 src/qemu/qemu_process.c   | 17 +++++++------
 9 files changed, 125 insertions(+), 56 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 3204140..bf0099d 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1290,11 +1290,6 @@ virDomainDiskDefNew(virDomainXMLOptionPtr xmlopt)
         !(ret->privateData = xmlopt->privateData.diskNew()))
         goto error;
 
-    if (virCondInit(&ret->blockJobSyncCond) < 0) {
-        virReportSystemError(errno, "%s", _("Failed to initialize condition"));
-        goto error;
-    }
-
     return ret;
 
  error:
@@ -1319,7 +1314,6 @@ virDomainDiskDefFree(virDomainDiskDefPtr def)
     VIR_FREE(def->domain_name);
     virDomainDeviceInfoClear(&def->info);
     virObjectUnref(def->privateData);
-    virCondDestroy(&def->blockJobSyncCond);
 
     VIR_FREE(def);
 }
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index b5e7617..8312c20 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -691,20 +691,10 @@ struct _virDomainDiskDef {
     int tray_status; /* enum virDomainDiskTray */
     int removable; /* enum virTristateSwitch */
 
-    /* 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;
     virStorageSourcePtr mirror;
     int mirrorState; /* enum virDomainDiskMirrorState */
     int mirrorJob; /* virDomainBlockJobType */
 
-    /* for some synchronous block jobs, we need to notify the owner */
-    virCond blockJobSyncCond;
-    int blockJobType;   /* type of the block job from the event */
-    int blockJobStatus; /* status of the finished block job */
-    bool blockJobSync; /* the block job needs synchronized termination */
-
     struct {
         unsigned int cylinders;
         unsigned int heads;
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 67a7e21..2586572 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -308,7 +308,6 @@ virDomainGraphicsTypeFromString;
 virDomainGraphicsTypeToString;
 virDomainGraphicsVNCSharePolicyTypeFromString;
 virDomainGraphicsVNCSharePolicyTypeToString;
-virDomainHasBlockjob;
 virDomainHasNet;
 virDomainHostdevCapsTypeToString;
 virDomainHostdevDefAlloc;
diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c
index 729928a..b9572d0 100644
--- a/src/qemu/qemu_blockjob.c
+++ b/src/qemu/qemu_blockjob.c
@@ -65,6 +65,7 @@ qemuBlockJobEventProcess(virQEMUDriverPtr driver,
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
     virDomainDiskDefPtr persistDisk = NULL;
     bool save = false;
+    qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
 
     /* Have to generate two variants of the event for old vs. new
      * client callbacks */
@@ -127,7 +128,7 @@ qemuBlockJobEventProcess(virQEMUDriverPtr driver,
         disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN;
         ignore_value(qemuDomainDetermineDiskChain(driver, vm, disk,
                                                   true, true));
-        disk->blockjob = false;
+        diskPriv->blockjob = false;
         break;
 
     case VIR_DOMAIN_BLOCK_JOB_READY:
@@ -143,7 +144,7 @@ qemuBlockJobEventProcess(virQEMUDriverPtr driver,
             VIR_DOMAIN_DISK_MIRROR_STATE_ABORT : VIR_DOMAIN_DISK_MIRROR_STATE_NONE;
         disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN;
         save = true;
-        disk->blockjob = false;
+        diskPriv->blockjob = false;
         break;
 
     case VIR_DOMAIN_BLOCK_JOB_LAST:
@@ -185,11 +186,13 @@ qemuBlockJobEventProcess(virQEMUDriverPtr driver,
 void
 qemuBlockJobSyncBegin(virDomainDiskDefPtr disk)
 {
-    if (disk->blockJobSync)
+    qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
+
+    if (diskPriv->blockJobSync)
         VIR_WARN("Disk %s already has synchronous block job",
                  disk->dst);
 
-    disk->blockJobSync = true;
+    diskPriv->blockJobSync = true;
 }
 
 
@@ -211,15 +214,17 @@ qemuBlockJobSyncEnd(virQEMUDriverPtr driver,
                     virDomainDiskDefPtr disk,
                     virConnectDomainEventBlockJobStatus *ret_status)
 {
-    if (disk->blockJobSync && disk->blockJobStatus != -1) {
+    qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
+
+    if (diskPriv->blockJobSync && diskPriv->blockJobStatus != -1) {
         if (ret_status)
-            *ret_status = disk->blockJobStatus;
+            *ret_status = diskPriv->blockJobStatus;
         qemuBlockJobEventProcess(driver, vm, disk,
-                                 disk->blockJobType,
-                                 disk->blockJobStatus);
-        disk->blockJobStatus = -1;
+                                 diskPriv->blockJobType,
+                                 diskPriv->blockJobStatus);
+        diskPriv->blockJobStatus = -1;
     }
-    disk->blockJobSync = false;
+    diskPriv->blockJobSync = false;
 }
 
 
@@ -248,24 +253,26 @@ qemuBlockJobSyncWaitWithTimeout(virQEMUDriverPtr driver,
                                 unsigned long long timeout,
                                 virConnectDomainEventBlockJobStatus *ret_status)
 {
-    if (!disk->blockJobSync) {
+    qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
+
+    if (!diskPriv->blockJobSync) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("No current synchronous block job"));
         return -1;
     }
 
-    while (disk->blockJobSync && disk->blockJobStatus == -1) {
+    while (diskPriv->blockJobSync && diskPriv->blockJobStatus == -1) {
         int r;
 
         if (!virDomainObjIsActive(vm)) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("guest unexpectedly quit"));
-            disk->blockJobSync = false;
+            diskPriv->blockJobSync = false;
             return -1;
         }
 
         if (timeout == (unsigned long long)-1) {
-            r = virCondWait(&disk->blockJobSyncCond, &vm->parent.lock);
+            r = virCondWait(&diskPriv->blockJobSyncCond, &vm->parent.lock);
         } else if (timeout) {
             unsigned long long now;
             if (virTimeMillisNow(&now) < 0) {
@@ -273,7 +280,8 @@ qemuBlockJobSyncWaitWithTimeout(virQEMUDriverPtr driver,
                                      _("Unable to get current time"));
                 return -1;
             }
-            r = virCondWaitUntil(&disk->blockJobSyncCond, &vm->parent.lock,
+            r = virCondWaitUntil(&diskPriv->blockJobSyncCond,
+                                 &vm->parent.lock,
                                  now + timeout);
             if (r < 0 && errno == ETIMEDOUT)
                 return 0;
@@ -283,7 +291,7 @@ qemuBlockJobSyncWaitWithTimeout(virQEMUDriverPtr driver,
         }
 
         if (r < 0) {
-            disk->blockJobSync = false;
+            diskPriv->blockJobSync = false;
             virReportSystemError(errno, "%s",
                                  _("Unable to wait on block job sync "
                                    "condition"));
@@ -292,11 +300,11 @@ qemuBlockJobSyncWaitWithTimeout(virQEMUDriverPtr driver,
     }
 
     if (ret_status)
-        *ret_status = disk->blockJobStatus;
+        *ret_status = diskPriv->blockJobStatus;
     qemuBlockJobEventProcess(driver, vm, disk,
-                             disk->blockJobType,
-                             disk->blockJobStatus);
-    disk->blockJobStatus = -1;
+                             diskPriv->blockJobType,
+                             diskPriv->blockJobStatus);
+    diskPriv->blockJobStatus = -1;
 
     return 0;
 }
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index b69f10f..608eed7 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -412,6 +412,53 @@ qemuDomainJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
 }
 
 
+static virClassPtr qemuDomainDiskPrivateClass;
+static void qemuDomainDiskPrivateDispose(void *obj);
+
+static int
+qemuDomainDiskPrivateOnceInit(void)
+{
+    qemuDomainDiskPrivateClass = virClassNew(virClassForObject(),
+                                             "qemuDomainDiskPrivate",
+                                             sizeof(qemuDomainDiskPrivate),
+                                             qemuDomainDiskPrivateDispose);
+    if (!qemuDomainDiskPrivateClass)
+        return -1;
+    else
+        return 0;
+}
+
+VIR_ONCE_GLOBAL_INIT(qemuDomainDiskPrivate)
+
+static virObjectPtr
+qemuDomainDiskPrivateNew(void)
+{
+    qemuDomainDiskPrivatePtr priv;
+
+    if (qemuDomainDiskPrivateInitialize() < 0)
+        return NULL;
+
+    if (!(priv = virObjectNew(qemuDomainDiskPrivateClass)))
+        return NULL;
+
+    if (virCondInit(&priv->blockJobSyncCond) < 0) {
+        virReportSystemError(errno, "%s", _("Failed to initialize condition"));
+        virObjectUnref(priv);
+        return NULL;
+    }
+
+    return (virObjectPtr) priv;
+}
+
+static void
+qemuDomainDiskPrivateDispose(void *obj)
+{
+    qemuDomainDiskPrivatePtr priv = obj;
+
+    virCondDestroy(&priv->blockJobSyncCond);
+}
+
+
 static void *
 qemuDomainObjPrivateAlloc(void)
 {
@@ -741,6 +788,7 @@ qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt, void *data)
 virDomainXMLPrivateDataCallbacks virQEMUDriverPrivateDataCallbacks = {
     .alloc = qemuDomainObjPrivateAlloc,
     .free = qemuDomainObjPrivateFree,
+    .diskNew = qemuDomainDiskPrivateNew,
     .parse = qemuDomainObjPrivateXMLParse,
     .format = qemuDomainObjPrivateXMLFormat,
 };
@@ -2809,6 +2857,8 @@ qemuDomainDetermineDiskChain(virQEMUDriverPtr driver,
 bool
 qemuDomainDiskBlockJobIsActive(virDomainDiskDefPtr disk)
 {
+    qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
+
     if (disk->mirror) {
         virReportError(VIR_ERR_BLOCK_COPY_ACTIVE,
                        _("disk '%s' already in active block job"),
@@ -2817,7 +2867,7 @@ qemuDomainDiskBlockJobIsActive(virDomainDiskDefPtr disk)
         return true;
     }
 
-    if (disk->blockjob) {
+    if (diskPriv->blockjob) {
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
                        _("disk '%s' already in active block job"),
                        disk->dst);
@@ -2843,12 +2893,13 @@ qemuDomainHasBlockjob(virDomainObjPtr vm,
 {
     size_t i;
     for (i = 0; i < vm->def->ndisks; i++) {
-        if (!copy_only &&
-            vm->def->disks[i]->blockjob)
+        virDomainDiskDefPtr disk = vm->def->disks[i];
+        qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
+
+        if (!copy_only && diskPriv->blockjob)
             return true;
 
-        if (vm->def->disks[i]->mirror &&
-            vm->def->disks[i]->mirrorJob == VIR_DOMAIN_BLOCK_JOB_TYPE_COPY)
+        if (disk->mirror && disk->mirrorJob == VIR_DOMAIN_BLOCK_JOB_TYPE_COPY)
             return true;
     }
 
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 7f2e4b5..53df1d3 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -34,6 +34,7 @@
 # include "qemu_conf.h"
 # include "qemu_capabilities.h"
 # include "virchrdev.h"
+# include "virobject.h"
 
 # define QEMU_DOMAIN_FORMAT_LIVE_FLAGS      \
     (VIR_DOMAIN_XML_SECURE |                \
@@ -199,6 +200,26 @@ struct _qemuDomainObjPrivate {
     virBitmapPtr autoCpuset;
 };
 
+# define QEMU_DOMAIN_DISK_PRIVATE(disk)	\
+    ((qemuDomainDiskPrivatePtr) (disk)->privateData)
+
+typedef struct _qemuDomainDiskPrivate qemuDomainDiskPrivate;
+typedef qemuDomainDiskPrivate *qemuDomainDiskPrivatePtr;
+struct _qemuDomainDiskPrivate {
+    virObject parent;
+
+    /* 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 */
+    virCond blockJobSyncCond;
+    int blockJobType;   /* type of the block job from the event */
+    int blockJobStatus; /* status of the finished block job */
+    bool blockJobSync; /* the block job needs synchronized termination */
+};
+
 typedef enum {
     QEMU_PROCESS_EVENT_WATCHDOG = 0,
     QEMU_PROCESS_EVENT_GUESTPANIC,
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index c54199c..9344533 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -14315,9 +14315,10 @@ qemuDomainSnapshotPrepare(virConnectPtr conn,
     for (i = 0; i < def->ndisks; i++) {
         virDomainSnapshotDiskDefPtr disk = &def->disks[i];
         virDomainDiskDefPtr dom_disk = vm->def->disks[i];
+        qemuDomainDiskPrivatePtr dom_diskPriv = QEMU_DOMAIN_DISK_PRIVATE(dom_disk);
 
         if (disk->snapshot != VIR_DOMAIN_SNAPSHOT_LOCATION_NONE &&
-            dom_disk->blockjob) {
+            dom_diskPriv->blockjob) {
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                            _("disk '%s' has an active block job"),
                            disk->name);
@@ -16637,7 +16638,7 @@ qemuDomainBlockPullCommon(virQEMUDriverPtr driver,
     if (ret < 0)
         goto endjob;
 
-    disk->blockjob = true;
+    QEMU_DOMAIN_DISK_PRIVATE(disk)->blockjob = true;
 
  endjob:
     qemuDomainObjEndJob(driver, vm);
@@ -16765,7 +16766,7 @@ qemuDomainBlockJobAbort(virDomainPtr dom,
     }
 
  endjob:
-    if (disk && disk->blockJobSync)
+    if (disk && QEMU_DOMAIN_DISK_PRIVATE(disk)->blockJobSync)
         qemuBlockJobSyncEnd(driver, vm, disk, NULL);
     qemuDomainObjEndJob(driver, vm);
 
@@ -17098,7 +17099,7 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm,
     disk->mirror = mirror;
     mirror = NULL;
     disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_COPY;
-    disk->blockjob = true;
+    QEMU_DOMAIN_DISK_PRIVATE(disk)->blockjob = true;
 
     if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0)
         VIR_WARN("Unable to save status on vm %s after state change",
@@ -17491,7 +17492,7 @@ qemuDomainBlockCommit(virDomainPtr dom,
     }
 
     if (ret == 0)
-        disk->blockjob = true;
+        QEMU_DOMAIN_DISK_PRIVATE(disk)->blockjob = true;
 
     if (mirror) {
         if (ret == 0) {
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 8f2189b..7472b09 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1743,6 +1743,7 @@ qemuMigrationCheckDriveMirror(virQEMUDriverPtr driver,
 
     for (i = 0; i < vm->def->ndisks; i++) {
         virDomainDiskDefPtr disk = vm->def->disks[i];
+        qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
 
         /* skip shared, RO and source-less disks */
         if (disk->src->shared || disk->src->readonly ||
@@ -1750,7 +1751,7 @@ qemuMigrationCheckDriveMirror(virQEMUDriverPtr driver,
             continue;
 
         /* skip disks that didn't start mirroring */
-        if (!disk->blockJobSync)
+        if (!diskPriv->blockJobSync)
             continue;
 
         /* process any pending event */
@@ -1871,6 +1872,7 @@ qemuMigrationCancelDriveMirror(virQEMUDriverPtr driver,
 
     for (i = 0; i < vm->def->ndisks; i++) {
         virDomainDiskDefPtr disk = vm->def->disks[i];
+        qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
 
         /* skip shared, RO and source-less disks */
         if (disk->src->shared || disk->src->readonly ||
@@ -1878,7 +1880,7 @@ qemuMigrationCancelDriveMirror(virQEMUDriverPtr driver,
             continue;
 
         /* skip disks that didn't start mirroring */
-        if (!disk->blockJobSync)
+        if (!diskPriv->blockJobSync)
             continue;
 
         if (qemuMigrationCancelOneDriveMirror(driver, vm, disk) < 0)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 56719eb..2b3d9b5 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -1001,6 +1001,7 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
     virQEMUDriverPtr driver = opaque;
     struct qemuProcessEvent *processEvent = NULL;
     virDomainDiskDefPtr disk;
+    qemuDomainDiskPrivatePtr diskPriv;
     char *data = NULL;
 
     virObjectLock(vm);
@@ -1010,12 +1011,13 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
 
     if (!(disk = qemuProcessFindDomainDiskByAlias(vm, diskAlias)))
         goto error;
+    diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
 
-    if (disk->blockJobSync) {
-        disk->blockJobType = type;
-        disk->blockJobStatus = status;
+    if (diskPriv->blockJobSync) {
+        diskPriv->blockJobType = type;
+        diskPriv->blockJobStatus = status;
         /* We have an SYNC API waiting for this event, dispatch it back */
-        virCondSignal(&disk->blockJobSyncCond);
+        virCondSignal(&diskPriv->blockJobSyncCond);
     } else {
         /* there is no waiting SYNC API, dispatch the update to a thread */
         if (VIR_ALLOC(processEvent) < 0)
@@ -5063,9 +5065,10 @@ void qemuProcessStop(virQEMUDriverPtr driver,
 
     /* Wake up anything waiting on synchronous block jobs */
     for (i = 0; i < vm->def->ndisks; i++) {
-        virDomainDiskDefPtr disk = vm->def->disks[i];
-        if (disk->blockJobSync && disk->blockJobStatus == -1)
-            virCondSignal(&disk->blockJobSyncCond);
+        qemuDomainDiskPrivatePtr diskPriv =
+            QEMU_DOMAIN_DISK_PRIVATE(vm->def->disks[i]);
+        if (diskPriv->blockJobSync && diskPriv->blockJobStatus == -1)
+            virCondSignal(&diskPriv->blockJobSyncCond);
     }
 
     if ((logfile = qemuDomainCreateLog(driver, vm, true)) < 0) {
-- 
2.4.0




More information about the libvir-list mailing list