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(a)gmail.com>
---
src/qemu/qemu_backup.c | 22 +-
src/qemu/qemu_domain.c | 498 +++++++++++++++++++++++++++++++
src/qemu/qemu_domain.h | 74 +++++
src/qemu/qemu_domainjob.c | 483 +-----------------------------
src/qemu/qemu_domainjob.h | 81 +----
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, 680 insertions(+), 629 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 c440c79e1d..1ae44ae39f 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -75,6 +75,457 @@
VIR_LOG_INIT("qemu.qemu_domain");
+static virDomainJobType
+qemuDomainJobStatusToType(qemuDomainJobStatus status)
+{
+ switch (status) {
+ case QEMU_DOMAIN_JOB_STATUS_NONE:
+ break;
+
+ case QEMU_DOMAIN_JOB_STATUS_ACTIVE:
+ case QEMU_DOMAIN_JOB_STATUS_MIGRATING:
+ case QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED:
+ case QEMU_DOMAIN_JOB_STATUS_POSTCOPY:
+ case QEMU_DOMAIN_JOB_STATUS_PAUSED:
+ return VIR_DOMAIN_JOB_UNBOUNDED;
+
+ case QEMU_DOMAIN_JOB_STATUS_COMPLETED:
+ return VIR_DOMAIN_JOB_COMPLETED;
+
+ case QEMU_DOMAIN_JOB_STATUS_FAILED:
+ return VIR_DOMAIN_JOB_FAILED;
+
+ case QEMU_DOMAIN_JOB_STATUS_CANCELED:
+ return VIR_DOMAIN_JOB_CANCELLED;
+ }
+
+ return VIR_DOMAIN_JOB_NONE;
+}
+
+int
+qemuDomainJobInfoUpdateTime(qemuDomainJobInfoPtr jobInfo)
+{
+ unsigned long long now;
+
+ if (!jobInfo->started)
+ return 0;
+
+ if (virTimeMillisNow(&now) < 0)
+ return -1;
+
+ if (now < jobInfo->started) {
+ VIR_WARN("Async job starts in the future");
+ jobInfo->started = 0;
+ return 0;
+ }
+
+ jobInfo->timeElapsed = now - jobInfo->started;
+ return 0;
+}
+
+int
+qemuDomainJobInfoUpdateDowntime(qemuDomainJobInfoPtr jobInfo)
+{
+ unsigned long long now;
+
+ if (!jobInfo->stopped)
+ return 0;
+
+ if (virTimeMillisNow(&now) < 0)
+ return -1;
+
+ if (now < jobInfo->stopped) {
+ VIR_WARN("Guest's CPUs stopped in the future");
+ jobInfo->stopped = 0;
+ return 0;
+ }
+
+ jobInfo->stats.mig.downtime = now - jobInfo->stopped;
+ jobInfo->stats.mig.downtime_set = true;
+ return 0;
+}
+
+
+int
+qemuDomainJobInfoToInfo(qemuDomainJobInfoPtr jobInfo,
+ virDomainJobInfoPtr info)
+{
+ info->type = qemuDomainJobStatusToType(jobInfo->status);
+ info->timeElapsed = jobInfo->timeElapsed;
+
+ switch (jobInfo->statsType) {
+ case QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION:
+ info->memTotal = jobInfo->stats.mig.ram_total;
+ info->memRemaining = jobInfo->stats.mig.ram_remaining;
+ info->memProcessed = jobInfo->stats.mig.ram_transferred;
+ info->fileTotal = jobInfo->stats.mig.disk_total +
+ jobInfo->mirrorStats.total;
+ info->fileRemaining = jobInfo->stats.mig.disk_remaining +
+ (jobInfo->mirrorStats.total -
+ jobInfo->mirrorStats.transferred);
+ info->fileProcessed = jobInfo->stats.mig.disk_transferred +
+ jobInfo->mirrorStats.transferred;
+ break;
+
+ case QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP:
+ info->memTotal = jobInfo->stats.mig.ram_total;
+ info->memRemaining = jobInfo->stats.mig.ram_remaining;
+ info->memProcessed = jobInfo->stats.mig.ram_transferred;
+ break;
+
+ case QEMU_DOMAIN_JOB_STATS_TYPE_MEMDUMP:
+ info->memTotal = jobInfo->stats.dump.total;
+ info->memProcessed = jobInfo->stats.dump.completed;
+ info->memRemaining = info->memTotal - info->memProcessed;
+ break;
+
+ case QEMU_DOMAIN_JOB_STATS_TYPE_BACKUP:
+ info->fileTotal = jobInfo->stats.backup.total;
+ info->fileProcessed = jobInfo->stats.backup.transferred;
+ info->fileRemaining = info->fileTotal - info->fileProcessed;
+ break;
+
+ case QEMU_DOMAIN_JOB_STATS_TYPE_NONE:
+ break;
+ }
+
+ info->dataTotal = info->memTotal + info->fileTotal;
+ info->dataRemaining = info->memRemaining + info->fileRemaining;
+ info->dataProcessed = info->memProcessed + info->fileProcessed;
+
+ return 0;
+}
+
+
+static int
+qemuDomainMigrationJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
+ int *type,
+ virTypedParameterPtr *params,
+ int *nparams)
+{
+ qemuMonitorMigrationStats *stats = &jobInfo->stats.mig;
+ qemuDomainMirrorStatsPtr mirrorStats = &jobInfo->mirrorStats;
+ virTypedParameterPtr par = NULL;
+ int maxpar = 0;
+ int npar = 0;
+ unsigned long long mirrorRemaining = mirrorStats->total -
+ mirrorStats->transferred;
+
+ if (virTypedParamsAddInt(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_OPERATION,
+ jobInfo->operation) < 0)
+ goto error;
+
+ if (virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_TIME_ELAPSED,
+ jobInfo->timeElapsed) < 0)
+ goto error;
+
+ if (jobInfo->timeDeltaSet &&
+ jobInfo->timeElapsed > jobInfo->timeDelta &&
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_TIME_ELAPSED_NET,
+ jobInfo->timeElapsed - jobInfo->timeDelta) < 0)
+ goto error;
+
+ if (stats->downtime_set &&
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_DOWNTIME,
+ stats->downtime) < 0)
+ goto error;
+
+ if (stats->downtime_set &&
+ jobInfo->timeDeltaSet &&
+ stats->downtime > jobInfo->timeDelta &&
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_DOWNTIME_NET,
+ stats->downtime - jobInfo->timeDelta) < 0)
+ goto error;
+
+ if (stats->setup_time_set &&
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_SETUP_TIME,
+ stats->setup_time) < 0)
+ goto error;
+
+ if (virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_DATA_TOTAL,
+ stats->ram_total +
+ stats->disk_total +
+ mirrorStats->total) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_DATA_PROCESSED,
+ stats->ram_transferred +
+ stats->disk_transferred +
+ mirrorStats->transferred) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_DATA_REMAINING,
+ stats->ram_remaining +
+ stats->disk_remaining +
+ mirrorRemaining) < 0)
+ goto error;
+
+ if (virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_MEMORY_TOTAL,
+ stats->ram_total) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_MEMORY_PROCESSED,
+ stats->ram_transferred) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_MEMORY_REMAINING,
+ stats->ram_remaining) < 0)
+ goto error;
+
+ if (stats->ram_bps &&
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_MEMORY_BPS,
+ stats->ram_bps) < 0)
+ goto error;
+
+ if (stats->ram_duplicate_set) {
+ if (virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_MEMORY_CONSTANT,
+ stats->ram_duplicate) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_MEMORY_NORMAL,
+ stats->ram_normal) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_MEMORY_NORMAL_BYTES,
+ stats->ram_normal_bytes) < 0)
+ goto error;
+ }
+
+ if (virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_MEMORY_DIRTY_RATE,
+ stats->ram_dirty_rate) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_MEMORY_ITERATION,
+ stats->ram_iteration) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_MEMORY_POSTCOPY_REQS,
+ stats->ram_postcopy_reqs) < 0)
+ goto error;
+
+ if (stats->ram_page_size > 0 &&
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_MEMORY_PAGE_SIZE,
+ stats->ram_page_size) < 0)
+ goto error;
+
+ /* The remaining stats are disk, mirror, or migration specific
+ * so if this is a SAVEDUMP, we can just skip them */
+ if (jobInfo->statsType == QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP)
+ goto done;
+
+ if (virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_DISK_TOTAL,
+ stats->disk_total +
+ mirrorStats->total) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_DISK_PROCESSED,
+ stats->disk_transferred +
+ mirrorStats->transferred) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_DISK_REMAINING,
+ stats->disk_remaining +
+ mirrorRemaining) < 0)
+ goto error;
+
+ if (stats->disk_bps &&
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_DISK_BPS,
+ stats->disk_bps) < 0)
+ goto error;
+
+ if (stats->xbzrle_set) {
+ if (virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_COMPRESSION_CACHE,
+ stats->xbzrle_cache_size) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_COMPRESSION_BYTES,
+ stats->xbzrle_bytes) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_COMPRESSION_PAGES,
+ stats->xbzrle_pages) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_COMPRESSION_CACHE_MISSES,
+ stats->xbzrle_cache_miss) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_COMPRESSION_OVERFLOW,
+ stats->xbzrle_overflow) < 0)
+ goto error;
+ }
+
+ if (stats->cpu_throttle_percentage &&
+ virTypedParamsAddInt(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_AUTO_CONVERGE_THROTTLE,
+ stats->cpu_throttle_percentage) < 0)
+ goto error;
+
+ done:
+ *type = qemuDomainJobStatusToType(jobInfo->status);
+ *params = par;
+ *nparams = npar;
+ return 0;
+
+ error:
+ virTypedParamsFree(par, npar);
+ return -1;
+}
+
+
+static int
+qemuDomainDumpJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
+ int *type,
+ virTypedParameterPtr *params,
+ int *nparams)
+{
+ qemuMonitorDumpStats *stats = &jobInfo->stats.dump;
+ virTypedParameterPtr par = NULL;
+ int maxpar = 0;
+ int npar = 0;
+
+ if (virTypedParamsAddInt(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_OPERATION,
+ jobInfo->operation) < 0)
+ goto error;
+
+ if (virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_TIME_ELAPSED,
+ jobInfo->timeElapsed) < 0)
+ goto error;
+
+ if (virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_MEMORY_TOTAL,
+ stats->total) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_MEMORY_PROCESSED,
+ stats->completed) < 0 ||
+ virTypedParamsAddULLong(&par, &npar, &maxpar,
+ VIR_DOMAIN_JOB_MEMORY_REMAINING,
+ stats->total - stats->completed) < 0)
+ goto error;
+
+ *type = qemuDomainJobStatusToType(jobInfo->status);
+ *params = par;
+ *nparams = npar;
+ return 0;
+
+ error:
+ virTypedParamsFree(par, npar);
+ return -1;
+}
+
+
+static int
+qemuDomainBackupJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
+ int *type,
+ virTypedParameterPtr *params,
+ int *nparams)
+{
+ qemuDomainBackupStats *stats = &jobInfo->stats.backup;
+ g_autoptr(virTypedParamList) par = g_new0(virTypedParamList, 1);
+
+ if (virTypedParamListAddInt(par, jobInfo->operation,
+ VIR_DOMAIN_JOB_OPERATION) < 0)
+ return -1;
+
+ if (virTypedParamListAddULLong(par, jobInfo->timeElapsed,
+ VIR_DOMAIN_JOB_TIME_ELAPSED) < 0)
+ return -1;
+
+ if (stats->transferred > 0 || stats->total > 0) {
+ if (virTypedParamListAddULLong(par, stats->total,
+ VIR_DOMAIN_JOB_DISK_TOTAL) < 0)
+ return -1;
+
+ if (virTypedParamListAddULLong(par, stats->transferred,
+ VIR_DOMAIN_JOB_DISK_PROCESSED) < 0)
+ return -1;
+
+ if (virTypedParamListAddULLong(par, stats->total - stats->transferred,
+ VIR_DOMAIN_JOB_DISK_REMAINING) < 0)
+ return -1;
+ }
+
+ if (stats->tmp_used > 0 || stats->tmp_total > 0) {
+ if (virTypedParamListAddULLong(par, stats->tmp_used,
+ VIR_DOMAIN_JOB_DISK_TEMP_USED) < 0)
+ return -1;
+
+ if (virTypedParamListAddULLong(par, stats->tmp_total,
+ VIR_DOMAIN_JOB_DISK_TEMP_TOTAL) < 0)
+ return -1;
+ }
+
+ if (jobInfo->status != QEMU_DOMAIN_JOB_STATUS_ACTIVE &&
+ virTypedParamListAddBoolean(par,
+ jobInfo->status ==
QEMU_DOMAIN_JOB_STATUS_COMPLETED,
+ VIR_DOMAIN_JOB_SUCCESS) < 0)
+ return -1;
+
+ if (jobInfo->errmsg &&
+ virTypedParamListAddString(par, jobInfo->errmsg, VIR_DOMAIN_JOB_ERRMSG) <
0)
+ return -1;
+
+ *nparams = virTypedParamListStealParams(par, params);
+ *type = qemuDomainJobStatusToType(jobInfo->status);
+ return 0;
+}
+
+
+int
+qemuDomainJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
+ int *type,
+ virTypedParameterPtr *params,
+ int *nparams)
+{
+ switch (jobInfo->statsType) {
+ case QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION:
+ case QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP:
+ return qemuDomainMigrationJobInfoToParams(jobInfo, type, params, nparams);
+
+ case QEMU_DOMAIN_JOB_STATS_TYPE_MEMDUMP:
+ return qemuDomainDumpJobInfoToParams(jobInfo, type, params, nparams);
+
+ case QEMU_DOMAIN_JOB_STATS_TYPE_BACKUP:
+ return qemuDomainBackupJobInfoToParams(jobInfo, type, params, nparams);
+
+ case QEMU_DOMAIN_JOB_STATS_TYPE_NONE:
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("invalid job statistics type"));
+ break;
+
+ default:
+ virReportEnumRangeError(qemuDomainJobStatsType, jobInfo->statsType);
+ break;
+ }
+
+ return -1;
+}
+
+
+void
+qemuDomainJobInfoFree(qemuDomainJobInfoPtr info)
+{
+ g_free(info->errmsg);
+ g_free(info);
+}
+
+
+qemuDomainJobInfoPtr
+qemuDomainJobInfoCopy(qemuDomainJobInfoPtr info)
+{
+ qemuDomainJobInfoPtr ret = g_new0(qemuDomainJobInfo, 1);
+
+ memcpy(ret, info, sizeof(*info));
+
+ ret->errmsg = g_strdup(info->errmsg);
+
+ return ret;
+}
+
+
static void *
qemuJobAllocPrivate(void)
{
@@ -91,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);
}
@@ -104,6 +557,7 @@ qemuJobResetPrivate(void *opaque)
priv->spiceMigrated = false;
priv->dumpCompleted = false;
qemuMigrationParamsFree(priv->migParams);
+ g_clear_pointer(&priv->current, qemuDomainJobInfoFree);
priv->migParams = NULL;
}
@@ -120,6 +574,48 @@ 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 (!jobPriv->completed)
+ return;
+
+ if (qemuDomainJobInfoToParams(jobPriv->completed, &type,
+ ¶ms, &nparams) < 0) {
+ VIR_WARN("Could not get stats for completed job; domain %s",
+ vm->def->name);
+ }
+
+ event = virDomainEventJobCompletedNewFromObj(vm, params, nparams);
+ virObjectEventStateQueue(driver->domainEventState, event);
+}
static int
qemuDomainParseJobPrivate(xmlXPathContextPtr ctxt,
@@ -140,6 +636,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 3a1bcbbfa3..386ae17272 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,8 +537,36 @@ 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
*/
};
+
+void qemuDomainEventEmitJobCompleted(virQEMUDriverPtr driver,
+ virDomainObjPtr vm);
+
+void
+qemuDomainJobInfoFree(qemuDomainJobInfoPtr info);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuDomainJobInfo, qemuDomainJobInfoFree);
+
+qemuDomainJobInfoPtr
+qemuDomainJobInfoCopy(qemuDomainJobInfoPtr info);
+
+int qemuDomainJobInfoUpdateTime(qemuDomainJobInfoPtr jobInfo)
+ ATTRIBUTE_NONNULL(1);
+int qemuDomainJobInfoUpdateDowntime(qemuDomainJobInfoPtr jobInfo)
+ ATTRIBUTE_NONNULL(1);
+int qemuDomainJobInfoToInfo(qemuDomainJobInfoPtr jobInfo,
+ virDomainJobInfoPtr info)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+int qemuDomainJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
+ int *type,
+ virTypedParameterPtr *params,
+ int *nparams)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2)
+ ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4);
+
int qemuDomainObjStartWorker(virDomainObjPtr dom);
void qemuDomainObjStopWorker(virDomainObjPtr dom);
diff --git a/src/qemu/qemu_domainjob.c b/src/qemu/qemu_domainjob.c
index 6393cc0b40..503a87bb12 100644
--- a/src/qemu/qemu_domainjob.c
+++ b/src/qemu/qemu_domainjob.c
@@ -115,51 +115,6 @@ qemuDomainAsyncJobPhaseFromString(qemuDomainAsyncJob job,
return -1;
}
-
-void
-qemuDomainJobInfoFree(qemuDomainJobInfoPtr info)
-{
- g_free(info->errmsg);
- g_free(info);
-}
-
-
-qemuDomainJobInfoPtr
-qemuDomainJobInfoCopy(qemuDomainJobInfoPtr info)
-{
- qemuDomainJobInfoPtr ret = g_new0(qemuDomainJobInfo, 1);
-
- memcpy(ret, info, sizeof(*info));
-
- ret->errmsg = g_strdup(info->errmsg);
-
- return ret;
-}
-
-void
-qemuDomainEventEmitJobCompleted(virQEMUDriverPtr driver,
- virDomainObjPtr vm)
-{
- qemuDomainObjPrivatePtr priv = vm->privateData;
- virObjectEventPtr event;
- virTypedParameterPtr params = NULL;
- int nparams = 0;
- int type;
-
- if (!priv->job.completed)
- return;
-
- if (qemuDomainJobInfoToParams(priv->job.completed, &type,
- ¶ms, &nparams) < 0) {
- VIR_WARN("Could not get stats for completed job; domain %s",
- vm->def->name);
- }
-
- event = virDomainEventJobCompletedNewFromObj(vm, params, nparams);
- virObjectEventStateQueue(driver->domainEventState, event);
-}
-
-
int
qemuDomainObjInitJob(qemuDomainJobObjPtr job,
qemuDomainObjPrivateJobCallbacksPtr cb)
@@ -216,7 +171,6 @@ qemuDomainObjResetAsyncJob(qemuDomainJobObjPtr job)
job->mask = QEMU_JOB_DEFAULT_MASK;
job->abortJob = false;
VIR_FREE(job->error);
- g_clear_pointer(&job->current, qemuDomainJobInfoFree);
job->cb->resetJobPrivate(job->privateData);
job->apiFlags = 0;
}
@@ -251,8 +205,6 @@ qemuDomainObjFreeJob(qemuDomainJobObjPtr job)
qemuDomainObjResetJob(job);
qemuDomainObjResetAsyncJob(job);
job->cb->freeJobPrivate(job->privateData);
- g_clear_pointer(&job->current, qemuDomainJobInfoFree);
- g_clear_pointer(&job->completed, qemuDomainJobInfoFree);
virCondDestroy(&job->cond);
virCondDestroy(&job->asyncCond);
}
@@ -264,435 +216,6 @@ qemuDomainTrackJob(qemuDomainJob job)
}
-int
-qemuDomainJobInfoUpdateTime(qemuDomainJobInfoPtr jobInfo)
-{
- unsigned long long now;
-
- if (!jobInfo->started)
- return 0;
-
- if (virTimeMillisNow(&now) < 0)
- return -1;
-
- if (now < jobInfo->started) {
- VIR_WARN("Async job starts in the future");
- jobInfo->started = 0;
- return 0;
- }
-
- jobInfo->timeElapsed = now - jobInfo->started;
- return 0;
-}
-
-int
-qemuDomainJobInfoUpdateDowntime(qemuDomainJobInfoPtr jobInfo)
-{
- unsigned long long now;
-
- if (!jobInfo->stopped)
- return 0;
-
- if (virTimeMillisNow(&now) < 0)
- return -1;
-
- if (now < jobInfo->stopped) {
- VIR_WARN("Guest's CPUs stopped in the future");
- jobInfo->stopped = 0;
- return 0;
- }
-
- jobInfo->stats.mig.downtime = now - jobInfo->stopped;
- jobInfo->stats.mig.downtime_set = true;
- return 0;
-}
-
-static virDomainJobType
-qemuDomainJobStatusToType(qemuDomainJobStatus status)
-{
- switch (status) {
- case QEMU_DOMAIN_JOB_STATUS_NONE:
- break;
-
- case QEMU_DOMAIN_JOB_STATUS_ACTIVE:
- case QEMU_DOMAIN_JOB_STATUS_MIGRATING:
- case QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED:
- case QEMU_DOMAIN_JOB_STATUS_POSTCOPY:
- case QEMU_DOMAIN_JOB_STATUS_PAUSED:
- return VIR_DOMAIN_JOB_UNBOUNDED;
-
- case QEMU_DOMAIN_JOB_STATUS_COMPLETED:
- return VIR_DOMAIN_JOB_COMPLETED;
-
- case QEMU_DOMAIN_JOB_STATUS_FAILED:
- return VIR_DOMAIN_JOB_FAILED;
-
- case QEMU_DOMAIN_JOB_STATUS_CANCELED:
- return VIR_DOMAIN_JOB_CANCELLED;
- }
-
- return VIR_DOMAIN_JOB_NONE;
-}
-
-int
-qemuDomainJobInfoToInfo(qemuDomainJobInfoPtr jobInfo,
- virDomainJobInfoPtr info)
-{
- info->type = qemuDomainJobStatusToType(jobInfo->status);
- info->timeElapsed = jobInfo->timeElapsed;
-
- switch (jobInfo->statsType) {
- case QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION:
- info->memTotal = jobInfo->stats.mig.ram_total;
- info->memRemaining = jobInfo->stats.mig.ram_remaining;
- info->memProcessed = jobInfo->stats.mig.ram_transferred;
- info->fileTotal = jobInfo->stats.mig.disk_total +
- jobInfo->mirrorStats.total;
- info->fileRemaining = jobInfo->stats.mig.disk_remaining +
- (jobInfo->mirrorStats.total -
- jobInfo->mirrorStats.transferred);
- info->fileProcessed = jobInfo->stats.mig.disk_transferred +
- jobInfo->mirrorStats.transferred;
- break;
-
- case QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP:
- info->memTotal = jobInfo->stats.mig.ram_total;
- info->memRemaining = jobInfo->stats.mig.ram_remaining;
- info->memProcessed = jobInfo->stats.mig.ram_transferred;
- break;
-
- case QEMU_DOMAIN_JOB_STATS_TYPE_MEMDUMP:
- info->memTotal = jobInfo->stats.dump.total;
- info->memProcessed = jobInfo->stats.dump.completed;
- info->memRemaining = info->memTotal - info->memProcessed;
- break;
-
- case QEMU_DOMAIN_JOB_STATS_TYPE_BACKUP:
- info->fileTotal = jobInfo->stats.backup.total;
- info->fileProcessed = jobInfo->stats.backup.transferred;
- info->fileRemaining = info->fileTotal - info->fileProcessed;
- break;
-
- case QEMU_DOMAIN_JOB_STATS_TYPE_NONE:
- break;
- }
-
- info->dataTotal = info->memTotal + info->fileTotal;
- info->dataRemaining = info->memRemaining + info->fileRemaining;
- info->dataProcessed = info->memProcessed + info->fileProcessed;
-
- return 0;
-}
-
-
-static int
-qemuDomainMigrationJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
- int *type,
- virTypedParameterPtr *params,
- int *nparams)
-{
- qemuMonitorMigrationStats *stats = &jobInfo->stats.mig;
- qemuDomainMirrorStatsPtr mirrorStats = &jobInfo->mirrorStats;
- virTypedParameterPtr par = NULL;
- int maxpar = 0;
- int npar = 0;
- unsigned long long mirrorRemaining = mirrorStats->total -
- mirrorStats->transferred;
-
- if (virTypedParamsAddInt(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_OPERATION,
- jobInfo->operation) < 0)
- goto error;
-
- if (virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_TIME_ELAPSED,
- jobInfo->timeElapsed) < 0)
- goto error;
-
- if (jobInfo->timeDeltaSet &&
- jobInfo->timeElapsed > jobInfo->timeDelta &&
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_TIME_ELAPSED_NET,
- jobInfo->timeElapsed - jobInfo->timeDelta) < 0)
- goto error;
-
- if (stats->downtime_set &&
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_DOWNTIME,
- stats->downtime) < 0)
- goto error;
-
- if (stats->downtime_set &&
- jobInfo->timeDeltaSet &&
- stats->downtime > jobInfo->timeDelta &&
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_DOWNTIME_NET,
- stats->downtime - jobInfo->timeDelta) < 0)
- goto error;
-
- if (stats->setup_time_set &&
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_SETUP_TIME,
- stats->setup_time) < 0)
- goto error;
-
- if (virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_DATA_TOTAL,
- stats->ram_total +
- stats->disk_total +
- mirrorStats->total) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_DATA_PROCESSED,
- stats->ram_transferred +
- stats->disk_transferred +
- mirrorStats->transferred) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_DATA_REMAINING,
- stats->ram_remaining +
- stats->disk_remaining +
- mirrorRemaining) < 0)
- goto error;
-
- if (virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_MEMORY_TOTAL,
- stats->ram_total) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_MEMORY_PROCESSED,
- stats->ram_transferred) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_MEMORY_REMAINING,
- stats->ram_remaining) < 0)
- goto error;
-
- if (stats->ram_bps &&
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_MEMORY_BPS,
- stats->ram_bps) < 0)
- goto error;
-
- if (stats->ram_duplicate_set) {
- if (virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_MEMORY_CONSTANT,
- stats->ram_duplicate) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_MEMORY_NORMAL,
- stats->ram_normal) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_MEMORY_NORMAL_BYTES,
- stats->ram_normal_bytes) < 0)
- goto error;
- }
-
- if (virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_MEMORY_DIRTY_RATE,
- stats->ram_dirty_rate) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_MEMORY_ITERATION,
- stats->ram_iteration) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_MEMORY_POSTCOPY_REQS,
- stats->ram_postcopy_reqs) < 0)
- goto error;
-
- if (stats->ram_page_size > 0 &&
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_MEMORY_PAGE_SIZE,
- stats->ram_page_size) < 0)
- goto error;
-
- /* The remaining stats are disk, mirror, or migration specific
- * so if this is a SAVEDUMP, we can just skip them */
- if (jobInfo->statsType == QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP)
- goto done;
-
- if (virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_DISK_TOTAL,
- stats->disk_total +
- mirrorStats->total) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_DISK_PROCESSED,
- stats->disk_transferred +
- mirrorStats->transferred) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_DISK_REMAINING,
- stats->disk_remaining +
- mirrorRemaining) < 0)
- goto error;
-
- if (stats->disk_bps &&
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_DISK_BPS,
- stats->disk_bps) < 0)
- goto error;
-
- if (stats->xbzrle_set) {
- if (virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_COMPRESSION_CACHE,
- stats->xbzrle_cache_size) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_COMPRESSION_BYTES,
- stats->xbzrle_bytes) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_COMPRESSION_PAGES,
- stats->xbzrle_pages) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_COMPRESSION_CACHE_MISSES,
- stats->xbzrle_cache_miss) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_COMPRESSION_OVERFLOW,
- stats->xbzrle_overflow) < 0)
- goto error;
- }
-
- if (stats->cpu_throttle_percentage &&
- virTypedParamsAddInt(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_AUTO_CONVERGE_THROTTLE,
- stats->cpu_throttle_percentage) < 0)
- goto error;
-
- done:
- *type = qemuDomainJobStatusToType(jobInfo->status);
- *params = par;
- *nparams = npar;
- return 0;
-
- error:
- virTypedParamsFree(par, npar);
- return -1;
-}
-
-
-static int
-qemuDomainDumpJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
- int *type,
- virTypedParameterPtr *params,
- int *nparams)
-{
- qemuMonitorDumpStats *stats = &jobInfo->stats.dump;
- virTypedParameterPtr par = NULL;
- int maxpar = 0;
- int npar = 0;
-
- if (virTypedParamsAddInt(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_OPERATION,
- jobInfo->operation) < 0)
- goto error;
-
- if (virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_TIME_ELAPSED,
- jobInfo->timeElapsed) < 0)
- goto error;
-
- if (virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_MEMORY_TOTAL,
- stats->total) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_MEMORY_PROCESSED,
- stats->completed) < 0 ||
- virTypedParamsAddULLong(&par, &npar, &maxpar,
- VIR_DOMAIN_JOB_MEMORY_REMAINING,
- stats->total - stats->completed) < 0)
- goto error;
-
- *type = qemuDomainJobStatusToType(jobInfo->status);
- *params = par;
- *nparams = npar;
- return 0;
-
- error:
- virTypedParamsFree(par, npar);
- return -1;
-}
-
-
-static int
-qemuDomainBackupJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
- int *type,
- virTypedParameterPtr *params,
- int *nparams)
-{
- qemuDomainBackupStats *stats = &jobInfo->stats.backup;
- g_autoptr(virTypedParamList) par = g_new0(virTypedParamList, 1);
-
- if (virTypedParamListAddInt(par, jobInfo->operation,
- VIR_DOMAIN_JOB_OPERATION) < 0)
- return -1;
-
- if (virTypedParamListAddULLong(par, jobInfo->timeElapsed,
- VIR_DOMAIN_JOB_TIME_ELAPSED) < 0)
- return -1;
-
- if (stats->transferred > 0 || stats->total > 0) {
- if (virTypedParamListAddULLong(par, stats->total,
- VIR_DOMAIN_JOB_DISK_TOTAL) < 0)
- return -1;
-
- if (virTypedParamListAddULLong(par, stats->transferred,
- VIR_DOMAIN_JOB_DISK_PROCESSED) < 0)
- return -1;
-
- if (virTypedParamListAddULLong(par, stats->total - stats->transferred,
- VIR_DOMAIN_JOB_DISK_REMAINING) < 0)
- return -1;
- }
-
- if (stats->tmp_used > 0 || stats->tmp_total > 0) {
- if (virTypedParamListAddULLong(par, stats->tmp_used,
- VIR_DOMAIN_JOB_DISK_TEMP_USED) < 0)
- return -1;
-
- if (virTypedParamListAddULLong(par, stats->tmp_total,
- VIR_DOMAIN_JOB_DISK_TEMP_TOTAL) < 0)
- return -1;
- }
-
- if (jobInfo->status != QEMU_DOMAIN_JOB_STATUS_ACTIVE &&
- virTypedParamListAddBoolean(par,
- jobInfo->status ==
QEMU_DOMAIN_JOB_STATUS_COMPLETED,
- VIR_DOMAIN_JOB_SUCCESS) < 0)
- return -1;
-
- if (jobInfo->errmsg &&
- virTypedParamListAddString(par, jobInfo->errmsg, VIR_DOMAIN_JOB_ERRMSG) <
0)
- return -1;
-
- *nparams = virTypedParamListStealParams(par, params);
- *type = qemuDomainJobStatusToType(jobInfo->status);
- return 0;
-}
-
-
-int
-qemuDomainJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
- int *type,
- virTypedParameterPtr *params,
- int *nparams)
-{
- switch (jobInfo->statsType) {
- case QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION:
- case QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP:
- return qemuDomainMigrationJobInfoToParams(jobInfo, type, params, nparams);
-
- case QEMU_DOMAIN_JOB_STATS_TYPE_MEMDUMP:
- return qemuDomainDumpJobInfoToParams(jobInfo, type, params, nparams);
-
- case QEMU_DOMAIN_JOB_STATS_TYPE_BACKUP:
- return qemuDomainBackupJobInfoToParams(jobInfo, type, params, nparams);
-
- case QEMU_DOMAIN_JOB_STATS_TYPE_NONE:
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("invalid job statistics type"));
- break;
-
- default:
- virReportEnumRangeError(qemuDomainJobStatsType, jobInfo->statsType);
- break;
- }
-
- return -1;
-}
-
-
void
qemuDomainObjSetJobPhase(virQEMUDriverPtr driver,
virDomainObjPtr obj,
@@ -894,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;
}
}
@@ -1066,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 c83e055647..88051d099a 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;
@@ -164,6 +108,10 @@ typedef int (*qemuDomainObjPrivateJobFormat)(virBufferPtr,
qemuDomainJobObjPtr);
typedef int (*qemuDomainObjPrivateJobParse)(xmlXPathContextPtr,
qemuDomainJobObjPtr);
+typedef void (*qemuDomainObjJobInfoSetOperation)(qemuDomainJobObjPtr,
+ virDomainJobOperation);
+typedef void (*qemuDomainObjCurrentJobInfoInit)(qemuDomainJobObjPtr,
+ unsigned long long);
typedef struct _qemuDomainObjPrivateJobCallbacks qemuDomainObjPrivateJobCallbacks;
typedef qemuDomainObjPrivateJobCallbacks *qemuDomainObjPrivateJobCallbacksPtr;
@@ -173,6 +121,8 @@ struct _qemuDomainObjPrivateJobCallbacks {
qemuDomainObjPrivateJobReset resetJobPrivate;
qemuDomainObjPrivateJobFormat formatJob;
qemuDomainObjPrivateJobParse parseJob;
+ qemuDomainObjJobInfoSetOperation setJobInfoOperation;
+ qemuDomainObjCurrentJobInfoInit currentJobInfoInit;
};
struct _qemuDomainJobObj {
@@ -198,8 +148,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 */
@@ -213,9 +161,6 @@ const char *qemuDomainAsyncJobPhaseToString(qemuDomainAsyncJob job,
int qemuDomainAsyncJobPhaseFromString(qemuDomainAsyncJob job,
const char *phase);
-void qemuDomainEventEmitJobCompleted(virQEMUDriverPtr driver,
- virDomainObjPtr vm);
-
int qemuDomainObjBeginJob(virQEMUDriverPtr driver,
virDomainObjPtr obj,
qemuDomainJob job)
@@ -262,20 +207,6 @@ void qemuDomainRemoveInactiveJob(virQEMUDriverPtr driver,
void qemuDomainRemoveInactiveJobLocked(virQEMUDriverPtr driver,
virDomainObjPtr vm);
-int qemuDomainJobInfoUpdateTime(qemuDomainJobInfoPtr jobInfo)
- ATTRIBUTE_NONNULL(1);
-int qemuDomainJobInfoUpdateDowntime(qemuDomainJobInfoPtr jobInfo)
- ATTRIBUTE_NONNULL(1);
-int qemuDomainJobInfoToInfo(qemuDomainJobInfoPtr jobInfo,
- virDomainJobInfoPtr info)
- ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
-int qemuDomainJobInfoToParams(qemuDomainJobInfoPtr jobInfo,
- int *type,
- virTypedParameterPtr *params,
- int *nparams)
- ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2)
- ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4);
-
bool qemuDomainTrackJob(qemuDomainJob job);
void qemuDomainObjFreeJob(qemuDomainJobObjPtr job);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 8008da6d16..27be53d3e4 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;
@@ -3894,6 +3898,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;
@@ -3918,7 +3923,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. */
@@ -7479,6 +7485,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;
@@ -7502,8 +7509,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);
@@ -7521,7 +7528,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;
}
}
@@ -13575,13 +13582,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;
}
@@ -13599,11 +13607,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:
@@ -13678,6 +13686,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;
@@ -13692,6 +13701,7 @@ qemuDomainGetJobStats(virDomainPtr dom,
goto cleanup;
priv = vm->privateData;
+ jobPriv = priv->job.privateData;
if (qemuDomainGetJobStatsInternal(driver, vm, completed, &jobInfo) < 0)
goto cleanup;
@@ -13707,7 +13717,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);
@@ -13739,6 +13749,7 @@ static int qemuDomainAbortJob(virDomainPtr dom)
virDomainObjPtr vm;
int ret = -1;
qemuDomainObjPrivatePtr priv;
+ qemuDomainJobPrivatePtr jobPriv;
int reason;
if (!(vm = qemuDomainObjFromDomain(dom)))
@@ -13754,6 +13765,7 @@ static int qemuDomainAbortJob(virDomainPtr dom)
goto endjob;
priv = vm->privateData;
+ jobPriv = priv->job.privateData;
switch (priv->job.asyncJob) {
case QEMU_ASYNC_JOB_NONE:
@@ -13774,7 +13786,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",
@@ -15442,6 +15454,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;
@@ -15519,7 +15532,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 0f2f92b211..c517774c9f 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