[GSoC][PATCH v3 2/8] qemu_domain: Added `qemuDomainJobInfo` to domainJob's `privateData`

Prathamesh Chavan pc44800 at gmail.com
Sun Aug 23 20:38:02 UTC 2020


As `qemuDomainJobInfo` had attributes specific to qemu hypervisor's
jobs, we moved the attribute `current` and `completed` from
`qemuDomainJobObj` to its `privateData` structure.

In this process, two callback functions: `setJobInfoOperation`
and `currentJobInfoInit` were introduced to qemuDomainJob's
callback structure.

Signed-off-by: Prathamesh Chavan <pc44800 at gmail.com>
---
 src/qemu/qemu_backup.c           | 22 ++++++-----
 src/qemu/qemu_domain.c           | 29 ++++++++++++++-
 src/qemu/qemu_domain.h           | 50 +++++++++++++++++++++++++
 src/qemu/qemu_domainjob.c        |  6 +--
 src/qemu/qemu_domainjob.h        | 64 +++-----------------------------
 src/qemu/qemu_driver.c           | 49 +++++++++++++++---------
 src/qemu/qemu_migration.c        | 62 +++++++++++++++++--------------
 src/qemu/qemu_migration_cookie.c |  8 ++--
 src/qemu/qemu_process.c          | 32 +++++++++-------
 9 files changed, 185 insertions(+), 137 deletions(-)

diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c
index a402730d38..1822c6f267 100644
--- a/src/qemu/qemu_backup.c
+++ b/src/qemu/qemu_backup.c
@@ -529,20 +529,21 @@ qemuBackupJobTerminate(virDomainObjPtr vm,
 
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
     size_t i;
 
-    qemuDomainJobInfoUpdateTime(priv->job.current);
+    qemuDomainJobInfoUpdateTime(jobPriv->current);
 
-    g_clear_pointer(&priv->job.completed, qemuDomainJobInfoFree);
-    priv->job.completed = qemuDomainJobInfoCopy(priv->job.current);
+    g_clear_pointer(&jobPriv->completed, qemuDomainJobInfoFree);
+    jobPriv->completed = qemuDomainJobInfoCopy(jobPriv->current);
 
-    priv->job.completed->stats.backup.total = priv->backup->push_total;
-    priv->job.completed->stats.backup.transferred = priv->backup->push_transferred;
-    priv->job.completed->stats.backup.tmp_used = priv->backup->pull_tmp_used;
-    priv->job.completed->stats.backup.tmp_total = priv->backup->pull_tmp_total;
+    jobPriv->completed->stats.backup.total = priv->backup->push_total;
+    jobPriv->completed->stats.backup.transferred = priv->backup->push_transferred;
+    jobPriv->completed->stats.backup.tmp_used = priv->backup->pull_tmp_used;
+    jobPriv->completed->stats.backup.tmp_total = priv->backup->pull_tmp_total;
 
-    priv->job.completed->status = jobstatus;
-    priv->job.completed->errmsg = g_strdup(priv->backup->errmsg);
+    jobPriv->completed->status = jobstatus;
+    jobPriv->completed->errmsg = g_strdup(priv->backup->errmsg);
 
     qemuDomainEventEmitJobCompleted(priv->driver, vm);
 
@@ -694,6 +695,7 @@ qemuBackupBegin(virDomainObjPtr vm,
                 unsigned int flags)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
     g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(priv->driver);
     g_autoptr(virDomainBackupDef) def = NULL;
     g_autofree char *suffix = NULL;
@@ -745,7 +747,7 @@ qemuBackupBegin(virDomainObjPtr vm,
     qemuDomainObjSetAsyncJobMask(vm, (QEMU_JOB_DEFAULT_MASK |
                                       JOB_MASK(QEMU_JOB_SUSPEND) |
                                       JOB_MASK(QEMU_JOB_MODIFY)));
-    priv->job.current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_BACKUP;
+    jobPriv->current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_BACKUP;
 
     if (!virDomainObjIsActive(vm)) {
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index ae8ce37be2..ea740bcf60 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -542,6 +542,8 @@ qemuJobFreePrivate(void *opaque)
         return;
 
     qemuMigrationParamsFree(priv->migParams);
+    g_clear_pointer(&priv->current, qemuDomainJobInfoFree);
+    g_clear_pointer(&priv->completed, qemuDomainJobInfoFree);
     VIR_FREE(priv);
 }
 
@@ -555,6 +557,7 @@ qemuJobResetPrivate(void *opaque)
     priv->spiceMigrated = false;
     priv->dumpCompleted = false;
     qemuMigrationParamsFree(priv->migParams);
+    g_clear_pointer(&priv->current, qemuDomainJobInfoFree);
     priv->migParams = NULL;
 }
 
@@ -629,20 +632,40 @@ qemuDomainFormatJobPrivate(virBufferPtr buf,
     return 0;
 }
 
+static void
+qemuDomainCurrentJobInfoInit(qemuDomainJobObjPtr job,
+                             unsigned long long now)
+{
+    qemuDomainJobPrivatePtr priv = job->privateData;
+    priv->current = g_new0(qemuDomainJobInfo, 1);
+    priv->current->status = QEMU_DOMAIN_JOB_STATUS_ACTIVE;
+    priv->current->started = now;
+
+}
+
+static void
+qemuDomainJobInfoSetOperation(qemuDomainJobObjPtr job,
+                              virDomainJobOperation operation)
+{
+    qemuDomainJobPrivatePtr priv = job->privateData;
+    priv->current->operation = operation;
+}
+
 void
 qemuDomainEventEmitJobCompleted(virQEMUDriverPtr driver,
                                 virDomainObjPtr vm)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
     virObjectEventPtr event;
     virTypedParameterPtr params = NULL;
     int nparams = 0;
     int type;
 
-    if (!priv->job.completed)
+    if (!jobPriv->completed)
         return;
 
-    if (qemuDomainJobInfoToParams(priv->job.completed, &type,
+    if (qemuDomainJobInfoToParams(jobPriv->completed, &type,
                                   &params, &nparams) < 0) {
         VIR_WARN("Could not get stats for completed job; domain %s",
                  vm->def->name);
@@ -759,6 +782,8 @@ static qemuDomainObjPrivateJobCallbacks qemuPrivateJobCallbacks = {
     .resetJobPrivate = qemuJobResetPrivate,
     .formatJob = qemuDomainFormatJobPrivate,
     .parseJob = qemuDomainParseJobPrivate,
+    .setJobInfoOperation = qemuDomainJobInfoSetOperation,
+    .currentJobInfoInit = qemuDomainCurrentJobInfoInit,
 };
 
 /**
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 3f5f73bbb6..1e180bf684 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -483,6 +483,52 @@ struct _qemuDomainXmlNsDef {
     char **capsdel;
 };
 
+typedef struct _qemuDomainMirrorStats qemuDomainMirrorStats;
+typedef qemuDomainMirrorStats *qemuDomainMirrorStatsPtr;
+struct _qemuDomainMirrorStats {
+    unsigned long long transferred;
+    unsigned long long total;
+};
+
+typedef struct _qemuDomainBackupStats qemuDomainBackupStats;
+struct _qemuDomainBackupStats {
+    unsigned long long transferred;
+    unsigned long long total;
+    unsigned long long tmp_used;
+    unsigned long long tmp_total;
+};
+
+typedef struct _qemuDomainJobInfo qemuDomainJobInfo;
+typedef qemuDomainJobInfo *qemuDomainJobInfoPtr;
+struct _qemuDomainJobInfo {
+    qemuDomainJobStatus status;
+    virDomainJobOperation operation;
+    unsigned long long started; /* When the async job started */
+    unsigned long long stopped; /* When the domain's CPUs were stopped */
+    unsigned long long sent; /* When the source sent status info to the
+                                destination (only for migrations). */
+    unsigned long long received; /* When the destination host received status
+                                    info from the source (migrations only). */
+    /* Computed values */
+    unsigned long long timeElapsed;
+    long long timeDelta; /* delta = received - sent, i.e., the difference
+                            between the source and the destination time plus
+                            the time between the end of Perform phase on the
+                            source and the beginning of Finish phase on the
+                            destination. */
+    bool timeDeltaSet;
+    /* Raw values from QEMU */
+    qemuDomainJobStatsType statsType;
+    union {
+        qemuMonitorMigrationStats mig;
+        qemuMonitorDumpStats dump;
+        qemuDomainBackupStats backup;
+    } stats;
+    qemuDomainMirrorStats mirrorStats;
+
+    char *errmsg; /* optional error message for failed completed jobs */
+};
+
 typedef struct _qemuDomainJobPrivate qemuDomainJobPrivate;
 typedef qemuDomainJobPrivate *qemuDomainJobPrivatePtr;
 struct _qemuDomainJobPrivate {
@@ -491,6 +537,8 @@ struct _qemuDomainJobPrivate {
     bool spiceMigrated;                 /* spice migration completed */
     bool dumpCompleted;                 /* dump completed */
     qemuMigrationParamsPtr migParams;
+    qemuDomainJobInfoPtr current;       /* async job progress data */
+    qemuDomainJobInfoPtr completed;     /* statistics data of a recently completed job */
 };
 
 
@@ -500,6 +548,8 @@ void qemuDomainEventEmitJobCompleted(virQEMUDriverPtr driver,
 void
 qemuDomainJobInfoFree(qemuDomainJobInfoPtr info);
 
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuDomainJobInfo, qemuDomainJobInfoFree);
+
 qemuDomainJobInfoPtr
 qemuDomainJobInfoCopy(qemuDomainJobInfoPtr info);
 
diff --git a/src/qemu/qemu_domainjob.c b/src/qemu/qemu_domainjob.c
index a8167f25f8..60b834a5cb 100644
--- a/src/qemu/qemu_domainjob.c
+++ b/src/qemu/qemu_domainjob.c
@@ -417,13 +417,11 @@ qemuDomainObjBeginJobInternal(virQEMUDriverPtr driver,
                       qemuDomainAsyncJobTypeToString(asyncJob),
                       obj, obj->def->name);
             qemuDomainObjResetAsyncJob(&priv->job);
-            priv->job.current = g_new0(qemuDomainJobInfo, 1);
-            priv->job.current->status = QEMU_DOMAIN_JOB_STATUS_ACTIVE;
+            priv->job.cb->currentJobInfoInit(&priv->job, now);
             priv->job.asyncJob = asyncJob;
             priv->job.asyncOwner = virThreadSelfID();
             priv->job.asyncOwnerAPI = virThreadJobGet();
             priv->job.asyncStarted = now;
-            priv->job.current->started = now;
         }
     }
 
@@ -589,7 +587,7 @@ int qemuDomainObjBeginAsyncJob(virQEMUDriverPtr driver,
         return -1;
 
     priv = obj->privateData;
-    priv->job.current->operation = operation;
+    priv->job.cb->setJobInfoOperation(&priv->job, operation);
     priv->job.apiFlags = apiFlags;
     return 0;
 }
diff --git a/src/qemu/qemu_domainjob.h b/src/qemu/qemu_domainjob.h
index 84b60a466a..c09cfb1a16 100644
--- a/src/qemu/qemu_domainjob.h
+++ b/src/qemu/qemu_domainjob.h
@@ -19,7 +19,6 @@
 #pragma once
 
 #include <glib-object.h>
-#include "qemu_monitor.h"
 
 #define JOB_MASK(job)                  (job == 0 ? 0 : 1 << (job - 1))
 #define QEMU_JOB_DEFAULT_MASK \
@@ -99,61 +98,6 @@ typedef enum {
     QEMU_DOMAIN_JOB_STATS_TYPE_BACKUP,
 } qemuDomainJobStatsType;
 
-
-typedef struct _qemuDomainMirrorStats qemuDomainMirrorStats;
-typedef qemuDomainMirrorStats *qemuDomainMirrorStatsPtr;
-struct _qemuDomainMirrorStats {
-    unsigned long long transferred;
-    unsigned long long total;
-};
-
-typedef struct _qemuDomainBackupStats qemuDomainBackupStats;
-struct _qemuDomainBackupStats {
-    unsigned long long transferred;
-    unsigned long long total;
-    unsigned long long tmp_used;
-    unsigned long long tmp_total;
-};
-
-typedef struct _qemuDomainJobInfo qemuDomainJobInfo;
-typedef qemuDomainJobInfo *qemuDomainJobInfoPtr;
-struct _qemuDomainJobInfo {
-    qemuDomainJobStatus status;
-    virDomainJobOperation operation;
-    unsigned long long started; /* When the async job started */
-    unsigned long long stopped; /* When the domain's CPUs were stopped */
-    unsigned long long sent; /* When the source sent status info to the
-                                destination (only for migrations). */
-    unsigned long long received; /* When the destination host received status
-                                    info from the source (migrations only). */
-    /* Computed values */
-    unsigned long long timeElapsed;
-    long long timeDelta; /* delta = received - sent, i.e., the difference
-                            between the source and the destination time plus
-                            the time between the end of Perform phase on the
-                            source and the beginning of Finish phase on the
-                            destination. */
-    bool timeDeltaSet;
-    /* Raw values from QEMU */
-    qemuDomainJobStatsType statsType;
-    union {
-        qemuMonitorMigrationStats mig;
-        qemuMonitorDumpStats dump;
-        qemuDomainBackupStats backup;
-    } stats;
-    qemuDomainMirrorStats mirrorStats;
-
-    char *errmsg; /* optional error message for failed completed jobs */
-};
-
-void
-qemuDomainJobInfoFree(qemuDomainJobInfoPtr info);
-
-G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuDomainJobInfo, qemuDomainJobInfoFree);
-
-qemuDomainJobInfoPtr
-qemuDomainJobInfoCopy(qemuDomainJobInfoPtr info);
-
 typedef struct _qemuDomainJobObj qemuDomainJobObj;
 typedef qemuDomainJobObj *qemuDomainJobObjPtr;
 
@@ -166,6 +110,10 @@ typedef int (*qemuDomainObjPrivateJobFormat)(virBufferPtr,
 typedef int (*qemuDomainObjPrivateJobParse)(xmlXPathContextPtr,
                                             qemuDomainJobObjPtr,
                                             virDomainObjPtr);
+typedef void (*qemuDomainObjJobInfoSetOperation)(qemuDomainJobObjPtr,
+                                                 virDomainJobOperation);
+typedef void (*qemuDomainObjCurrentJobInfoInit)(qemuDomainJobObjPtr,
+                                                unsigned long long);
 
 typedef struct _qemuDomainObjPrivateJobCallbacks qemuDomainObjPrivateJobCallbacks;
 typedef qemuDomainObjPrivateJobCallbacks *qemuDomainObjPrivateJobCallbacksPtr;
@@ -175,6 +123,8 @@ struct _qemuDomainObjPrivateJobCallbacks {
    qemuDomainObjPrivateJobReset resetJobPrivate;
    qemuDomainObjPrivateJobFormat formatJob;
    qemuDomainObjPrivateJobParse parseJob;
+   qemuDomainObjJobInfoSetOperation setJobInfoOperation;
+   qemuDomainObjCurrentJobInfoInit currentJobInfoInit;
 };
 
 struct _qemuDomainJobObj {
@@ -200,8 +150,6 @@ struct _qemuDomainJobObj {
     unsigned long long asyncStarted;    /* When the current async job started */
     int phase;                          /* Job phase (mainly for migrations) */
     unsigned long long mask;            /* Jobs allowed during async job */
-    qemuDomainJobInfoPtr current;       /* async job progress data */
-    qemuDomainJobInfoPtr completed;     /* statistics data of a recently completed job */
     bool abortJob;                      /* abort of the job requested */
     char *error;                        /* job event completion error */
     unsigned long apiFlags; /* flags passed to the API which started the async job */
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 1b2ff1b3da..77d9a841ed 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -2724,6 +2724,7 @@ qemuDomainGetControlInfo(virDomainPtr dom,
 {
     virDomainObjPtr vm;
     qemuDomainObjPrivatePtr priv;
+    qemuDomainJobPrivatePtr jobPriv;
     int ret = -1;
 
     virCheckFlags(0, -1);
@@ -2738,6 +2739,7 @@ qemuDomainGetControlInfo(virDomainPtr dom,
         goto cleanup;
 
     priv = vm->privateData;
+    jobPriv = priv->job.privateData;
 
     memset(info, 0, sizeof(*info));
 
@@ -2747,9 +2749,9 @@ qemuDomainGetControlInfo(virDomainPtr dom,
     } else if (priv->job.active) {
         if (virTimeMillisNow(&info->stateTime) < 0)
             goto cleanup;
-        if (priv->job.current) {
+        if (jobPriv->current) {
             info->state = VIR_DOMAIN_CONTROL_JOB;
-            info->stateTime -= priv->job.current->started;
+            info->stateTime -= jobPriv->current->started;
         } else {
             if (priv->monStart > 0) {
                 info->state = VIR_DOMAIN_CONTROL_OCCUPIED;
@@ -3314,6 +3316,7 @@ qemuDomainSaveInternal(virQEMUDriverPtr driver,
     int ret = -1;
     virObjectEventPtr event = NULL;
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
     virQEMUSaveDataPtr data = NULL;
     g_autoptr(qemuDomainSaveCookie) cookie = NULL;
 
@@ -3330,7 +3333,7 @@ qemuDomainSaveInternal(virQEMUDriverPtr driver,
         goto endjob;
     }
 
-    priv->job.current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP;
+    jobPriv->current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP;
 
     /* Pause */
     if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
@@ -3715,7 +3718,7 @@ qemuDumpWaitForCompletion(virDomainObjPtr vm)
             return -1;
     }
 
-    if (priv->job.current->stats.dump.status == QEMU_MONITOR_DUMP_STATUS_FAILED) {
+    if (jobPriv->current->stats.dump.status == QEMU_MONITOR_DUMP_STATUS_FAILED) {
         if (priv->job.error)
             virReportError(VIR_ERR_OPERATION_FAILED,
                            _("memory-only dump failed: %s"),
@@ -3726,7 +3729,7 @@ qemuDumpWaitForCompletion(virDomainObjPtr vm)
 
         return -1;
     }
-    qemuDomainJobInfoUpdateTime(priv->job.current);
+    qemuDomainJobInfoUpdateTime(jobPriv->current);
 
     return 0;
 }
@@ -3740,6 +3743,7 @@ qemuDumpToFd(virQEMUDriverPtr driver,
              const char *dumpformat)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
     bool detach = false;
     int ret = -1;
 
@@ -3755,9 +3759,9 @@ qemuDumpToFd(virQEMUDriverPtr driver,
         return -1;
 
     if (detach)
-        priv->job.current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_MEMDUMP;
+        jobPriv->current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_MEMDUMP;
     else
-        g_clear_pointer(&priv->job.current, qemuDomainJobInfoFree);
+        g_clear_pointer(&jobPriv->current, qemuDomainJobInfoFree);
 
     if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
         return -1;
@@ -3895,6 +3899,7 @@ qemuDomainCoreDumpWithFormat(virDomainPtr dom,
     virQEMUDriverPtr driver = dom->conn->privateData;
     virDomainObjPtr vm;
     qemuDomainObjPrivatePtr priv = NULL;
+    qemuDomainJobPrivatePtr jobPriv;
     bool resume = false, paused = false;
     int ret = -1;
     virObjectEventPtr event = NULL;
@@ -3919,7 +3924,8 @@ qemuDomainCoreDumpWithFormat(virDomainPtr dom,
         goto endjob;
 
     priv = vm->privateData;
-    priv->job.current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP;
+    jobPriv = priv->job.privateData;
+    jobPriv->current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP;
 
     /* Migrate will always stop the VM, so the resume condition is
        independent of whether the stop command is issued.  */
@@ -7480,6 +7486,7 @@ qemuDomainObjStart(virConnectPtr conn,
     bool force_boot = (flags & VIR_DOMAIN_START_FORCE_BOOT) != 0;
     unsigned int start_flags = VIR_QEMU_PROCESS_START_COLD;
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
 
     start_flags |= start_paused ? VIR_QEMU_PROCESS_START_PAUSED : 0;
     start_flags |= autodestroy ? VIR_QEMU_PROCESS_START_AUTODESTROY : 0;
@@ -7503,8 +7510,8 @@ qemuDomainObjStart(virConnectPtr conn,
             }
             vm->hasManagedSave = false;
         } else {
-            virDomainJobOperation op = priv->job.current->operation;
-            priv->job.current->operation = VIR_DOMAIN_JOB_OPERATION_RESTORE;
+            virDomainJobOperation op = jobPriv->current->operation;
+            jobPriv->current->operation = VIR_DOMAIN_JOB_OPERATION_RESTORE;
 
             ret = qemuDomainObjRestore(conn, driver, vm, managed_save,
                                        start_paused, bypass_cache, asyncJob);
@@ -7522,7 +7529,7 @@ qemuDomainObjStart(virConnectPtr conn,
                 return ret;
             } else {
                 VIR_WARN("Ignoring incomplete managed state %s", managed_save);
-                priv->job.current->operation = op;
+                jobPriv->current->operation = op;
                 vm->hasManagedSave = false;
             }
         }
@@ -13576,13 +13583,14 @@ qemuDomainGetJobStatsInternal(virQEMUDriverPtr driver,
                               qemuDomainJobInfoPtr *jobInfo)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
     int ret = -1;
 
     *jobInfo = NULL;
 
     if (completed) {
-        if (priv->job.completed && !priv->job.current)
-            *jobInfo = qemuDomainJobInfoCopy(priv->job.completed);
+        if (jobPriv->completed && !jobPriv->current)
+            *jobInfo = qemuDomainJobInfoCopy(jobPriv->completed);
 
         return 0;
     }
@@ -13600,11 +13608,11 @@ qemuDomainGetJobStatsInternal(virQEMUDriverPtr driver,
     if (virDomainObjCheckActive(vm) < 0)
         goto cleanup;
 
-    if (!priv->job.current) {
+    if (!jobPriv->current) {
         ret = 0;
         goto cleanup;
     }
-    *jobInfo = qemuDomainJobInfoCopy(priv->job.current);
+    *jobInfo = qemuDomainJobInfoCopy(jobPriv->current);
 
     switch ((*jobInfo)->statsType) {
     case QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION:
@@ -13679,6 +13687,7 @@ qemuDomainGetJobStats(virDomainPtr dom,
     virQEMUDriverPtr driver = dom->conn->privateData;
     virDomainObjPtr vm;
     qemuDomainObjPrivatePtr priv;
+    qemuDomainJobPrivatePtr jobPriv;
     g_autoptr(qemuDomainJobInfo) jobInfo = NULL;
     bool completed = !!(flags & VIR_DOMAIN_JOB_STATS_COMPLETED);
     int ret = -1;
@@ -13693,6 +13702,7 @@ qemuDomainGetJobStats(virDomainPtr dom,
         goto cleanup;
 
     priv = vm->privateData;
+    jobPriv = priv->job.privateData;
     if (qemuDomainGetJobStatsInternal(driver, vm, completed, &jobInfo) < 0)
         goto cleanup;
 
@@ -13708,7 +13718,7 @@ qemuDomainGetJobStats(virDomainPtr dom,
     ret = qemuDomainJobInfoToParams(jobInfo, type, params, nparams);
 
     if (completed && ret == 0 && !(flags & VIR_DOMAIN_JOB_STATS_KEEP_COMPLETED))
-        g_clear_pointer(&priv->job.completed, qemuDomainJobInfoFree);
+        g_clear_pointer(&jobPriv->completed, qemuDomainJobInfoFree);
 
  cleanup:
     virDomainObjEndAPI(&vm);
@@ -13740,6 +13750,7 @@ static int qemuDomainAbortJob(virDomainPtr dom)
     virDomainObjPtr vm;
     int ret = -1;
     qemuDomainObjPrivatePtr priv;
+    qemuDomainJobPrivatePtr jobPriv;
     int reason;
 
     if (!(vm = qemuDomainObjFromDomain(dom)))
@@ -13755,6 +13766,7 @@ static int qemuDomainAbortJob(virDomainPtr dom)
         goto endjob;
 
     priv = vm->privateData;
+    jobPriv = priv->job.privateData;
 
     switch (priv->job.asyncJob) {
     case QEMU_ASYNC_JOB_NONE:
@@ -13775,7 +13787,7 @@ static int qemuDomainAbortJob(virDomainPtr dom)
         break;
 
     case QEMU_ASYNC_JOB_MIGRATION_OUT:
-        if ((priv->job.current->status == QEMU_DOMAIN_JOB_STATUS_POSTCOPY ||
+        if ((jobPriv->current->status == QEMU_DOMAIN_JOB_STATUS_POSTCOPY ||
              (virDomainObjGetState(vm, &reason) == VIR_DOMAIN_PAUSED &&
               reason == VIR_DOMAIN_PAUSED_POSTCOPY))) {
             virReportError(VIR_ERR_OPERATION_INVALID, "%s",
@@ -15443,6 +15455,7 @@ qemuDomainSnapshotCreateActiveExternal(virQEMUDriverPtr driver,
     bool resume = false;
     int ret = -1;
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
     g_autofree char *xml = NULL;
     virDomainSnapshotDefPtr snapdef = virDomainSnapshotObjGetDef(snap);
     bool memory = snapdef->memory == VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL;
@@ -15520,7 +15533,7 @@ qemuDomainSnapshotCreateActiveExternal(virQEMUDriverPtr driver,
         if (!qemuMigrationSrcIsAllowed(driver, vm, false, 0))
             goto cleanup;
 
-        priv->job.current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP;
+        jobPriv->current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP;
 
         /* allow the migration job to be cancelled or the domain to be paused */
         qemuDomainObjSetAsyncJobMask(vm, (QEMU_JOB_DEFAULT_MASK |
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 142faa2cf9..9b481c3443 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1008,6 +1008,7 @@ qemuMigrationSrcNBDStorageCopy(virQEMUDriverPtr driver,
                                unsigned int flags)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
     int port;
     size_t i;
     unsigned long long mirror_speed = speed;
@@ -1052,7 +1053,7 @@ qemuMigrationSrcNBDStorageCopy(virQEMUDriverPtr driver,
             return -1;
 
         if (priv->job.abortJob) {
-            priv->job.current->status = QEMU_DOMAIN_JOB_STATUS_CANCELED;
+            jobPriv->current->status = QEMU_DOMAIN_JOB_STATUS_CANCELED;
             virReportError(VIR_ERR_OPERATION_ABORTED, _("%s: %s"),
                            qemuDomainAsyncJobTypeToString(priv->job.asyncJob),
                            _("canceled by client"));
@@ -1070,7 +1071,7 @@ qemuMigrationSrcNBDStorageCopy(virQEMUDriverPtr driver,
     }
 
     qemuMigrationSrcFetchMirrorStats(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT,
-                                     priv->job.current);
+                                     jobPriv->current);
 
     /* Okay, all disks are ready. Modify migrate_flags */
     *migrate_flags &= ~(QEMU_MONITOR_MIGRATE_NON_SHARED_DISK |
@@ -1550,7 +1551,8 @@ qemuMigrationJobCheckStatus(virQEMUDriverPtr driver,
                             qemuDomainAsyncJob asyncJob)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
-    qemuDomainJobInfoPtr jobInfo = priv->job.current;
+    qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
+    qemuDomainJobInfoPtr jobInfo = jobPriv->current;
     char *error = NULL;
     bool events = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT);
     int ret = -1;
@@ -1620,7 +1622,8 @@ qemuMigrationAnyCompleted(virQEMUDriverPtr driver,
                           unsigned int flags)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
-    qemuDomainJobInfoPtr jobInfo = priv->job.current;
+    qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
+    qemuDomainJobInfoPtr jobInfo = jobPriv->current;
     int pauseReason;
 
     if (qemuMigrationJobCheckStatus(driver, vm, asyncJob) < 0)
@@ -1711,7 +1714,8 @@ qemuMigrationSrcWaitForCompletion(virQEMUDriverPtr driver,
                                   unsigned int flags)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
-    qemuDomainJobInfoPtr jobInfo = priv->job.current;
+    qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
+    qemuDomainJobInfoPtr jobInfo = jobPriv->current;
     bool events = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT);
     int rv;
 
@@ -1743,9 +1747,9 @@ qemuMigrationSrcWaitForCompletion(virQEMUDriverPtr driver,
 
     qemuDomainJobInfoUpdateTime(jobInfo);
     qemuDomainJobInfoUpdateDowntime(jobInfo);
-    g_clear_pointer(&priv->job.completed, qemuDomainJobInfoFree);
-    priv->job.completed = qemuDomainJobInfoCopy(jobInfo);
-    priv->job.completed->status = QEMU_DOMAIN_JOB_STATUS_COMPLETED;
+    g_clear_pointer(&jobPriv->completed, qemuDomainJobInfoFree);
+    jobPriv->completed = qemuDomainJobInfoCopy(jobInfo);
+    jobPriv->completed->status = QEMU_DOMAIN_JOB_STATUS_COMPLETED;
 
     if (asyncJob != QEMU_ASYNC_JOB_MIGRATION_OUT &&
         jobInfo->status == QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED)
@@ -3018,16 +3022,16 @@ qemuMigrationSrcConfirmPhase(virQEMUDriverPtr driver,
         return -1;
 
     if (retcode == 0)
-        jobInfo = priv->job.completed;
+        jobInfo = jobPriv->completed;
     else
-        g_clear_pointer(&priv->job.completed, qemuDomainJobInfoFree);
+        g_clear_pointer(&jobPriv->completed, qemuDomainJobInfoFree);
 
     /* Update times with the values sent by the destination daemon */
     if (mig->jobInfo && jobInfo) {
         int reason;
 
         /* We need to refresh migration statistics after a completed post-copy
-         * migration since priv->job.completed contains obsolete data from the
+         * migration since jobPriv->completed contains obsolete data from the
          * time we switched to post-copy mode.
          */
         if (virDomainObjGetState(vm, &reason) == VIR_DOMAIN_PAUSED &&
@@ -3479,6 +3483,7 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver,
     int ret = -1;
     unsigned int migrate_flags = QEMU_MONITOR_MIGRATE_BACKGROUND;
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
     g_autoptr(qemuMigrationCookie) mig = NULL;
     g_autofree char *tlsAlias = NULL;
     qemuMigrationIOThreadPtr iothread = NULL;
@@ -3636,7 +3641,7 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver,
         /* explicitly do this *after* we entered the monitor,
          * as this is a critical section so we are guaranteed
          * priv->job.abortJob will not change */
-        priv->job.current->status = QEMU_DOMAIN_JOB_STATUS_CANCELED;
+        jobPriv->current->status = QEMU_DOMAIN_JOB_STATUS_CANCELED;
         virReportError(VIR_ERR_OPERATION_ABORTED, _("%s: %s"),
                        qemuDomainAsyncJobTypeToString(priv->job.asyncJob),
                        _("canceled by client"));
@@ -3741,7 +3746,7 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver,
      * resume it now once we finished all block jobs and wait for the real
      * end of the migration.
      */
-    if (priv->job.current->status == QEMU_DOMAIN_JOB_STATUS_PAUSED) {
+    if (jobPriv->current->status == QEMU_DOMAIN_JOB_STATUS_PAUSED) {
         if (qemuMigrationSrcContinue(driver, vm,
                                      QEMU_MONITOR_MIGRATION_STATUS_PRE_SWITCHOVER,
                                      QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
@@ -3769,11 +3774,11 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver,
             goto error;
     }
 
-    if (priv->job.completed) {
-        priv->job.completed->stopped = priv->job.current->stopped;
-        qemuDomainJobInfoUpdateTime(priv->job.completed);
-        qemuDomainJobInfoUpdateDowntime(priv->job.completed);
-        ignore_value(virTimeMillisNow(&priv->job.completed->sent));
+    if (jobPriv->completed) {
+        jobPriv->completed->stopped = jobPriv->current->stopped;
+        qemuDomainJobInfoUpdateTime(jobPriv->completed);
+        qemuDomainJobInfoUpdateDowntime(jobPriv->completed);
+        ignore_value(virTimeMillisNow(&jobPriv->completed->sent));
     }
 
     cookieFlags |= QEMU_MIGRATION_COOKIE_NETWORK |
@@ -3801,7 +3806,7 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver,
 
     if (virDomainObjIsActive(vm)) {
         if (cancel &&
-            priv->job.current->status != QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED &&
+            jobPriv->current->status != QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED &&
             qemuDomainObjEnterMonitorAsync(driver, vm,
                                            QEMU_ASYNC_JOB_MIGRATION_OUT) == 0) {
             qemuMonitorMigrateCancel(priv->mon);
@@ -3814,8 +3819,8 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver,
                                           QEMU_ASYNC_JOB_MIGRATION_OUT,
                                           dconn);
 
-        if (priv->job.current->status != QEMU_DOMAIN_JOB_STATUS_CANCELED)
-            priv->job.current->status = QEMU_DOMAIN_JOB_STATUS_FAILED;
+        if (jobPriv->current->status != QEMU_DOMAIN_JOB_STATUS_CANCELED)
+            jobPriv->current->status = QEMU_DOMAIN_JOB_STATUS_FAILED;
     }
 
     if (iothread)
@@ -5023,7 +5028,7 @@ qemuMigrationDstFinish(virQEMUDriverPtr driver,
                                        : QEMU_MIGRATION_PHASE_FINISH2);
 
     qemuDomainCleanupRemove(vm, qemuMigrationDstPrepareCleanup);
-    g_clear_pointer(&priv->job.completed, qemuDomainJobInfoFree);
+    g_clear_pointer(&jobPriv->completed, qemuDomainJobInfoFree);
 
     cookie_flags = QEMU_MIGRATION_COOKIE_NETWORK |
                    QEMU_MIGRATION_COOKIE_STATS |
@@ -5115,7 +5120,7 @@ qemuMigrationDstFinish(virQEMUDriverPtr driver,
             goto endjob;
     }
 
-    if (priv->job.current->status == QEMU_DOMAIN_JOB_STATUS_POSTCOPY)
+    if (jobPriv->current->status == QEMU_DOMAIN_JOB_STATUS_POSTCOPY)
         inPostCopy = true;
 
     if (!(flags & VIR_MIGRATE_PAUSED)) {
@@ -5229,9 +5234,9 @@ qemuMigrationDstFinish(virQEMUDriverPtr driver,
 
     if (dom) {
         if (jobInfo) {
-            priv->job.completed = g_steal_pointer(&jobInfo);
-            priv->job.completed->status = QEMU_DOMAIN_JOB_STATUS_COMPLETED;
-            priv->job.completed->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION;
+            jobPriv->completed = g_steal_pointer(&jobInfo);
+            jobPriv->completed->status = QEMU_DOMAIN_JOB_STATUS_COMPLETED;
+            jobPriv->completed->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION;
         }
 
         if (qemuMigrationBakeCookie(mig, driver, vm,
@@ -5244,7 +5249,7 @@ qemuMigrationDstFinish(virQEMUDriverPtr driver,
          * is obsolete anyway.
          */
         if (inPostCopy)
-            g_clear_pointer(&priv->job.completed, qemuDomainJobInfoFree);
+            g_clear_pointer(&jobPriv->completed, qemuDomainJobInfoFree);
     }
 
     qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN,
@@ -5473,6 +5478,7 @@ qemuMigrationJobStart(virQEMUDriverPtr driver,
                       unsigned long apiFlags)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
     virDomainJobOperation op;
     unsigned long long mask;
 
@@ -5489,7 +5495,7 @@ qemuMigrationJobStart(virQEMUDriverPtr driver,
     if (qemuDomainObjBeginAsyncJob(driver, vm, job, op, apiFlags) < 0)
         return -1;
 
-    priv->job.current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION;
+    jobPriv->current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION;
 
     qemuDomainObjSetAsyncJobMask(vm, mask);
     return 0;
diff --git a/src/qemu/qemu_migration_cookie.c b/src/qemu/qemu_migration_cookie.c
index 81b557e0a8..a0e8cba8ba 100644
--- a/src/qemu/qemu_migration_cookie.c
+++ b/src/qemu/qemu_migration_cookie.c
@@ -509,12 +509,13 @@ qemuMigrationCookieAddStatistics(qemuMigrationCookiePtr mig,
                                  virDomainObjPtr vm)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
 
-    if (!priv->job.completed)
+    if (!jobPriv->completed)
         return 0;
 
     g_clear_pointer(&mig->jobInfo, qemuDomainJobInfoFree);
-    mig->jobInfo = qemuDomainJobInfoCopy(priv->job.completed);
+    mig->jobInfo = qemuDomainJobInfoCopy(jobPriv->completed);
 
     mig->flags |= QEMU_MIGRATION_COOKIE_STATS;
 
@@ -1465,6 +1466,7 @@ qemuMigrationEatCookie(virQEMUDriverPtr driver,
                        unsigned int flags)
 {
     g_autoptr(qemuMigrationCookie) mig = NULL;
+    qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
 
     /* Parse & validate incoming cookie (if any) */
     if (cookiein && cookieinlen &&
@@ -1513,7 +1515,7 @@ qemuMigrationEatCookie(virQEMUDriverPtr driver,
     }
 
     if (flags & QEMU_MIGRATION_COOKIE_STATS && mig->jobInfo)
-        mig->jobInfo->operation = priv->job.current->operation;
+        mig->jobInfo->operation = jobPriv->current->operation;
 
     return g_steal_pointer(&mig);
 }
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 126fabf5ef..652d217b5c 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -657,6 +657,7 @@ qemuProcessHandleStop(qemuMonitorPtr mon G_GNUC_UNUSED,
     virDomainEventSuspendedDetailType detail;
     g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
 
     virObjectLock(vm);
 
@@ -668,7 +669,7 @@ qemuProcessHandleStop(qemuMonitorPtr mon G_GNUC_UNUSED,
     if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING &&
         !priv->pausedShutdown) {
         if (priv->job.asyncJob == QEMU_ASYNC_JOB_MIGRATION_OUT) {
-            if (priv->job.current->status == QEMU_DOMAIN_JOB_STATUS_POSTCOPY)
+            if (jobPriv->current->status == QEMU_DOMAIN_JOB_STATUS_POSTCOPY)
                 reason = VIR_DOMAIN_PAUSED_POSTCOPY;
             else
                 reason = VIR_DOMAIN_PAUSED_MIGRATION;
@@ -680,8 +681,8 @@ qemuProcessHandleStop(qemuMonitorPtr mon G_GNUC_UNUSED,
                   vm->def->name, virDomainPausedReasonTypeToString(reason),
                   detail);
 
-        if (priv->job.current)
-            ignore_value(virTimeMillisNow(&priv->job.current->stopped));
+        if (jobPriv->current)
+            ignore_value(virTimeMillisNow(&jobPriv->current->stopped));
 
         if (priv->signalStop)
             virDomainObjBroadcast(vm);
@@ -1649,6 +1650,7 @@ qemuProcessHandleMigrationStatus(qemuMonitorPtr mon G_GNUC_UNUSED,
                                  void *opaque)
 {
     qemuDomainObjPrivatePtr priv;
+    qemuDomainJobPrivatePtr jobPriv;
     virQEMUDriverPtr driver = opaque;
     virObjectEventPtr event = NULL;
     g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
@@ -1661,12 +1663,13 @@ qemuProcessHandleMigrationStatus(qemuMonitorPtr mon G_GNUC_UNUSED,
               qemuMonitorMigrationStatusTypeToString(status));
 
     priv = vm->privateData;
+    jobPriv = priv->job.privateData;
     if (priv->job.asyncJob == QEMU_ASYNC_JOB_NONE) {
         VIR_DEBUG("got MIGRATION event without a migration job");
         goto cleanup;
     }
 
-    priv->job.current->stats.mig.status = status;
+    jobPriv->current->stats.mig.status = status;
     virDomainObjBroadcast(vm);
 
     if (status == QEMU_MONITOR_MIGRATION_STATUS_POSTCOPY &&
@@ -1747,13 +1750,13 @@ qemuProcessHandleDumpCompleted(qemuMonitorPtr mon G_GNUC_UNUSED,
         goto cleanup;
     }
     jobPriv->dumpCompleted = true;
-    priv->job.current->stats.dump = *stats;
+    jobPriv->current->stats.dump = *stats;
     priv->job.error = g_strdup(error);
 
     /* Force error if extracting the DUMP_COMPLETED status failed */
     if (!error && status < 0) {
         priv->job.error = g_strdup(virGetLastErrorMessage());
-        priv->job.current->stats.dump.status = QEMU_MONITOR_DUMP_STATUS_FAILED;
+        jobPriv->current->stats.dump.status = QEMU_MONITOR_DUMP_STATUS_FAILED;
     }
 
     virDomainObjBroadcast(vm);
@@ -3267,6 +3270,7 @@ int qemuProcessStopCPUs(virQEMUDriverPtr driver,
 {
     int ret = -1;
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
 
     VIR_FREE(priv->lockState);
 
@@ -3285,8 +3289,8 @@ int qemuProcessStopCPUs(virQEMUDriverPtr driver,
     /* de-activate netdevs after stopping CPUs */
     ignore_value(qemuInterfaceStopDevices(vm->def));
 
-    if (priv->job.current)
-        ignore_value(virTimeMillisNow(&priv->job.current->stopped));
+    if (jobPriv->current)
+        ignore_value(virTimeMillisNow(&jobPriv->current->stopped));
 
     /* The STOP event handler will change the domain state with the reason
      * saved in priv->pausedReason and it will also emit corresponding domain
@@ -3583,6 +3587,7 @@ qemuProcessRecoverJob(virQEMUDriverPtr driver,
                       unsigned int *stopFlags)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    qemuDomainJobPrivatePtr jobPriv = priv->job.privateData;
     virDomainState state;
     int reason;
     unsigned long long now;
@@ -3651,11 +3656,11 @@ qemuProcessRecoverJob(virQEMUDriverPtr driver,
         /* We reset the job parameters for backup so that the job will look
          * active. This is possible because we are able to recover the state
          * of blockjobs and also the backup job allows all sub-job types */
-        priv->job.current = g_new0(qemuDomainJobInfo, 1);
-        priv->job.current->operation = VIR_DOMAIN_JOB_OPERATION_BACKUP;
-        priv->job.current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_BACKUP;
-        priv->job.current->status = QEMU_DOMAIN_JOB_STATUS_ACTIVE;
-        priv->job.current->started = now;
+        jobPriv->current = g_new0(qemuDomainJobInfo, 1);
+        jobPriv->current->operation = VIR_DOMAIN_JOB_OPERATION_BACKUP;
+        jobPriv->current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_BACKUP;
+        jobPriv->current->status = QEMU_DOMAIN_JOB_STATUS_ACTIVE;
+        jobPriv->current->started = now;
         break;
 
     case QEMU_ASYNC_JOB_NONE:
@@ -3760,7 +3765,6 @@ qemuDomainPerfRestart(virDomainObjPtr vm)
     return 0;
 }
 
-
 static void
 qemuProcessReconnectCheckMemAliasOrderMismatch(virDomainObjPtr vm)
 {
-- 
2.25.1




More information about the libvir-list mailing list