This patch includes: * introducing new files: src/hypervisor/domain_job.c and src/hypervisor/domain_job.h * new struct virDomainJobData, which is almost the same as qemuDomainJobInfo - the only differences are moving qemu specific job stats into the qemuDomainJobDataPrivate and adding jobType (possibly more attributes in the future if needed). * moving qemuDomainJobStatus to the domain_job.h and renaming it as virDomainJobStatus * moving and renaming qemuDomainJobStatusToType * adding callback struct virDomainJobDataPrivateDataCallbacks taking care of allocation, copying and freeing of private data of virDomainJobData * adding functions for virDomainJobDataPrivateDataCallbacks for qemu hypervisor * adding 'public' (public between the different hypervisors) functions taking care of init, copy, free of virDomainJobData * renaming every occurrence of qemuDomainJobInfo *info to virDomainJobData *data Signed-off-by: Kristina Hanicova <khanicov@xxxxxxxxxx> --- src/hypervisor/domain_job.c | 78 +++++++++++ src/hypervisor/domain_job.h | 72 ++++++++++ src/hypervisor/meson.build | 1 + src/libvirt_private.syms | 7 + src/qemu/qemu_backup.c | 42 +++--- src/qemu/qemu_backup.h | 4 +- src/qemu/qemu_domainjob.c | 227 +++++++++++++++---------------- src/qemu/qemu_domainjob.h | 54 ++------ src/qemu/qemu_driver.c | 113 ++++++++------- src/qemu/qemu_migration.c | 190 ++++++++++++++------------ src/qemu/qemu_migration.h | 4 +- src/qemu/qemu_migration_cookie.c | 60 ++++---- src/qemu/qemu_migration_cookie.h | 2 +- src/qemu/qemu_process.c | 24 ++-- src/qemu/qemu_snapshot.c | 4 +- 15 files changed, 520 insertions(+), 362 deletions(-) create mode 100644 src/hypervisor/domain_job.c create mode 100644 src/hypervisor/domain_job.h diff --git a/src/hypervisor/domain_job.c b/src/hypervisor/domain_job.c new file mode 100644 index 0000000000..9ac8a6d544 --- /dev/null +++ b/src/hypervisor/domain_job.c @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2022 Red Hat, Inc. + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#include <config.h> +#include <string.h> + +#include "domain_job.h" + + +virDomainJobData * +virDomainJobDataInit(virDomainJobDataPrivateDataCallbacks *cb) +{ + virDomainJobData *ret = g_new0(virDomainJobData, 1); + + ret->privateDataCb = cb; + + if (ret->privateDataCb) + ret->privateData = ret->privateDataCb->allocPrivateData(); + + return ret; +} + +virDomainJobData * +virDomainJobDataCopy(virDomainJobData *data) +{ + virDomainJobData *ret = g_new0(virDomainJobData, 1); + + memcpy(ret, data, sizeof(*data)); + + if (ret->privateDataCb) + ret->privateData = data->privateDataCb->copyPrivateData(data->privateData); + + ret->errmsg = g_strdup(data->errmsg); + + return ret; +} + +void +virDomainJobDataFree(virDomainJobData *data) +{ + if (!data) + return; + + if (data->privateDataCb) + data->privateDataCb->freePrivateData(data->privateData); + + g_free(data->errmsg); + g_free(data); +} + +virDomainJobType +virDomainJobStatusToType(virDomainJobStatus status) +{ + switch (status) { + case VIR_DOMAIN_JOB_STATUS_NONE: + break; + + case VIR_DOMAIN_JOB_STATUS_ACTIVE: + case VIR_DOMAIN_JOB_STATUS_MIGRATING: + case VIR_DOMAIN_JOB_STATUS_HYPERVISOR_COMPLETED: + case VIR_DOMAIN_JOB_STATUS_POSTCOPY: + case VIR_DOMAIN_JOB_STATUS_PAUSED: + return VIR_DOMAIN_JOB_UNBOUNDED; + + case VIR_DOMAIN_JOB_STATUS_COMPLETED: + return VIR_DOMAIN_JOB_COMPLETED; + + case VIR_DOMAIN_JOB_STATUS_FAILED: + return VIR_DOMAIN_JOB_FAILED; + + case VIR_DOMAIN_JOB_STATUS_CANCELED: + return VIR_DOMAIN_JOB_CANCELLED; + } + + return VIR_DOMAIN_JOB_NONE; +} diff --git a/src/hypervisor/domain_job.h b/src/hypervisor/domain_job.h new file mode 100644 index 0000000000..257ef067e4 --- /dev/null +++ b/src/hypervisor/domain_job.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2022 Red Hat, Inc. + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#pragma once + +#include "internal.h" + +typedef enum { + VIR_DOMAIN_JOB_STATUS_NONE = 0, + VIR_DOMAIN_JOB_STATUS_ACTIVE, + VIR_DOMAIN_JOB_STATUS_MIGRATING, + VIR_DOMAIN_JOB_STATUS_HYPERVISOR_COMPLETED, + VIR_DOMAIN_JOB_STATUS_PAUSED, + VIR_DOMAIN_JOB_STATUS_POSTCOPY, + VIR_DOMAIN_JOB_STATUS_COMPLETED, + VIR_DOMAIN_JOB_STATUS_FAILED, + VIR_DOMAIN_JOB_STATUS_CANCELED, +} virDomainJobStatus; + +typedef void *(*virDomainJobDataPrivateDataAlloc) (void); +typedef void *(*virDomainJobDataPrivateDataCopy) (void *); +typedef void (*virDomainJobDataPrivateDataFree) (void *); + +typedef struct _virDomainJobDataPrivateDataCallbacks virDomainJobDataPrivateDataCallbacks; +struct _virDomainJobDataPrivateDataCallbacks { + virDomainJobDataPrivateDataAlloc allocPrivateData; + virDomainJobDataPrivateDataCopy copyPrivateData; + virDomainJobDataPrivateDataFree freePrivateData; +}; + +typedef struct _virDomainJobData virDomainJobData; +struct _virDomainJobData { + virDomainJobType jobType; + + virDomainJobStatus 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; + + char *errmsg; /* optional error message for failed completed jobs */ + + void *privateData; /* private data of hypervisors */ + virDomainJobDataPrivateDataCallbacks *privateDataCb; /* callbacks of private data, hypervisor based */ +}; + + +virDomainJobData * +virDomainJobDataInit(virDomainJobDataPrivateDataCallbacks *cb); + +void +virDomainJobDataFree(virDomainJobData *data); + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainJobData, virDomainJobDataFree); + +virDomainJobData * +virDomainJobDataCopy(virDomainJobData *data); + +virDomainJobType +virDomainJobStatusToType(virDomainJobStatus status); diff --git a/src/hypervisor/meson.build b/src/hypervisor/meson.build index 70801c0820..ec11ec0cd8 100644 --- a/src/hypervisor/meson.build +++ b/src/hypervisor/meson.build @@ -3,6 +3,7 @@ hypervisor_sources = [ 'domain_driver.c', 'virclosecallbacks.c', 'virhostdev.c', + 'domain_job.c', ] stateful_driver_source_files += files(hypervisor_sources) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 398cc79ee3..2380f02b88 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1577,6 +1577,13 @@ virDomainDriverParseBlkioDeviceStr; virDomainDriverSetupPersistentDefBlkioParams; +# hypervisor/domain_job.h +virDomainJobDataCopy; +virDomainJobDataFree; +virDomainJobDataInit; +virDomainJobStatusToType; + + # hypervisor/virclosecallbacks.h virCloseCallbacksGet; virCloseCallbacksGetConn; diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c index 1f7ab55eca..b0c81261de 100644 --- a/src/qemu/qemu_backup.c +++ b/src/qemu/qemu_backup.c @@ -555,7 +555,7 @@ qemuBackupBeginPullExportDisks(virDomainObj *vm, void qemuBackupJobTerminate(virDomainObj *vm, - qemuDomainJobStatus jobstatus) + virDomainJobStatus jobstatus) { qemuDomainObjPrivate *priv = vm->privateData; @@ -583,7 +583,7 @@ qemuBackupJobTerminate(virDomainObj *vm, !(priv->backup->apiFlags & VIR_DOMAIN_BACKUP_BEGIN_REUSE_EXTERNAL) && (priv->backup->type == VIR_DOMAIN_BACKUP_TYPE_PULL || (priv->backup->type == VIR_DOMAIN_BACKUP_TYPE_PUSH && - jobstatus != QEMU_DOMAIN_JOB_STATUS_COMPLETED))) { + jobstatus != VIR_DOMAIN_JOB_STATUS_COMPLETED))) { uid_t uid; gid_t gid; @@ -600,15 +600,19 @@ qemuBackupJobTerminate(virDomainObj *vm, } if (priv->job.current) { - qemuDomainJobInfoUpdateTime(priv->job.current); + qemuDomainJobDataPrivate *privData = NULL; - g_clear_pointer(&priv->job.completed, qemuDomainJobInfoFree); - priv->job.completed = qemuDomainJobInfoCopy(priv->job.current); + qemuDomainJobDataUpdateTime(priv->job.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; + g_clear_pointer(&priv->job.completed, virDomainJobDataFree); + priv->job.completed = virDomainJobDataCopy(priv->job.current); + + privData = priv->job.completed->privateData; + + privData->stats.backup.total = priv->backup->push_total; + privData->stats.backup.transferred = priv->backup->push_transferred; + privData->stats.backup.tmp_used = priv->backup->pull_tmp_used; + privData->stats.backup.tmp_total = priv->backup->pull_tmp_total; priv->job.completed->status = jobstatus; priv->job.completed->errmsg = g_strdup(priv->backup->errmsg); @@ -686,7 +690,7 @@ qemuBackupJobCancelBlockjobs(virDomainObj *vm, } if (terminatebackup && !has_active) - qemuBackupJobTerminate(vm, QEMU_DOMAIN_JOB_STATUS_CANCELED); + qemuBackupJobTerminate(vm, VIR_DOMAIN_JOB_STATUS_CANCELED); } @@ -741,6 +745,7 @@ qemuBackupBegin(virDomainObj *vm, unsigned int flags) { qemuDomainObjPrivate *priv = vm->privateData; + qemuDomainJobDataPrivate *privData = priv->job.current->privateData; g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(priv->driver); g_autoptr(virDomainBackupDef) def = NULL; g_autofree char *suffix = NULL; @@ -794,7 +799,7 @@ qemuBackupBegin(virDomainObj *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; + privData->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_BACKUP; if (!virDomainObjIsActive(vm)) { virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", @@ -984,7 +989,7 @@ qemuBackupNotifyBlockjobEnd(virDomainObj *vm, bool has_cancelling = false; bool has_cancelled = false; bool has_failed = false; - qemuDomainJobStatus jobstatus = QEMU_DOMAIN_JOB_STATUS_COMPLETED; + virDomainJobStatus jobstatus = VIR_DOMAIN_JOB_STATUS_COMPLETED; virDomainBackupDef *backup = priv->backup; size_t i; @@ -1081,9 +1086,9 @@ qemuBackupNotifyBlockjobEnd(virDomainObj *vm, /* all sub-jobs have stopped */ if (has_failed) - jobstatus = QEMU_DOMAIN_JOB_STATUS_FAILED; + jobstatus = VIR_DOMAIN_JOB_STATUS_FAILED; else if (has_cancelled && backup->type == VIR_DOMAIN_BACKUP_TYPE_PUSH) - jobstatus = QEMU_DOMAIN_JOB_STATUS_CANCELED; + jobstatus = VIR_DOMAIN_JOB_STATUS_CANCELED; qemuBackupJobTerminate(vm, jobstatus); } @@ -1134,9 +1139,10 @@ qemuBackupGetJobInfoStatsUpdateOne(virDomainObj *vm, int qemuBackupGetJobInfoStats(virQEMUDriver *driver, virDomainObj *vm, - qemuDomainJobInfo *jobInfo) + virDomainJobData *jobData) { - qemuDomainBackupStats *stats = &jobInfo->stats.backup; + qemuDomainJobDataPrivate *privJob = jobData->privateData; + qemuDomainBackupStats *stats = &privJob->stats.backup; qemuDomainObjPrivate *priv = vm->privateData; qemuMonitorJobInfo **blockjobs = NULL; size_t nblockjobs = 0; @@ -1150,10 +1156,10 @@ qemuBackupGetJobInfoStats(virQEMUDriver *driver, return -1; } - if (qemuDomainJobInfoUpdateTime(jobInfo) < 0) + if (qemuDomainJobDataUpdateTime(jobData) < 0) return -1; - jobInfo->status = QEMU_DOMAIN_JOB_STATUS_ACTIVE; + jobData->status = VIR_DOMAIN_JOB_STATUS_ACTIVE; qemuDomainObjEnterMonitor(driver, vm); diff --git a/src/qemu/qemu_backup.h b/src/qemu/qemu_backup.h index ebb3154516..de4dff9357 100644 --- a/src/qemu/qemu_backup.h +++ b/src/qemu/qemu_backup.h @@ -45,12 +45,12 @@ qemuBackupNotifyBlockjobEnd(virDomainObj *vm, void qemuBackupJobTerminate(virDomainObj *vm, - qemuDomainJobStatus jobstatus); + virDomainJobStatus jobstatus); int qemuBackupGetJobInfoStats(virQEMUDriver *driver, virDomainObj *vm, - qemuDomainJobInfo *jobInfo); + virDomainJobData *jobData); /* exported for testing */ int diff --git a/src/qemu/qemu_domainjob.c b/src/qemu/qemu_domainjob.c index 1ecde5af86..baa52dd986 100644 --- a/src/qemu/qemu_domainjob.c +++ b/src/qemu/qemu_domainjob.c @@ -63,6 +63,38 @@ VIR_ENUM_IMPL(qemuDomainAsyncJob, "backup", ); +static void * +qemuJobDataAllocPrivateData(void) +{ + return g_new0(qemuDomainJobDataPrivate, 1); +} + + +static void * +qemuJobDataCopyPrivateData(void *data) +{ + qemuDomainJobDataPrivate *ret = g_new0(qemuDomainJobDataPrivate, 1); + + memcpy(ret, data, sizeof(qemuDomainJobDataPrivate)); + + return ret; +} + + +static void +qemuJobDataFreePrivateData(void *data) +{ + g_free(data); +} + + +virDomainJobDataPrivateDataCallbacks qemuJobDataPrivateDataCallbacks = { + .allocPrivateData = qemuJobDataAllocPrivateData, + .copyPrivateData = qemuJobDataCopyPrivateData, + .freePrivateData = qemuJobDataFreePrivateData, +}; + + const char * qemuDomainAsyncJobPhaseToString(qemuDomainAsyncJob job, int phase G_GNUC_UNUSED) @@ -116,26 +148,6 @@ qemuDomainAsyncJobPhaseFromString(qemuDomainAsyncJob job, } -void -qemuDomainJobInfoFree(qemuDomainJobInfo *info) -{ - g_free(info->errmsg); - g_free(info); -} - - -qemuDomainJobInfo * -qemuDomainJobInfoCopy(qemuDomainJobInfo *info) -{ - qemuDomainJobInfo *ret = g_new0(qemuDomainJobInfo, 1); - - memcpy(ret, info, sizeof(*info)); - - ret->errmsg = g_strdup(info->errmsg); - - return ret; -} - void qemuDomainEventEmitJobCompleted(virQEMUDriver *driver, virDomainObj *vm) @@ -149,7 +161,7 @@ qemuDomainEventEmitJobCompleted(virQEMUDriver *driver, if (!priv->job.completed) return; - if (qemuDomainJobInfoToParams(priv->job.completed, &type, + if (qemuDomainJobDataToParams(priv->job.completed, &type, ¶ms, &nparams) < 0) { VIR_WARN("Could not get stats for completed job; domain %s", vm->def->name); @@ -216,7 +228,7 @@ qemuDomainObjResetAsyncJob(qemuDomainJobObj *job) job->mask = QEMU_JOB_DEFAULT_MASK; job->abortJob = false; VIR_FREE(job->error); - g_clear_pointer(&job->current, qemuDomainJobInfoFree); + g_clear_pointer(&job->current, virDomainJobDataFree); job->cb->resetJobPrivate(job->privateData); job->apiFlags = 0; } @@ -254,8 +266,8 @@ qemuDomainObjClearJob(qemuDomainJobObj *job) qemuDomainObjResetJob(job); qemuDomainObjResetAsyncJob(job); g_clear_pointer(&job->privateData, job->cb->freeJobPrivate); - g_clear_pointer(&job->current, qemuDomainJobInfoFree); - g_clear_pointer(&job->completed, qemuDomainJobInfoFree); + g_clear_pointer(&job->current, virDomainJobDataFree); + g_clear_pointer(&job->completed, virDomainJobDataFree); virCondDestroy(&job->cond); virCondDestroy(&job->asyncCond); } @@ -268,111 +280,87 @@ qemuDomainTrackJob(qemuDomainJob job) int -qemuDomainJobInfoUpdateTime(qemuDomainJobInfo *jobInfo) +qemuDomainJobDataUpdateTime(virDomainJobData *jobData) { unsigned long long now; - if (!jobInfo->started) + if (!jobData->started) return 0; if (virTimeMillisNow(&now) < 0) return -1; - if (now < jobInfo->started) { + if (now < jobData->started) { VIR_WARN("Async job starts in the future"); - jobInfo->started = 0; + jobData->started = 0; return 0; } - jobInfo->timeElapsed = now - jobInfo->started; + jobData->timeElapsed = now - jobData->started; return 0; } int -qemuDomainJobInfoUpdateDowntime(qemuDomainJobInfo *jobInfo) +qemuDomainJobDataUpdateDowntime(virDomainJobData *jobData) { unsigned long long now; + qemuDomainJobDataPrivate *priv = jobData->privateData; - if (!jobInfo->stopped) + if (!jobData->stopped) return 0; if (virTimeMillisNow(&now) < 0) return -1; - if (now < jobInfo->stopped) { + if (now < jobData->stopped) { VIR_WARN("Guest's CPUs stopped in the future"); - jobInfo->stopped = 0; + jobData->stopped = 0; return 0; } - jobInfo->stats.mig.downtime = now - jobInfo->stopped; - jobInfo->stats.mig.downtime_set = true; + priv->stats.mig.downtime = now - jobData->stopped; + priv->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(qemuDomainJobInfo *jobInfo, +qemuDomainJobDataToInfo(virDomainJobData *jobData, virDomainJobInfoPtr info) { - info->type = qemuDomainJobStatusToType(jobInfo->status); - info->timeElapsed = jobInfo->timeElapsed; + qemuDomainJobDataPrivate *priv = jobData->privateData; + info->type = virDomainJobStatusToType(jobData->status); + info->timeElapsed = jobData->timeElapsed; - switch (jobInfo->statsType) { + switch (priv->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; + info->memTotal = priv->stats.mig.ram_total; + info->memRemaining = priv->stats.mig.ram_remaining; + info->memProcessed = priv->stats.mig.ram_transferred; + info->fileTotal = priv->stats.mig.disk_total + + priv->mirrorStats.total; + info->fileRemaining = priv->stats.mig.disk_remaining + + (priv->mirrorStats.total - + priv->mirrorStats.transferred); + info->fileProcessed = priv->stats.mig.disk_transferred + + priv->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; + info->memTotal = priv->stats.mig.ram_total; + info->memRemaining = priv->stats.mig.ram_remaining; + info->memProcessed = priv->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->memTotal = priv->stats.dump.total; + info->memProcessed = priv->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->fileTotal = priv->stats.backup.total; + info->fileProcessed = priv->stats.backup.transferred; info->fileRemaining = info->fileTotal - info->fileProcessed; break; @@ -389,13 +377,14 @@ qemuDomainJobInfoToInfo(qemuDomainJobInfo *jobInfo, static int -qemuDomainMigrationJobInfoToParams(qemuDomainJobInfo *jobInfo, +qemuDomainMigrationJobDataToParams(virDomainJobData *jobData, int *type, virTypedParameterPtr *params, int *nparams) { - qemuMonitorMigrationStats *stats = &jobInfo->stats.mig; - qemuDomainMirrorStats *mirrorStats = &jobInfo->mirrorStats; + qemuDomainJobDataPrivate *priv = jobData->privateData; + qemuMonitorMigrationStats *stats = &priv->stats.mig; + qemuDomainMirrorStats *mirrorStats = &priv->mirrorStats; virTypedParameterPtr par = NULL; int maxpar = 0; int npar = 0; @@ -404,19 +393,19 @@ qemuDomainMigrationJobInfoToParams(qemuDomainJobInfo *jobInfo, if (virTypedParamsAddInt(&par, &npar, &maxpar, VIR_DOMAIN_JOB_OPERATION, - jobInfo->operation) < 0) + jobData->operation) < 0) goto error; if (virTypedParamsAddULLong(&par, &npar, &maxpar, VIR_DOMAIN_JOB_TIME_ELAPSED, - jobInfo->timeElapsed) < 0) + jobData->timeElapsed) < 0) goto error; - if (jobInfo->timeDeltaSet && - jobInfo->timeElapsed > jobInfo->timeDelta && + if (jobData->timeDeltaSet && + jobData->timeElapsed > jobData->timeDelta && virTypedParamsAddULLong(&par, &npar, &maxpar, VIR_DOMAIN_JOB_TIME_ELAPSED_NET, - jobInfo->timeElapsed - jobInfo->timeDelta) < 0) + jobData->timeElapsed - jobData->timeDelta) < 0) goto error; if (stats->downtime_set && @@ -426,11 +415,11 @@ qemuDomainMigrationJobInfoToParams(qemuDomainJobInfo *jobInfo, goto error; if (stats->downtime_set && - jobInfo->timeDeltaSet && - stats->downtime > jobInfo->timeDelta && + jobData->timeDeltaSet && + stats->downtime > jobData->timeDelta && virTypedParamsAddULLong(&par, &npar, &maxpar, VIR_DOMAIN_JOB_DOWNTIME_NET, - stats->downtime - jobInfo->timeDelta) < 0) + stats->downtime - jobData->timeDelta) < 0) goto error; if (stats->setup_time_set && @@ -505,7 +494,7 @@ qemuDomainMigrationJobInfoToParams(qemuDomainJobInfo *jobInfo, /* 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) + if (priv->statsType == QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP) goto done; if (virTypedParamsAddULLong(&par, &npar, &maxpar, @@ -554,7 +543,7 @@ qemuDomainMigrationJobInfoToParams(qemuDomainJobInfo *jobInfo, goto error; done: - *type = qemuDomainJobStatusToType(jobInfo->status); + *type = virDomainJobStatusToType(jobData->status); *params = par; *nparams = npar; return 0; @@ -566,24 +555,25 @@ qemuDomainMigrationJobInfoToParams(qemuDomainJobInfo *jobInfo, static int -qemuDomainDumpJobInfoToParams(qemuDomainJobInfo *jobInfo, +qemuDomainDumpJobDataToParams(virDomainJobData *jobData, int *type, virTypedParameterPtr *params, int *nparams) { - qemuMonitorDumpStats *stats = &jobInfo->stats.dump; + qemuDomainJobDataPrivate *priv = jobData->privateData; + qemuMonitorDumpStats *stats = &priv->stats.dump; virTypedParameterPtr par = NULL; int maxpar = 0; int npar = 0; if (virTypedParamsAddInt(&par, &npar, &maxpar, VIR_DOMAIN_JOB_OPERATION, - jobInfo->operation) < 0) + jobData->operation) < 0) goto error; if (virTypedParamsAddULLong(&par, &npar, &maxpar, VIR_DOMAIN_JOB_TIME_ELAPSED, - jobInfo->timeElapsed) < 0) + jobData->timeElapsed) < 0) goto error; if (virTypedParamsAddULLong(&par, &npar, &maxpar, @@ -597,7 +587,7 @@ qemuDomainDumpJobInfoToParams(qemuDomainJobInfo *jobInfo, stats->total - stats->completed) < 0) goto error; - *type = qemuDomainJobStatusToType(jobInfo->status); + *type = virDomainJobStatusToType(jobData->status); *params = par; *nparams = npar; return 0; @@ -609,19 +599,20 @@ qemuDomainDumpJobInfoToParams(qemuDomainJobInfo *jobInfo, static int -qemuDomainBackupJobInfoToParams(qemuDomainJobInfo *jobInfo, +qemuDomainBackupJobDataToParams(virDomainJobData *jobData, int *type, virTypedParameterPtr *params, int *nparams) { - qemuDomainBackupStats *stats = &jobInfo->stats.backup; + qemuDomainJobDataPrivate *priv = jobData->privateData; + qemuDomainBackupStats *stats = &priv->stats.backup; g_autoptr(virTypedParamList) par = g_new0(virTypedParamList, 1); - if (virTypedParamListAddInt(par, jobInfo->operation, + if (virTypedParamListAddInt(par, jobData->operation, VIR_DOMAIN_JOB_OPERATION) < 0) return -1; - if (virTypedParamListAddULLong(par, jobInfo->timeElapsed, + if (virTypedParamListAddULLong(par, jobData->timeElapsed, VIR_DOMAIN_JOB_TIME_ELAPSED) < 0) return -1; @@ -649,38 +640,40 @@ qemuDomainBackupJobInfoToParams(qemuDomainJobInfo *jobInfo, return -1; } - if (jobInfo->status != QEMU_DOMAIN_JOB_STATUS_ACTIVE && + if (jobData->status != VIR_DOMAIN_JOB_STATUS_ACTIVE && virTypedParamListAddBoolean(par, - jobInfo->status == QEMU_DOMAIN_JOB_STATUS_COMPLETED, + jobData->status == VIR_DOMAIN_JOB_STATUS_COMPLETED, VIR_DOMAIN_JOB_SUCCESS) < 0) return -1; - if (jobInfo->errmsg && - virTypedParamListAddString(par, jobInfo->errmsg, VIR_DOMAIN_JOB_ERRMSG) < 0) + if (jobData->errmsg && + virTypedParamListAddString(par, jobData->errmsg, VIR_DOMAIN_JOB_ERRMSG) < 0) return -1; *nparams = virTypedParamListStealParams(par, params); - *type = qemuDomainJobStatusToType(jobInfo->status); + *type = virDomainJobStatusToType(jobData->status); return 0; } int -qemuDomainJobInfoToParams(qemuDomainJobInfo *jobInfo, +qemuDomainJobDataToParams(virDomainJobData *jobData, int *type, virTypedParameterPtr *params, int *nparams) { - switch (jobInfo->statsType) { + qemuDomainJobDataPrivate *priv = jobData->privateData; + + switch (priv->statsType) { case QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION: case QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP: - return qemuDomainMigrationJobInfoToParams(jobInfo, type, params, nparams); + return qemuDomainMigrationJobDataToParams(jobData, type, params, nparams); case QEMU_DOMAIN_JOB_STATS_TYPE_MEMDUMP: - return qemuDomainDumpJobInfoToParams(jobInfo, type, params, nparams); + return qemuDomainDumpJobDataToParams(jobData, type, params, nparams); case QEMU_DOMAIN_JOB_STATS_TYPE_BACKUP: - return qemuDomainBackupJobInfoToParams(jobInfo, type, params, nparams); + return qemuDomainBackupJobDataToParams(jobData, type, params, nparams); case QEMU_DOMAIN_JOB_STATS_TYPE_NONE: virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -688,7 +681,7 @@ qemuDomainJobInfoToParams(qemuDomainJobInfo *jobInfo, break; default: - virReportEnumRangeError(qemuDomainJobStatsType, jobInfo->statsType); + virReportEnumRangeError(qemuDomainJobStatsType, priv->statsType); break; } @@ -895,8 +888,8 @@ qemuDomainObjBeginJobInternal(virQEMUDriver *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.current = virDomainJobDataInit(&qemuJobDataPrivateDataCallbacks); + priv->job.current->status = VIR_DOMAIN_JOB_STATUS_ACTIVE; priv->job.asyncJob = asyncJob; priv->job.asyncOwner = virThreadSelfID(); priv->job.asyncOwnerAPI = g_strdup(virThreadJobGet()); diff --git a/src/qemu/qemu_domainjob.h b/src/qemu/qemu_domainjob.h index f904bd49c2..36acf401dd 100644 --- a/src/qemu/qemu_domainjob.h +++ b/src/qemu/qemu_domainjob.h @@ -20,6 +20,7 @@ #include <glib-object.h> #include "qemu_monitor.h" +#include "domain_job.h" #define JOB_MASK(job) (job == 0 ? 0 : 1 << (job - 1)) #define QEMU_JOB_DEFAULT_MASK \ @@ -79,17 +80,6 @@ typedef enum { } qemuDomainAsyncJob; VIR_ENUM_DECL(qemuDomainAsyncJob); -typedef enum { - QEMU_DOMAIN_JOB_STATUS_NONE = 0, - QEMU_DOMAIN_JOB_STATUS_ACTIVE, - QEMU_DOMAIN_JOB_STATUS_MIGRATING, - QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED, - QEMU_DOMAIN_JOB_STATUS_PAUSED, - QEMU_DOMAIN_JOB_STATUS_POSTCOPY, - QEMU_DOMAIN_JOB_STATUS_COMPLETED, - QEMU_DOMAIN_JOB_STATUS_FAILED, - QEMU_DOMAIN_JOB_STATUS_CANCELED, -} qemuDomainJobStatus; typedef enum { QEMU_DOMAIN_JOB_STATS_TYPE_NONE = 0, @@ -114,24 +104,8 @@ struct _qemuDomainBackupStats { unsigned long long tmp_total; }; -typedef struct _qemuDomainJobInfo qemuDomainJobInfo; -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; +typedef struct _qemuDomainJobDataPrivate qemuDomainJobDataPrivate; +struct _qemuDomainJobDataPrivate { /* Raw values from QEMU */ qemuDomainJobStatsType statsType; union { @@ -140,17 +114,9 @@ struct _qemuDomainJobInfo { qemuDomainBackupStats backup; } stats; qemuDomainMirrorStats mirrorStats; - - char *errmsg; /* optional error message for failed completed jobs */ }; -void -qemuDomainJobInfoFree(qemuDomainJobInfo *info); - -G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuDomainJobInfo, qemuDomainJobInfoFree); - -qemuDomainJobInfo * -qemuDomainJobInfoCopy(qemuDomainJobInfo *info); +extern virDomainJobDataPrivateDataCallbacks qemuJobDataPrivateDataCallbacks; typedef struct _qemuDomainJobObj qemuDomainJobObj; @@ -198,8 +164,8 @@ 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 */ - qemuDomainJobInfo *current; /* async job progress data */ - qemuDomainJobInfo *completed; /* statistics data of a recently completed job */ + virDomainJobData *current; /* async job progress data */ + virDomainJobData *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 */ @@ -256,14 +222,14 @@ void qemuDomainObjDiscardAsyncJob(virQEMUDriver *driver, virDomainObj *obj); void qemuDomainObjReleaseAsyncJob(virDomainObj *obj); -int qemuDomainJobInfoUpdateTime(qemuDomainJobInfo *jobInfo) +int qemuDomainJobDataUpdateTime(virDomainJobData *jobData) ATTRIBUTE_NONNULL(1); -int qemuDomainJobInfoUpdateDowntime(qemuDomainJobInfo *jobInfo) +int qemuDomainJobDataUpdateDowntime(virDomainJobData *jobData) ATTRIBUTE_NONNULL(1); -int qemuDomainJobInfoToInfo(qemuDomainJobInfo *jobInfo, +int qemuDomainJobDataToInfo(virDomainJobData *jobData, virDomainJobInfoPtr info) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); -int qemuDomainJobInfoToParams(qemuDomainJobInfo *jobInfo, +int qemuDomainJobDataToParams(virDomainJobData *jobData, int *type, virTypedParameterPtr *params, int *nparams) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 9279eaf811..52a8931656 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -2637,6 +2637,7 @@ qemuDomainSaveInternal(virQEMUDriver *driver, int ret = -1; virObjectEvent *event = NULL; qemuDomainObjPrivate *priv = vm->privateData; + qemuDomainJobDataPrivate *privJobCurrent = priv->job.current->privateData; virQEMUSaveData *data = NULL; g_autoptr(qemuDomainSaveCookie) cookie = NULL; @@ -2653,7 +2654,7 @@ qemuDomainSaveInternal(virQEMUDriver *driver, goto endjob; } - priv->job.current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP; + privJobCurrent->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP; /* Pause */ if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) { @@ -2946,6 +2947,7 @@ qemuDumpWaitForCompletion(virDomainObj *vm) { qemuDomainObjPrivate *priv = vm->privateData; qemuDomainJobPrivate *jobPriv = priv->job.privateData; + qemuDomainJobDataPrivate *privJobCurrent = priv->job.current->privateData; VIR_DEBUG("Waiting for dump completion"); while (!jobPriv->dumpCompleted && !priv->job.abortJob) { @@ -2953,7 +2955,7 @@ qemuDumpWaitForCompletion(virDomainObj *vm) return -1; } - if (priv->job.current->stats.dump.status == QEMU_MONITOR_DUMP_STATUS_FAILED) { + if (privJobCurrent->stats.dump.status == QEMU_MONITOR_DUMP_STATUS_FAILED) { if (priv->job.error) virReportError(VIR_ERR_OPERATION_FAILED, _("memory-only dump failed: %s"), @@ -2964,7 +2966,7 @@ qemuDumpWaitForCompletion(virDomainObj *vm) return -1; } - qemuDomainJobInfoUpdateTime(priv->job.current); + qemuDomainJobDataUpdateTime(priv->job.current); return 0; } @@ -2992,10 +2994,13 @@ qemuDumpToFd(virQEMUDriver *driver, if (qemuSecuritySetImageFDLabel(driver->securityManager, vm->def, fd) < 0) return -1; - if (detach) - priv->job.current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_MEMDUMP; - else - g_clear_pointer(&priv->job.current, qemuDomainJobInfoFree); + if (detach) { + qemuDomainJobDataPrivate *privStats = priv->job.current->privateData; + + privStats->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_MEMDUMP; + } else { + g_clear_pointer(&priv->job.current, virDomainJobDataFree); + } if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) return -1; @@ -3130,6 +3135,7 @@ qemuDomainCoreDumpWithFormat(virDomainPtr dom, virQEMUDriver *driver = dom->conn->privateData; virDomainObj *vm; qemuDomainObjPrivate *priv = NULL; + qemuDomainJobDataPrivate *privJobCurrent = NULL; bool resume = false, paused = false; int ret = -1; virObjectEvent *event = NULL; @@ -3154,7 +3160,8 @@ qemuDomainCoreDumpWithFormat(virDomainPtr dom, goto endjob; priv = vm->privateData; - priv->job.current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP; + privJobCurrent = priv->job.current->privateData; + privJobCurrent->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. */ @@ -12423,28 +12430,30 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn, static int qemuDomainGetJobInfoMigrationStats(virQEMUDriver *driver, virDomainObj *vm, - qemuDomainJobInfo *jobInfo) + virDomainJobData *jobData) { qemuDomainObjPrivate *priv = vm->privateData; + qemuDomainJobDataPrivate *privStats = jobData->privateData; + bool events = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT); - if (jobInfo->status == QEMU_DOMAIN_JOB_STATUS_ACTIVE || - jobInfo->status == QEMU_DOMAIN_JOB_STATUS_MIGRATING || - jobInfo->status == QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED || - jobInfo->status == QEMU_DOMAIN_JOB_STATUS_POSTCOPY) { + if (jobData->status == VIR_DOMAIN_JOB_STATUS_ACTIVE || + jobData->status == VIR_DOMAIN_JOB_STATUS_MIGRATING || + jobData->status == VIR_DOMAIN_JOB_STATUS_HYPERVISOR_COMPLETED || + jobData->status == VIR_DOMAIN_JOB_STATUS_POSTCOPY) { if (events && - jobInfo->status != QEMU_DOMAIN_JOB_STATUS_ACTIVE && + jobData->status != VIR_DOMAIN_JOB_STATUS_ACTIVE && qemuMigrationAnyFetchStats(driver, vm, QEMU_ASYNC_JOB_NONE, - jobInfo, NULL) < 0) + jobData, NULL) < 0) return -1; - if (jobInfo->status == QEMU_DOMAIN_JOB_STATUS_ACTIVE && - jobInfo->statsType == QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION && + if (jobData->status == VIR_DOMAIN_JOB_STATUS_ACTIVE && + privStats->statsType == QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION && qemuMigrationSrcFetchMirrorStats(driver, vm, QEMU_ASYNC_JOB_NONE, - jobInfo) < 0) + jobData) < 0) return -1; - if (qemuDomainJobInfoUpdateTime(jobInfo) < 0) + if (qemuDomainJobDataUpdateTime(jobData) < 0) return -1; } @@ -12455,9 +12464,10 @@ qemuDomainGetJobInfoMigrationStats(virQEMUDriver *driver, static int qemuDomainGetJobInfoDumpStats(virQEMUDriver *driver, virDomainObj *vm, - qemuDomainJobInfo *jobInfo) + virDomainJobData *jobData) { qemuDomainObjPrivate *priv = vm->privateData; + qemuDomainJobDataPrivate *privJob = jobData->privateData; qemuMonitorDumpStats stats = { 0 }; int rc; @@ -12470,33 +12480,33 @@ qemuDomainGetJobInfoDumpStats(virQEMUDriver *driver, if (rc < 0) return -1; - jobInfo->stats.dump = stats; + privJob->stats.dump = stats; - if (qemuDomainJobInfoUpdateTime(jobInfo) < 0) + if (qemuDomainJobDataUpdateTime(jobData) < 0) return -1; - switch (jobInfo->stats.dump.status) { + switch (privJob->stats.dump.status) { case QEMU_MONITOR_DUMP_STATUS_NONE: case QEMU_MONITOR_DUMP_STATUS_FAILED: case QEMU_MONITOR_DUMP_STATUS_LAST: virReportError(VIR_ERR_OPERATION_FAILED, _("dump query failed, status=%d"), - jobInfo->stats.dump.status); + privJob->stats.dump.status); return -1; break; case QEMU_MONITOR_DUMP_STATUS_ACTIVE: - jobInfo->status = QEMU_DOMAIN_JOB_STATUS_ACTIVE; + jobData->status = VIR_DOMAIN_JOB_STATUS_ACTIVE; VIR_DEBUG("dump active, bytes written='%llu' remaining='%llu'", - jobInfo->stats.dump.completed, - jobInfo->stats.dump.total - - jobInfo->stats.dump.completed); + privJob->stats.dump.completed, + privJob->stats.dump.total - + privJob->stats.dump.completed); break; case QEMU_MONITOR_DUMP_STATUS_COMPLETED: - jobInfo->status = QEMU_DOMAIN_JOB_STATUS_COMPLETED; + jobData->status = VIR_DOMAIN_JOB_STATUS_COMPLETED; VIR_DEBUG("dump completed, bytes written='%llu'", - jobInfo->stats.dump.completed); + privJob->stats.dump.completed); break; } @@ -12508,16 +12518,17 @@ static int qemuDomainGetJobStatsInternal(virQEMUDriver *driver, virDomainObj *vm, bool completed, - qemuDomainJobInfo **jobInfo) + virDomainJobData **jobData) { qemuDomainObjPrivate *priv = vm->privateData; + qemuDomainJobDataPrivate *privStats = NULL; int ret = -1; - *jobInfo = NULL; + *jobData = NULL; if (completed) { if (priv->job.completed && !priv->job.current) - *jobInfo = qemuDomainJobInfoCopy(priv->job.completed); + *jobData = virDomainJobDataCopy(priv->job.completed); return 0; } @@ -12539,22 +12550,24 @@ qemuDomainGetJobStatsInternal(virQEMUDriver *driver, ret = 0; goto cleanup; } - *jobInfo = qemuDomainJobInfoCopy(priv->job.current); + *jobData = virDomainJobDataCopy(priv->job.current); + + privStats = (*jobData)->privateData; - switch ((*jobInfo)->statsType) { + switch (privStats->statsType) { case QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION: case QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP: - if (qemuDomainGetJobInfoMigrationStats(driver, vm, *jobInfo) < 0) + if (qemuDomainGetJobInfoMigrationStats(driver, vm, *jobData) < 0) goto cleanup; break; case QEMU_DOMAIN_JOB_STATS_TYPE_MEMDUMP: - if (qemuDomainGetJobInfoDumpStats(driver, vm, *jobInfo) < 0) + if (qemuDomainGetJobInfoDumpStats(driver, vm, *jobData) < 0) goto cleanup; break; case QEMU_DOMAIN_JOB_STATS_TYPE_BACKUP: - if (qemuBackupGetJobInfoStats(driver, vm, *jobInfo) < 0) + if (qemuBackupGetJobInfoStats(driver, vm, *jobData) < 0) goto cleanup; break; @@ -12575,7 +12588,7 @@ qemuDomainGetJobInfo(virDomainPtr dom, virDomainJobInfoPtr info) { virQEMUDriver *driver = dom->conn->privateData; - g_autoptr(qemuDomainJobInfo) jobInfo = NULL; + g_autoptr(virDomainJobData) jobData = NULL; virDomainObj *vm; int ret = -1; @@ -12587,16 +12600,16 @@ qemuDomainGetJobInfo(virDomainPtr dom, if (virDomainGetJobInfoEnsureACL(dom->conn, vm->def) < 0) goto cleanup; - if (qemuDomainGetJobStatsInternal(driver, vm, false, &jobInfo) < 0) + if (qemuDomainGetJobStatsInternal(driver, vm, false, &jobData) < 0) goto cleanup; - if (!jobInfo || - jobInfo->status == QEMU_DOMAIN_JOB_STATUS_NONE) { + if (!jobData || + jobData->status == VIR_DOMAIN_JOB_STATUS_NONE) { ret = 0; goto cleanup; } - ret = qemuDomainJobInfoToInfo(jobInfo, info); + ret = qemuDomainJobDataToInfo(jobData, info); cleanup: virDomainObjEndAPI(&vm); @@ -12614,7 +12627,7 @@ qemuDomainGetJobStats(virDomainPtr dom, virQEMUDriver *driver = dom->conn->privateData; virDomainObj *vm; qemuDomainObjPrivate *priv; - g_autoptr(qemuDomainJobInfo) jobInfo = NULL; + g_autoptr(virDomainJobData) jobData = NULL; bool completed = !!(flags & VIR_DOMAIN_JOB_STATS_COMPLETED); int ret = -1; @@ -12628,11 +12641,11 @@ qemuDomainGetJobStats(virDomainPtr dom, goto cleanup; priv = vm->privateData; - if (qemuDomainGetJobStatsInternal(driver, vm, completed, &jobInfo) < 0) + if (qemuDomainGetJobStatsInternal(driver, vm, completed, &jobData) < 0) goto cleanup; - if (!jobInfo || - jobInfo->status == QEMU_DOMAIN_JOB_STATUS_NONE) { + if (!jobData || + jobData->status == VIR_DOMAIN_JOB_STATUS_NONE) { *type = VIR_DOMAIN_JOB_NONE; *params = NULL; *nparams = 0; @@ -12640,10 +12653,10 @@ qemuDomainGetJobStats(virDomainPtr dom, goto cleanup; } - ret = qemuDomainJobInfoToParams(jobInfo, type, params, nparams); + ret = qemuDomainJobDataToParams(jobData, type, params, nparams); if (completed && ret == 0 && !(flags & VIR_DOMAIN_JOB_STATS_KEEP_COMPLETED)) - g_clear_pointer(&priv->job.completed, qemuDomainJobInfoFree); + g_clear_pointer(&priv->job.completed, virDomainJobDataFree); cleanup: virDomainObjEndAPI(&vm); @@ -12709,7 +12722,7 @@ static int qemuDomainAbortJob(virDomainPtr dom) break; case QEMU_ASYNC_JOB_MIGRATION_OUT: - if ((priv->job.current->status == QEMU_DOMAIN_JOB_STATUS_POSTCOPY || + if ((priv->job.current->status == VIR_DOMAIN_JOB_STATUS_POSTCOPY || (virDomainObjGetState(vm, &reason) == VIR_DOMAIN_PAUSED && reason == VIR_DOMAIN_PAUSED_POSTCOPY))) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index a1e6a8d1b1..a48350be74 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -1199,7 +1199,7 @@ qemuMigrationSrcNBDStorageCopy(virQEMUDriver *driver, return -1; if (priv->job.abortJob) { - priv->job.current->status = QEMU_DOMAIN_JOB_STATUS_CANCELED; + priv->job.current->status = VIR_DOMAIN_JOB_STATUS_CANCELED; virReportError(VIR_ERR_OPERATION_ABORTED, _("%s: %s"), qemuDomainAsyncJobTypeToString(priv->job.asyncJob), _("canceled by client")); @@ -1622,35 +1622,37 @@ qemuMigrationSrcWaitForSpice(virDomainObj *vm) static void -qemuMigrationUpdateJobType(qemuDomainJobInfo *jobInfo) +qemuMigrationUpdateJobType(virDomainJobData *jobData) { - switch ((qemuMonitorMigrationStatus) jobInfo->stats.mig.status) { + qemuDomainJobDataPrivate *priv = jobData->privateData; + + switch ((qemuMonitorMigrationStatus) priv->stats.mig.status) { case QEMU_MONITOR_MIGRATION_STATUS_POSTCOPY: - jobInfo->status = QEMU_DOMAIN_JOB_STATUS_POSTCOPY; + jobData->status = VIR_DOMAIN_JOB_STATUS_POSTCOPY; break; case QEMU_MONITOR_MIGRATION_STATUS_COMPLETED: - jobInfo->status = QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED; + jobData->status = VIR_DOMAIN_JOB_STATUS_HYPERVISOR_COMPLETED; break; case QEMU_MONITOR_MIGRATION_STATUS_INACTIVE: - jobInfo->status = QEMU_DOMAIN_JOB_STATUS_NONE; + jobData->status = VIR_DOMAIN_JOB_STATUS_NONE; break; case QEMU_MONITOR_MIGRATION_STATUS_ERROR: - jobInfo->status = QEMU_DOMAIN_JOB_STATUS_FAILED; + jobData->status = VIR_DOMAIN_JOB_STATUS_FAILED; break; case QEMU_MONITOR_MIGRATION_STATUS_CANCELLED: - jobInfo->status = QEMU_DOMAIN_JOB_STATUS_CANCELED; + jobData->status = VIR_DOMAIN_JOB_STATUS_CANCELED; break; case QEMU_MONITOR_MIGRATION_STATUS_PRE_SWITCHOVER: - jobInfo->status = QEMU_DOMAIN_JOB_STATUS_PAUSED; + jobData->status = VIR_DOMAIN_JOB_STATUS_PAUSED; break; case QEMU_MONITOR_MIGRATION_STATUS_DEVICE: - jobInfo->status = QEMU_DOMAIN_JOB_STATUS_MIGRATING; + jobData->status = VIR_DOMAIN_JOB_STATUS_MIGRATING; break; case QEMU_MONITOR_MIGRATION_STATUS_SETUP: @@ -1667,11 +1669,12 @@ int qemuMigrationAnyFetchStats(virQEMUDriver *driver, virDomainObj *vm, qemuDomainAsyncJob asyncJob, - qemuDomainJobInfo *jobInfo, + virDomainJobData *jobData, char **error) { qemuDomainObjPrivate *priv = vm->privateData; qemuMonitorMigrationStats stats; + qemuDomainJobDataPrivate *privJob = jobData->privateData; int rv; if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) @@ -1683,7 +1686,7 @@ qemuMigrationAnyFetchStats(virQEMUDriver *driver, if (rv < 0) return -1; - jobInfo->stats.mig = stats; + privJob->stats.mig = stats; return 0; } @@ -1724,41 +1727,42 @@ qemuMigrationJobCheckStatus(virQEMUDriver *driver, qemuDomainAsyncJob asyncJob) { qemuDomainObjPrivate *priv = vm->privateData; - qemuDomainJobInfo *jobInfo = priv->job.current; + virDomainJobData *jobData = priv->job.current; + qemuDomainJobDataPrivate *privJob = jobData->privateData; g_autofree char *error = NULL; bool events = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT); if (!events || - jobInfo->stats.mig.status == QEMU_MONITOR_MIGRATION_STATUS_ERROR) { - if (qemuMigrationAnyFetchStats(driver, vm, asyncJob, jobInfo, &error) < 0) + privJob->stats.mig.status == QEMU_MONITOR_MIGRATION_STATUS_ERROR) { + if (qemuMigrationAnyFetchStats(driver, vm, asyncJob, jobData, &error) < 0) return -1; } - qemuMigrationUpdateJobType(jobInfo); + qemuMigrationUpdateJobType(jobData); - switch (jobInfo->status) { - case QEMU_DOMAIN_JOB_STATUS_NONE: + switch (jobData->status) { + case VIR_DOMAIN_JOB_STATUS_NONE: virReportError(VIR_ERR_OPERATION_FAILED, _("%s: %s"), qemuMigrationJobName(vm), _("is not active")); return -1; - case QEMU_DOMAIN_JOB_STATUS_FAILED: + case VIR_DOMAIN_JOB_STATUS_FAILED: virReportError(VIR_ERR_OPERATION_FAILED, _("%s: %s"), qemuMigrationJobName(vm), error ? error : _("unexpectedly failed")); return -1; - case QEMU_DOMAIN_JOB_STATUS_CANCELED: + case VIR_DOMAIN_JOB_STATUS_CANCELED: virReportError(VIR_ERR_OPERATION_ABORTED, _("%s: %s"), qemuMigrationJobName(vm), _("canceled by client")); return -1; - case QEMU_DOMAIN_JOB_STATUS_COMPLETED: - 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: + case VIR_DOMAIN_JOB_STATUS_COMPLETED: + case VIR_DOMAIN_JOB_STATUS_ACTIVE: + case VIR_DOMAIN_JOB_STATUS_MIGRATING: + case VIR_DOMAIN_JOB_STATUS_HYPERVISOR_COMPLETED: + case VIR_DOMAIN_JOB_STATUS_POSTCOPY: + case VIR_DOMAIN_JOB_STATUS_PAUSED: break; } @@ -1789,7 +1793,7 @@ qemuMigrationAnyCompleted(virQEMUDriver *driver, unsigned int flags) { qemuDomainObjPrivate *priv = vm->privateData; - qemuDomainJobInfo *jobInfo = priv->job.current; + virDomainJobData *jobData = priv->job.current; int pauseReason; if (qemuMigrationJobCheckStatus(driver, vm, asyncJob) < 0) @@ -1819,7 +1823,7 @@ qemuMigrationAnyCompleted(virQEMUDriver *driver, * wait again for the real end of the migration. */ if (flags & QEMU_MIGRATION_COMPLETED_PRE_SWITCHOVER && - jobInfo->status == QEMU_DOMAIN_JOB_STATUS_PAUSED) { + jobData->status == VIR_DOMAIN_JOB_STATUS_PAUSED) { VIR_DEBUG("Migration paused before switchover"); return 1; } @@ -1829,38 +1833,38 @@ qemuMigrationAnyCompleted(virQEMUDriver *driver, * will continue waiting until the migrate state changes to completed. */ if (flags & QEMU_MIGRATION_COMPLETED_POSTCOPY && - jobInfo->status == QEMU_DOMAIN_JOB_STATUS_POSTCOPY) { + jobData->status == VIR_DOMAIN_JOB_STATUS_POSTCOPY) { VIR_DEBUG("Migration switched to post-copy"); return 1; } - if (jobInfo->status == QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED) + if (jobData->status == VIR_DOMAIN_JOB_STATUS_HYPERVISOR_COMPLETED) return 1; else return 0; error: - switch (jobInfo->status) { - case QEMU_DOMAIN_JOB_STATUS_MIGRATING: - case QEMU_DOMAIN_JOB_STATUS_POSTCOPY: - case QEMU_DOMAIN_JOB_STATUS_PAUSED: + switch (jobData->status) { + case VIR_DOMAIN_JOB_STATUS_MIGRATING: + case VIR_DOMAIN_JOB_STATUS_POSTCOPY: + case VIR_DOMAIN_JOB_STATUS_PAUSED: /* The migration was aborted by us rather than QEMU itself. */ - jobInfo->status = QEMU_DOMAIN_JOB_STATUS_FAILED; + jobData->status = VIR_DOMAIN_JOB_STATUS_FAILED; return -2; - case QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED: + case VIR_DOMAIN_JOB_STATUS_HYPERVISOR_COMPLETED: /* Something failed after QEMU already finished the migration. */ - jobInfo->status = QEMU_DOMAIN_JOB_STATUS_FAILED; + jobData->status = VIR_DOMAIN_JOB_STATUS_FAILED; return -1; - case QEMU_DOMAIN_JOB_STATUS_FAILED: - case QEMU_DOMAIN_JOB_STATUS_CANCELED: + case VIR_DOMAIN_JOB_STATUS_FAILED: + case VIR_DOMAIN_JOB_STATUS_CANCELED: /* QEMU aborted the migration. */ return -1; - case QEMU_DOMAIN_JOB_STATUS_ACTIVE: - case QEMU_DOMAIN_JOB_STATUS_COMPLETED: - case QEMU_DOMAIN_JOB_STATUS_NONE: + case VIR_DOMAIN_JOB_STATUS_ACTIVE: + case VIR_DOMAIN_JOB_STATUS_COMPLETED: + case VIR_DOMAIN_JOB_STATUS_NONE: /* Impossible. */ break; } @@ -1880,11 +1884,11 @@ qemuMigrationSrcWaitForCompletion(virQEMUDriver *driver, unsigned int flags) { qemuDomainObjPrivate *priv = vm->privateData; - qemuDomainJobInfo *jobInfo = priv->job.current; + virDomainJobData *jobData = priv->job.current; bool events = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT); int rv; - jobInfo->status = QEMU_DOMAIN_JOB_STATUS_MIGRATING; + jobData->status = VIR_DOMAIN_JOB_STATUS_MIGRATING; while ((rv = qemuMigrationAnyCompleted(driver, vm, asyncJob, dconn, flags)) != 1) { @@ -1894,7 +1898,7 @@ qemuMigrationSrcWaitForCompletion(virQEMUDriver *driver, if (events) { if (virDomainObjWait(vm) < 0) { if (virDomainObjIsActive(vm)) - jobInfo->status = QEMU_DOMAIN_JOB_STATUS_FAILED; + jobData->status = VIR_DOMAIN_JOB_STATUS_FAILED; return -2; } } else { @@ -1908,17 +1912,17 @@ qemuMigrationSrcWaitForCompletion(virQEMUDriver *driver, } if (events) - ignore_value(qemuMigrationAnyFetchStats(driver, vm, asyncJob, jobInfo, NULL)); + ignore_value(qemuMigrationAnyFetchStats(driver, vm, asyncJob, jobData, NULL)); - 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; + qemuDomainJobDataUpdateTime(jobData); + qemuDomainJobDataUpdateDowntime(jobData); + g_clear_pointer(&priv->job.completed, virDomainJobDataFree); + priv->job.completed = virDomainJobDataCopy(jobData); + priv->job.completed->status = VIR_DOMAIN_JOB_STATUS_COMPLETED; if (asyncJob != QEMU_ASYNC_JOB_MIGRATION_OUT && - jobInfo->status == QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED) - jobInfo->status = QEMU_DOMAIN_JOB_STATUS_COMPLETED; + jobData->status == VIR_DOMAIN_JOB_STATUS_HYPERVISOR_COMPLETED) + jobData->status = VIR_DOMAIN_JOB_STATUS_COMPLETED; return 0; } @@ -3383,7 +3387,7 @@ qemuMigrationSrcConfirmPhase(virQEMUDriver *driver, virObjectEvent *event; qemuDomainObjPrivate *priv = vm->privateData; qemuDomainJobPrivate *jobPriv = priv->job.privateData; - qemuDomainJobInfo *jobInfo = NULL; + virDomainJobData *jobData = NULL; VIR_DEBUG("driver=%p, vm=%p, cookiein=%s, cookieinlen=%d, " "flags=0x%x, retcode=%d", @@ -3403,13 +3407,15 @@ qemuMigrationSrcConfirmPhase(virQEMUDriver *driver, return -1; if (retcode == 0) - jobInfo = priv->job.completed; + jobData = priv->job.completed; else - g_clear_pointer(&priv->job.completed, qemuDomainJobInfoFree); + g_clear_pointer(&priv->job.completed, virDomainJobDataFree); /* Update times with the values sent by the destination daemon */ - if (mig->jobInfo && jobInfo) { + if (mig->jobData && jobData) { int reason; + qemuDomainJobDataPrivate *privJob = jobData->privateData; + qemuDomainJobDataPrivate *privMigJob = mig->jobData->privateData; /* We need to refresh migration statistics after a completed post-copy * migration since priv->job.completed contains obsolete data from the @@ -3418,14 +3424,14 @@ qemuMigrationSrcConfirmPhase(virQEMUDriver *driver, if (virDomainObjGetState(vm, &reason) == VIR_DOMAIN_PAUSED && reason == VIR_DOMAIN_PAUSED_POSTCOPY && qemuMigrationAnyFetchStats(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, - jobInfo, NULL) < 0) + jobData, NULL) < 0) VIR_WARN("Could not refresh migration statistics"); - qemuDomainJobInfoUpdateTime(jobInfo); - jobInfo->timeDeltaSet = mig->jobInfo->timeDeltaSet; - jobInfo->timeDelta = mig->jobInfo->timeDelta; - jobInfo->stats.mig.downtime_set = mig->jobInfo->stats.mig.downtime_set; - jobInfo->stats.mig.downtime = mig->jobInfo->stats.mig.downtime; + qemuDomainJobDataUpdateTime(jobData); + jobData->timeDeltaSet = mig->jobData->timeDeltaSet; + jobData->timeDelta = mig->jobData->timeDelta; + privJob->stats.mig.downtime_set = privMigJob->stats.mig.downtime_set; + privJob->stats.mig.downtime = privMigJob->stats.mig.downtime; } if (flags & VIR_MIGRATE_OFFLINE) @@ -4194,7 +4200,7 @@ qemuMigrationSrcRun(virQEMUDriver *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; + priv->job.current->status = VIR_DOMAIN_JOB_STATUS_CANCELED; virReportError(VIR_ERR_OPERATION_ABORTED, _("%s: %s"), qemuDomainAsyncJobTypeToString(priv->job.asyncJob), _("canceled by client")); @@ -4309,7 +4315,7 @@ qemuMigrationSrcRun(virQEMUDriver *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 (priv->job.current->status == VIR_DOMAIN_JOB_STATUS_PAUSED) { if (qemuMigrationSrcContinue(driver, vm, QEMU_MONITOR_MIGRATION_STATUS_PRE_SWITCHOVER, QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) @@ -4339,8 +4345,8 @@ qemuMigrationSrcRun(virQEMUDriver *driver, if (priv->job.completed) { priv->job.completed->stopped = priv->job.current->stopped; - qemuDomainJobInfoUpdateTime(priv->job.completed); - qemuDomainJobInfoUpdateDowntime(priv->job.completed); + qemuDomainJobDataUpdateTime(priv->job.completed); + qemuDomainJobDataUpdateDowntime(priv->job.completed); ignore_value(virTimeMillisNow(&priv->job.completed->sent)); } @@ -4370,7 +4376,7 @@ qemuMigrationSrcRun(virQEMUDriver *driver, if (virDomainObjIsActive(vm)) { if (cancel && - priv->job.current->status != QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED && + priv->job.current->status != VIR_DOMAIN_JOB_STATUS_HYPERVISOR_COMPLETED && qemuDomainObjEnterMonitorAsync(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT) == 0) { qemuMonitorMigrateCancel(priv->mon); @@ -4385,8 +4391,8 @@ qemuMigrationSrcRun(virQEMUDriver *driver, qemuMigrationSrcCancelRemoveTempBitmaps(vm, QEMU_ASYNC_JOB_MIGRATION_OUT); - if (priv->job.current->status != QEMU_DOMAIN_JOB_STATUS_CANCELED) - priv->job.current->status = QEMU_DOMAIN_JOB_STATUS_FAILED; + if (priv->job.current->status != VIR_DOMAIN_JOB_STATUS_CANCELED) + priv->job.current->status = VIR_DOMAIN_JOB_STATUS_FAILED; } if (iothread) @@ -5620,7 +5626,7 @@ qemuMigrationDstFinish(virQEMUDriver *driver, unsigned short port; unsigned long long timeReceived = 0; virObjectEvent *event; - qemuDomainJobInfo *jobInfo = NULL; + virDomainJobData *jobData = NULL; bool inPostCopy = false; bool doKill = true; @@ -5644,7 +5650,7 @@ qemuMigrationDstFinish(virQEMUDriver *driver, : QEMU_MIGRATION_PHASE_FINISH2); qemuDomainCleanupRemove(vm, qemuMigrationDstPrepareCleanup); - g_clear_pointer(&priv->job.completed, qemuDomainJobInfoFree); + g_clear_pointer(&priv->job.completed, virDomainJobDataFree); cookie_flags = QEMU_MIGRATION_COOKIE_NETWORK | QEMU_MIGRATION_COOKIE_STATS | @@ -5736,7 +5742,7 @@ qemuMigrationDstFinish(virQEMUDriver *driver, goto endjob; } - if (priv->job.current->status == QEMU_DOMAIN_JOB_STATUS_POSTCOPY) + if (priv->job.current->status == VIR_DOMAIN_JOB_STATUS_POSTCOPY) inPostCopy = true; if (!(flags & VIR_MIGRATE_PAUSED)) { @@ -5772,16 +5778,16 @@ qemuMigrationDstFinish(virQEMUDriver *driver, doKill = false; } - if (mig->jobInfo) { - jobInfo = g_steal_pointer(&mig->jobInfo); + if (mig->jobData) { + jobData = g_steal_pointer(&mig->jobData); - if (jobInfo->sent && timeReceived) { - jobInfo->timeDelta = timeReceived - jobInfo->sent; - jobInfo->received = timeReceived; - jobInfo->timeDeltaSet = true; + if (jobData->sent && timeReceived) { + jobData->timeDelta = timeReceived - jobData->sent; + jobData->received = timeReceived; + jobData->timeDeltaSet = true; } - qemuDomainJobInfoUpdateTime(jobInfo); - qemuDomainJobInfoUpdateDowntime(jobInfo); + qemuDomainJobDataUpdateTime(jobData); + qemuDomainJobDataUpdateDowntime(jobData); } if (inPostCopy) { @@ -5846,10 +5852,12 @@ qemuMigrationDstFinish(virQEMUDriver *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; + if (jobData) { + qemuDomainJobDataPrivate *privJob = jobData->privateData; + + priv->job.completed = g_steal_pointer(&jobData); + priv->job.completed->status = VIR_DOMAIN_JOB_STATUS_COMPLETED; + privJob->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION; } if (qemuMigrationCookieFormat(mig, driver, vm, @@ -5862,7 +5870,7 @@ qemuMigrationDstFinish(virQEMUDriver *driver, * is obsolete anyway. */ if (inPostCopy) - g_clear_pointer(&priv->job.completed, qemuDomainJobInfoFree); + g_clear_pointer(&priv->job.completed, virDomainJobDataFree); } qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN, @@ -5873,7 +5881,7 @@ qemuMigrationDstFinish(virQEMUDriver *driver, qemuDomainRemoveInactiveJob(driver, vm); cleanup: - g_clear_pointer(&jobInfo, qemuDomainJobInfoFree); + g_clear_pointer(&jobData, virDomainJobDataFree); virPortAllocatorRelease(port); if (priv->mon) qemuMonitorSetDomainLog(priv->mon, NULL, NULL, NULL); @@ -6091,6 +6099,7 @@ qemuMigrationJobStart(virQEMUDriver *driver, unsigned long apiFlags) { qemuDomainObjPrivate *priv = vm->privateData; + qemuDomainJobDataPrivate *privJob = priv->job.current->privateData; virDomainJobOperation op; unsigned long long mask; @@ -6107,7 +6116,7 @@ qemuMigrationJobStart(virQEMUDriver *driver, if (qemuDomainObjBeginAsyncJob(driver, vm, job, op, apiFlags) < 0) return -1; - priv->job.current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION; + privJob->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION; qemuDomainObjSetAsyncJobMask(vm, mask); return 0; @@ -6227,13 +6236,14 @@ int qemuMigrationSrcFetchMirrorStats(virQEMUDriver *driver, virDomainObj *vm, qemuDomainAsyncJob asyncJob, - qemuDomainJobInfo *jobInfo) + virDomainJobData *jobData) { size_t i; qemuDomainObjPrivate *priv = vm->privateData; + qemuDomainJobDataPrivate *privJob = jobData->privateData; bool nbd = false; g_autoptr(GHashTable) blockinfo = NULL; - qemuDomainMirrorStats *stats = &jobInfo->mirrorStats; + qemuDomainMirrorStats *stats = &privJob->mirrorStats; for (i = 0; i < vm->def->ndisks; i++) { virDomainDiskDef *disk = vm->def->disks[i]; diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h index b233358a51..6b169f73c7 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -221,7 +221,7 @@ int qemuMigrationAnyFetchStats(virQEMUDriver *driver, virDomainObj *vm, qemuDomainAsyncJob asyncJob, - qemuDomainJobInfo *jobInfo, + virDomainJobData *jobData, char **error); int @@ -258,4 +258,4 @@ int qemuMigrationSrcFetchMirrorStats(virQEMUDriver *driver, virDomainObj *vm, qemuDomainAsyncJob asyncJob, - qemuDomainJobInfo *jobInfo); + virDomainJobData *jobData); diff --git a/src/qemu/qemu_migration_cookie.c b/src/qemu/qemu_migration_cookie.c index ba05a5a07f..0b51676c24 100644 --- a/src/qemu/qemu_migration_cookie.c +++ b/src/qemu/qemu_migration_cookie.c @@ -166,7 +166,7 @@ qemuMigrationCookieFree(qemuMigrationCookie *mig) g_free(mig->name); g_free(mig->lockState); g_free(mig->lockDriver); - g_clear_pointer(&mig->jobInfo, qemuDomainJobInfoFree); + g_clear_pointer(&mig->jobData, virDomainJobDataFree); virCPUDefFree(mig->cpu); qemuMigrationCookieCapsFree(mig->caps); if (mig->blockDirtyBitmaps) @@ -531,8 +531,8 @@ qemuMigrationCookieAddStatistics(qemuMigrationCookie *mig, if (!priv->job.completed) return 0; - g_clear_pointer(&mig->jobInfo, qemuDomainJobInfoFree); - mig->jobInfo = qemuDomainJobInfoCopy(priv->job.completed); + g_clear_pointer(&mig->jobData, virDomainJobDataFree); + mig->jobData = virDomainJobDataCopy(priv->job.completed); mig->flags |= QEMU_MIGRATION_COOKIE_STATS; @@ -632,22 +632,23 @@ qemuMigrationCookieNetworkXMLFormat(virBuffer *buf, static void qemuMigrationCookieStatisticsXMLFormat(virBuffer *buf, - qemuDomainJobInfo *jobInfo) + virDomainJobData *jobData) { - qemuMonitorMigrationStats *stats = &jobInfo->stats.mig; + qemuDomainJobDataPrivate *priv = jobData->privateData; + qemuMonitorMigrationStats *stats = &priv->stats.mig; virBufferAddLit(buf, "<statistics>\n"); virBufferAdjustIndent(buf, 2); - virBufferAsprintf(buf, "<started>%llu</started>\n", jobInfo->started); - virBufferAsprintf(buf, "<stopped>%llu</stopped>\n", jobInfo->stopped); - virBufferAsprintf(buf, "<sent>%llu</sent>\n", jobInfo->sent); - if (jobInfo->timeDeltaSet) - virBufferAsprintf(buf, "<delta>%lld</delta>\n", jobInfo->timeDelta); + virBufferAsprintf(buf, "<started>%llu</started>\n", jobData->started); + virBufferAsprintf(buf, "<stopped>%llu</stopped>\n", jobData->stopped); + virBufferAsprintf(buf, "<sent>%llu</sent>\n", jobData->sent); + if (jobData->timeDeltaSet) + virBufferAsprintf(buf, "<delta>%lld</delta>\n", jobData->timeDelta); virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n", VIR_DOMAIN_JOB_TIME_ELAPSED, - jobInfo->timeElapsed); + jobData->timeElapsed); if (stats->downtime_set) virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n", VIR_DOMAIN_JOB_DOWNTIME, @@ -884,8 +885,8 @@ qemuMigrationCookieXMLFormat(virQEMUDriver *driver, if ((mig->flags & QEMU_MIGRATION_COOKIE_NBD) && mig->nbd) qemuMigrationCookieNBDXMLFormat(mig->nbd, buf); - if (mig->flags & QEMU_MIGRATION_COOKIE_STATS && mig->jobInfo) - qemuMigrationCookieStatisticsXMLFormat(buf, mig->jobInfo); + if (mig->flags & QEMU_MIGRATION_COOKIE_STATS && mig->jobData) + qemuMigrationCookieStatisticsXMLFormat(buf, mig->jobData); if (mig->flags & QEMU_MIGRATION_COOKIE_CPU && mig->cpu) virCPUDefFormatBufFull(buf, mig->cpu, NULL); @@ -1031,29 +1032,30 @@ qemuMigrationCookieNBDXMLParse(xmlXPathContextPtr ctxt) } -static qemuDomainJobInfo * +static virDomainJobData * qemuMigrationCookieStatisticsXMLParse(xmlXPathContextPtr ctxt) { - qemuDomainJobInfo *jobInfo = NULL; + virDomainJobData *jobData = NULL; qemuMonitorMigrationStats *stats; + qemuDomainJobDataPrivate *priv = NULL; VIR_XPATH_NODE_AUTORESTORE(ctxt) if (!(ctxt->node = virXPathNode("./statistics", ctxt))) return NULL; - jobInfo = g_new0(qemuDomainJobInfo, 1); + jobData = virDomainJobDataInit(&qemuJobDataPrivateDataCallbacks); + priv = jobData->privateData; + stats = &priv->stats.mig; + jobData->status = VIR_DOMAIN_JOB_STATUS_COMPLETED; - stats = &jobInfo->stats.mig; - jobInfo->status = QEMU_DOMAIN_JOB_STATUS_COMPLETED; - - virXPathULongLong("string(./started[1])", ctxt, &jobInfo->started); - virXPathULongLong("string(./stopped[1])", ctxt, &jobInfo->stopped); - virXPathULongLong("string(./sent[1])", ctxt, &jobInfo->sent); - if (virXPathLongLong("string(./delta[1])", ctxt, &jobInfo->timeDelta) == 0) - jobInfo->timeDeltaSet = true; + virXPathULongLong("string(./started[1])", ctxt, &jobData->started); + virXPathULongLong("string(./stopped[1])", ctxt, &jobData->stopped); + virXPathULongLong("string(./sent[1])", ctxt, &jobData->sent); + if (virXPathLongLong("string(./delta[1])", ctxt, &jobData->timeDelta) == 0) + jobData->timeDeltaSet = true; virXPathULongLong("string(./" VIR_DOMAIN_JOB_TIME_ELAPSED "[1])", - ctxt, &jobInfo->timeElapsed); + ctxt, &jobData->timeElapsed); if (virXPathULongLong("string(./" VIR_DOMAIN_JOB_DOWNTIME "[1])", ctxt, &stats->downtime) == 0) @@ -1113,7 +1115,7 @@ qemuMigrationCookieStatisticsXMLParse(xmlXPathContextPtr ctxt) virXPathInt("string(./" VIR_DOMAIN_JOB_AUTO_CONVERGE_THROTTLE "[1])", ctxt, &stats->cpu_throttle_percentage); - return jobInfo; + return jobData; } @@ -1385,7 +1387,7 @@ qemuMigrationCookieXMLParse(qemuMigrationCookie *mig, if (flags & QEMU_MIGRATION_COOKIE_STATS && virXPathBoolean("boolean(./statistics)", ctxt) && - (!(mig->jobInfo = qemuMigrationCookieStatisticsXMLParse(ctxt)))) + (!(mig->jobData = qemuMigrationCookieStatisticsXMLParse(ctxt)))) return -1; if (flags & QEMU_MIGRATION_COOKIE_CPU && @@ -1546,8 +1548,8 @@ qemuMigrationCookieParse(virQEMUDriver *driver, } } - if (flags & QEMU_MIGRATION_COOKIE_STATS && mig->jobInfo && priv->job.current) - mig->jobInfo->operation = priv->job.current->operation; + if (flags & QEMU_MIGRATION_COOKIE_STATS && mig->jobData && priv->job.current) + mig->jobData->operation = priv->job.current->operation; return g_steal_pointer(&mig); } diff --git a/src/qemu/qemu_migration_cookie.h b/src/qemu/qemu_migration_cookie.h index 1726e5f2da..d9e1d949a8 100644 --- a/src/qemu/qemu_migration_cookie.h +++ b/src/qemu/qemu_migration_cookie.h @@ -162,7 +162,7 @@ struct _qemuMigrationCookie { qemuMigrationCookieNBD *nbd; /* If (flags & QEMU_MIGRATION_COOKIE_STATS) */ - qemuDomainJobInfo *jobInfo; + virDomainJobData *jobData; /* If flags & QEMU_MIGRATION_COOKIE_CPU */ virCPUDef *cpu; diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 8fccf6b760..4b921c1e35 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -651,7 +651,7 @@ qemuProcessHandleStop(qemuMonitor *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 (priv->job.current->status == VIR_DOMAIN_JOB_STATUS_POSTCOPY) reason = VIR_DOMAIN_PAUSED_POSTCOPY; else reason = VIR_DOMAIN_PAUSED_MIGRATION; @@ -1545,6 +1545,7 @@ qemuProcessHandleMigrationStatus(qemuMonitor *mon G_GNUC_UNUSED, void *opaque) { qemuDomainObjPrivate *priv; + qemuDomainJobDataPrivate *privJob = NULL; virQEMUDriver *driver = opaque; virObjectEvent *event = NULL; int reason; @@ -1561,7 +1562,9 @@ qemuProcessHandleMigrationStatus(qemuMonitor *mon G_GNUC_UNUSED, goto cleanup; } - priv->job.current->stats.mig.status = status; + privJob = priv->job.current->privateData; + + privJob->stats.mig.status = status; virDomainObjBroadcast(vm); if (status == QEMU_MONITOR_MIGRATION_STATUS_POSTCOPY && @@ -1623,6 +1626,7 @@ qemuProcessHandleDumpCompleted(qemuMonitor *mon G_GNUC_UNUSED, { qemuDomainObjPrivate *priv; qemuDomainJobPrivate *jobPriv; + qemuDomainJobDataPrivate *privJobCurrent = NULL; virObjectLock(vm); @@ -1631,18 +1635,19 @@ qemuProcessHandleDumpCompleted(qemuMonitor *mon G_GNUC_UNUSED, priv = vm->privateData; jobPriv = priv->job.privateData; + privJobCurrent = priv->job.current->privateData; if (priv->job.asyncJob == QEMU_ASYNC_JOB_NONE) { VIR_DEBUG("got DUMP_COMPLETED event without a dump_completed job"); goto cleanup; } jobPriv->dumpCompleted = true; - priv->job.current->stats.dump = *stats; + privJobCurrent->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; + privJobCurrent->stats.dump.status = QEMU_MONITOR_DUMP_STATUS_FAILED; } virDomainObjBroadcast(vm); @@ -3592,6 +3597,7 @@ qemuProcessRecoverJob(virQEMUDriver *driver, unsigned int *stopFlags) { qemuDomainObjPrivate *priv = vm->privateData; + qemuDomainJobDataPrivate *privDataJobCurrent = NULL; virDomainState state; int reason; unsigned long long now; @@ -3659,10 +3665,12 @@ qemuProcessRecoverJob(virQEMUDriver *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 = virDomainJobDataInit(&qemuJobDataPrivateDataCallbacks); + privDataJobCurrent = priv->job.current->privateData; + 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; + privDataJobCurrent->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_BACKUP; + priv->job.current->status = VIR_DOMAIN_JOB_STATUS_ACTIVE; priv->job.current->started = now; break; @@ -8304,7 +8312,7 @@ void qemuProcessStop(virQEMUDriver *driver, /* clean up a possible backup job */ if (priv->backup) - qemuBackupJobTerminate(vm, QEMU_DOMAIN_JOB_STATUS_CANCELED); + qemuBackupJobTerminate(vm, VIR_DOMAIN_JOB_STATUS_CANCELED); /* Do this explicitly after vm->pid is reset so that security drivers don't * try to enter the domain's namespace which is non-existent by now as qemu diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c index a99f1246e0..98080ac5f8 100644 --- a/src/qemu/qemu_snapshot.c +++ b/src/qemu/qemu_snapshot.c @@ -1414,11 +1414,13 @@ qemuSnapshotCreateActiveExternal(virQEMUDriver *driver, /* do the memory snapshot if necessary */ if (memory) { + qemuDomainJobDataPrivate *privJobCurrent = priv->job.current->privateData; + /* check if migration is possible */ if (!qemuMigrationSrcIsAllowed(driver, vm, false, 0)) goto cleanup; - priv->job.current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_SAVEDUMP; + privJobCurrent->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 | -- 2.34.1