diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 4b65d87fd0..bbdfdc4e13 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -79,6 +79,42 @@ void qemuDomainEventQueue(struct qemud_driver *driver, } +static int +qemuDomainObjInitJob(qemuDomainObjPrivatePtr priv) +{ + memset(&priv->job, 0, sizeof(priv->job)); + + if (virCondInit(&priv->job.cond) < 0) + return -1; + + if (virCondInit(&priv->job.signalCond) < 0) { + ignore_value(virCondDestroy(&priv->job.cond)); + return -1; + } + + return 0; +} + +static void +qemuDomainObjResetJob(qemuDomainObjPrivatePtr priv) +{ + struct qemuDomainJobObj *job = &priv->job; + + job->active = QEMU_JOB_NONE; + job->start = 0; + memset(&job->info, 0, sizeof(job->info)); + job->signals = 0; + memset(&job->signalsData, 0, sizeof(job->signalsData)); +} + +static void +qemuDomainObjFreeJob(qemuDomainObjPrivatePtr priv) +{ + ignore_value(virCondDestroy(&priv->job.cond)); + ignore_value(virCondDestroy(&priv->job.signalCond)); +} + + static void *qemuDomainObjPrivateAlloc(void) { qemuDomainObjPrivatePtr priv; @@ -86,19 +122,10 @@ static void *qemuDomainObjPrivateAlloc(void) if (VIR_ALLOC(priv) < 0) return NULL; - if (virCondInit(&priv->jobCond) < 0) - goto initfail; - - if (virCondInit(&priv->signalCond) < 0) { - ignore_value(virCondDestroy(&priv->jobCond)); - goto initfail; - } + if (qemuDomainObjInitJob(priv) < 0) + VIR_FREE(priv); return priv; - -initfail: - VIR_FREE(priv); - return NULL; } static void qemuDomainObjPrivateFree(void *data) @@ -109,9 +136,8 @@ static void qemuDomainObjPrivateFree(void *data) qemuDomainPCIAddressSetFree(priv->pciaddrs); virDomainChrSourceDefFree(priv->monConfig); + qemuDomainObjFreeJob(priv); VIR_FREE(priv->vcpupids); - ignore_value(virCondDestroy(&priv->jobCond)); - ignore_value(virCondDestroy(&priv->signalCond)); VIR_FREE(priv->lockState); /* This should never be non-NULL if we get here, but just in case... */ @@ -473,6 +499,24 @@ void qemuDomainSetNamespaceHooks(virCapsPtr caps) caps->ns.href = qemuDomainDefNamespaceHref; } +void +qemuDomainObjSetJob(virDomainObjPtr obj, + enum qemuDomainJob job) +{ + qemuDomainObjPrivatePtr priv = obj->privateData; + + priv->job.active = job; +} + +void +qemuDomainObjDiscardJob(virDomainObjPtr obj) +{ + qemuDomainObjPrivatePtr priv = obj->privateData; + + qemuDomainObjResetJob(priv); + qemuDomainObjSetJob(obj, QEMU_JOB_NONE); +} + /* * obj must be locked before calling, qemud_driver must NOT be locked * @@ -498,8 +542,8 @@ int qemuDomainObjBeginJob(virDomainObjPtr obj) virDomainObjRef(obj); - while (priv->jobActive) { - if (virCondWaitUntil(&priv->jobCond, &obj->lock, then) < 0) { + while (priv->job.active) { + if (virCondWaitUntil(&priv->job.cond, &obj->lock, then) < 0) { /* Safe to ignore value since ref count was incremented above */ ignore_value(virDomainObjUnref(obj)); if (errno == ETIMEDOUT) @@ -511,11 +555,9 @@ int qemuDomainObjBeginJob(virDomainObjPtr obj) return -1; } } - priv->jobActive = QEMU_JOB_UNSPECIFIED; - priv->jobSignals = 0; - memset(&priv->jobSignalsData, 0, sizeof(priv->jobSignalsData)); - priv->jobStart = now; - memset(&priv->jobInfo, 0, sizeof(priv->jobInfo)); + qemuDomainObjResetJob(priv); + qemuDomainObjSetJob(obj, QEMU_JOB_UNSPECIFIED); + priv->job.start = now; return 0; } @@ -540,8 +582,8 @@ int qemuDomainObjBeginJobWithDriver(struct qemud_driver *driver, virDomainObjRef(obj); qemuDriverUnlock(driver); - while (priv->jobActive) { - if (virCondWaitUntil(&priv->jobCond, &obj->lock, then) < 0) { + while (priv->job.active) { + if (virCondWaitUntil(&priv->job.cond, &obj->lock, then) < 0) { if (errno == ETIMEDOUT) qemuReportError(VIR_ERR_OPERATION_TIMEOUT, "%s", _("cannot acquire state change lock")); @@ -556,11 +598,9 @@ int qemuDomainObjBeginJobWithDriver(struct qemud_driver *driver, return -1; } } - priv->jobActive = QEMU_JOB_UNSPECIFIED; - priv->jobSignals = 0; - memset(&priv->jobSignalsData, 0, sizeof(priv->jobSignalsData)); - priv->jobStart = now; - memset(&priv->jobInfo, 0, sizeof(priv->jobInfo)); + qemuDomainObjResetJob(priv); + qemuDomainObjSetJob(obj, QEMU_JOB_UNSPECIFIED); + priv->job.start = now; virDomainObjUnlock(obj); qemuDriverLock(driver); @@ -582,17 +622,13 @@ int qemuDomainObjEndJob(virDomainObjPtr obj) { qemuDomainObjPrivatePtr priv = obj->privateData; - priv->jobActive = QEMU_JOB_NONE; - priv->jobSignals = 0; - memset(&priv->jobSignalsData, 0, sizeof(priv->jobSignalsData)); - priv->jobStart = 0; - memset(&priv->jobInfo, 0, sizeof(priv->jobInfo)); - virCondSignal(&priv->jobCond); + qemuDomainObjResetJob(priv); + qemuDomainObjSetJob(obj, QEMU_JOB_NONE); + virCondSignal(&priv->job.cond); return virDomainObjUnref(obj); } - /* * obj must be locked before calling, qemud_driver must be unlocked * diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index f4647a0921..782e012296 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -68,19 +68,26 @@ struct qemuDomainJobSignalsData { int *infoRetCode; /* Return code for the blkinfo calls */ }; +struct qemuDomainJobObj { + virCond cond; /* Use in conjunction with main virDomainObjPtr lock */ + virCond signalCond; /* Use to coordinate the safe queries during migration */ + + enum qemuDomainJob active; /* Currently running job */ + + unsigned long long start; /* When the job started */ + virDomainJobInfo info; /* Progress data */ + + unsigned int signals; /* Signals for running job */ + struct qemuDomainJobSignalsData signalsData; /* Signal specific data */ +}; + typedef struct _qemuDomainPCIAddressSet qemuDomainPCIAddressSet; typedef qemuDomainPCIAddressSet *qemuDomainPCIAddressSetPtr; typedef struct _qemuDomainObjPrivate qemuDomainObjPrivate; typedef qemuDomainObjPrivate *qemuDomainObjPrivatePtr; struct _qemuDomainObjPrivate { - virCond jobCond; /* Use in conjunction with main virDomainObjPtr lock */ - virCond signalCond; /* Use to coordinate the safe queries during migration */ - enum qemuDomainJob jobActive; /* Currently running job */ - unsigned int jobSignals; /* Signals for running job */ - struct qemuDomainJobSignalsData jobSignalsData; /* Signal specific data */ - virDomainJobInfo jobInfo; - unsigned long long jobStart; + struct qemuDomainJobObj job; qemuMonitorPtr mon; virDomainChrSourceDefPtr monConfig; @@ -121,6 +128,10 @@ int qemuDomainObjBeginJob(virDomainObjPtr obj) ATTRIBUTE_RETURN_CHECK; int qemuDomainObjBeginJobWithDriver(struct qemud_driver *driver, virDomainObjPtr obj) ATTRIBUTE_RETURN_CHECK; int qemuDomainObjEndJob(virDomainObjPtr obj) ATTRIBUTE_RETURN_CHECK; + +void qemuDomainObjSetJob(virDomainObjPtr obj, enum qemuDomainJob job); +void qemuDomainObjDiscardJob(virDomainObjPtr obj); + void qemuDomainObjEnterMonitor(virDomainObjPtr obj); void qemuDomainObjExitMonitor(virDomainObjPtr obj); void qemuDomainObjEnterMonitorWithDriver(struct qemud_driver *driver, diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 0ea182d459..0e42fb77b7 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1348,11 +1348,11 @@ static int qemudDomainSuspend(virDomainPtr dom) { priv = vm->privateData; - if (priv->jobActive == QEMU_JOB_MIGRATION_OUT) { + if (priv->job.active == QEMU_JOB_MIGRATION_OUT) { if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_PAUSED) { VIR_DEBUG("Requesting domain pause on %s", vm->def->name); - priv->jobSignals |= QEMU_JOB_SIGNAL_SUSPEND; + priv->job.signals |= QEMU_JOB_SIGNAL_SUSPEND; } ret = 0; goto cleanup; @@ -1883,7 +1883,7 @@ static int qemudDomainGetInfo(virDomainPtr dom, if ((vm->def->memballoon != NULL) && (vm->def->memballoon->model == VIR_DOMAIN_MEMBALLOON_MODEL_NONE)) { info->memory = vm->def->mem.max_balloon; - } else if (!priv->jobActive) { + } else if (!priv->job.active) { if (qemuDomainObjBeginJob(vm) < 0) goto cleanup; if (!virDomainObjIsActive(vm)) @@ -1990,12 +1990,12 @@ qemuDomainGetControlInfo(virDomainPtr dom, if (priv->monError) { info->state = VIR_DOMAIN_CONTROL_ERROR; - } else if (priv->jobActive) { + } else if (priv->job.active) { if (!priv->monStart) { info->state = VIR_DOMAIN_CONTROL_JOB; if (virTimeMs(&info->stateTime) < 0) goto cleanup; - info->stateTime -= priv->jobStart; + info->stateTime -= priv->job.start; } else { info->state = VIR_DOMAIN_CONTROL_OCCUPIED; if (virTimeMs(&info->stateTime) < 0) @@ -2130,10 +2130,10 @@ static int qemudDomainSaveFlag(struct qemud_driver *driver, virDomainPtr dom, if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0) goto cleanup; - priv->jobActive = QEMU_JOB_SAVE; + qemuDomainObjSetJob(vm, QEMU_JOB_SAVE); - memset(&priv->jobInfo, 0, sizeof(priv->jobInfo)); - priv->jobInfo.type = VIR_DOMAIN_JOB_UNBOUNDED; + memset(&priv->job.info, 0, sizeof(priv->job.info)); + priv->job.info.type = VIR_DOMAIN_JOB_UNBOUNDED; /* Pause */ if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) { @@ -2623,7 +2623,7 @@ static int qemudDomainCoreDump(virDomainPtr dom, goto endjob; } - priv->jobActive = QEMU_JOB_DUMP; + qemuDomainObjSetJob(vm, QEMU_JOB_DUMP); /* Migrate will always stop the VM, so the resume condition is independent of whether the stop command is issued. */ @@ -3855,7 +3855,7 @@ static char *qemuDomainGetXMLDesc(virDomainPtr dom, qemuDomainObjPrivatePtr priv = vm->privateData; /* Don't delay if someone's using the monitor, just use * existing most recent data instead */ - if (!priv->jobActive) { + if (!priv->job.active) { if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0) goto cleanup; @@ -6023,19 +6023,19 @@ qemudDomainBlockStats (virDomainPtr dom, } priv = vm->privateData; - if ((priv->jobActive == QEMU_JOB_MIGRATION_OUT) - || (priv->jobActive == QEMU_JOB_SAVE)) { + if ((priv->job.active == QEMU_JOB_MIGRATION_OUT) + || (priv->job.active == QEMU_JOB_SAVE)) { virDomainObjRef(vm); - while (priv->jobSignals & QEMU_JOB_SIGNAL_BLKSTAT) - ignore_value(virCondWait(&priv->signalCond, &vm->lock)); + while (priv->job.signals & QEMU_JOB_SIGNAL_BLKSTAT) + ignore_value(virCondWait(&priv->job.signalCond, &vm->lock)); - priv->jobSignalsData.statDevName = disk->info.alias; - priv->jobSignalsData.blockStat = stats; - priv->jobSignalsData.statRetCode = &ret; - priv->jobSignals |= QEMU_JOB_SIGNAL_BLKSTAT; + priv->job.signalsData.statDevName = disk->info.alias; + priv->job.signalsData.blockStat = stats; + priv->job.signalsData.statRetCode = &ret; + priv->job.signals |= QEMU_JOB_SIGNAL_BLKSTAT; - while (priv->jobSignals & QEMU_JOB_SIGNAL_BLKSTAT) - ignore_value(virCondWait(&priv->signalCond, &vm->lock)); + while (priv->job.signals & QEMU_JOB_SIGNAL_BLKSTAT) + ignore_value(virCondWait(&priv->job.signalCond, &vm->lock)); if (virDomainObjUnref(vm) == 0) vm = NULL; @@ -6470,19 +6470,19 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom, virDomainObjIsActive(vm)) { qemuDomainObjPrivatePtr priv = vm->privateData; - if ((priv->jobActive == QEMU_JOB_MIGRATION_OUT) - || (priv->jobActive == QEMU_JOB_SAVE)) { + if ((priv->job.active == QEMU_JOB_MIGRATION_OUT) + || (priv->job.active == QEMU_JOB_SAVE)) { virDomainObjRef(vm); - while (priv->jobSignals & QEMU_JOB_SIGNAL_BLKINFO) - ignore_value(virCondWait(&priv->signalCond, &vm->lock)); + while (priv->job.signals & QEMU_JOB_SIGNAL_BLKINFO) + ignore_value(virCondWait(&priv->job.signalCond, &vm->lock)); - priv->jobSignalsData.infoDevName = disk->info.alias; - priv->jobSignalsData.blockInfo = info; - priv->jobSignalsData.infoRetCode = &ret; - priv->jobSignals |= QEMU_JOB_SIGNAL_BLKINFO; + priv->job.signalsData.infoDevName = disk->info.alias; + priv->job.signalsData.blockInfo = info; + priv->job.signalsData.infoRetCode = &ret; + priv->job.signals |= QEMU_JOB_SIGNAL_BLKINFO; - while (priv->jobSignals & QEMU_JOB_SIGNAL_BLKINFO) - ignore_value(virCondWait(&priv->signalCond, &vm->lock)); + while (priv->job.signals & QEMU_JOB_SIGNAL_BLKINFO) + ignore_value(virCondWait(&priv->job.signalCond, &vm->lock)); if (virDomainObjUnref(vm) == 0) vm = NULL; @@ -7310,8 +7310,8 @@ static int qemuDomainGetJobInfo(virDomainPtr dom, priv = vm->privateData; if (virDomainObjIsActive(vm)) { - if (priv->jobActive) { - memcpy(info, &priv->jobInfo, sizeof(*info)); + if (priv->job.active) { + memcpy(info, &priv->job.info, sizeof(*info)); /* Refresh elapsed time again just to ensure it * is fully updated. This is primarily for benefit @@ -7320,7 +7320,7 @@ static int qemuDomainGetJobInfo(virDomainPtr dom, */ if (virTimeMs(&info->timeElapsed) < 0) goto cleanup; - info->timeElapsed -= priv->jobStart; + info->timeElapsed -= priv->job.start; } else { memset(info, 0, sizeof(*info)); info->type = VIR_DOMAIN_JOB_NONE; @@ -7360,9 +7360,9 @@ static int qemuDomainAbortJob(virDomainPtr dom) { priv = vm->privateData; if (virDomainObjIsActive(vm)) { - if (priv->jobActive) { + if (priv->job.active) { VIR_DEBUG("Requesting cancellation of job on vm %s", vm->def->name); - priv->jobSignals |= QEMU_JOB_SIGNAL_CANCEL; + priv->job.signals |= QEMU_JOB_SIGNAL_CANCEL; } else { qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", _("no job is active on the domain")); @@ -7414,15 +7414,15 @@ qemuDomainMigrateSetMaxDowntime(virDomainPtr dom, priv = vm->privateData; - if (priv->jobActive != QEMU_JOB_MIGRATION_OUT) { + if (priv->job.active != QEMU_JOB_MIGRATION_OUT) { qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", _("domain is not being migrated")); goto cleanup; } VIR_DEBUG("Requesting migration downtime change to %llums", downtime); - priv->jobSignalsData.migrateDowntime = downtime; - priv->jobSignals |= QEMU_JOB_SIGNAL_MIGRATE_DOWNTIME; + priv->job.signalsData.migrateDowntime = downtime; + priv->job.signals |= QEMU_JOB_SIGNAL_MIGRATE_DOWNTIME; ret = 0; cleanup: @@ -7463,15 +7463,15 @@ qemuDomainMigrateSetMaxSpeed(virDomainPtr dom, priv = vm->privateData; - if (priv->jobActive != QEMU_JOB_MIGRATION_OUT) { + if (priv->job.active != QEMU_JOB_MIGRATION_OUT) { qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", _("domain is not being migrated")); goto cleanup; } VIR_DEBUG("Requesting migration speed change to %luMbs", bandwidth); - priv->jobSignalsData.migrateBandwidth = bandwidth; - priv->jobSignals |= QEMU_JOB_SIGNAL_MIGRATE_SPEED; + priv->job.signalsData.migrateBandwidth = bandwidth; + priv->job.signals |= QEMU_JOB_SIGNAL_MIGRATE_SPEED; ret = 0; cleanup: diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 05c10138b2..40bee93d36 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -742,12 +742,12 @@ qemuMigrationProcessJobSignals(struct qemud_driver *driver, qemuReportError(VIR_ERR_INTERNAL_ERROR, _("%s: %s"), job, _("guest unexpectedly quit")); if (cleanup) - priv->jobSignals = 0; + priv->job.signals = 0; return -1; } - if (priv->jobSignals & QEMU_JOB_SIGNAL_CANCEL) { - priv->jobSignals ^= QEMU_JOB_SIGNAL_CANCEL; + if (priv->job.signals & QEMU_JOB_SIGNAL_CANCEL) { + priv->job.signals ^= QEMU_JOB_SIGNAL_CANCEL; VIR_DEBUG("Cancelling job at client request"); qemuDomainObjEnterMonitorWithDriver(driver, vm); ret = qemuMonitorMigrateCancel(priv->mon); @@ -755,58 +755,58 @@ qemuMigrationProcessJobSignals(struct qemud_driver *driver, if (ret < 0) { VIR_WARN("Unable to cancel job"); } - } else if (priv->jobSignals & QEMU_JOB_SIGNAL_SUSPEND) { - priv->jobSignals ^= QEMU_JOB_SIGNAL_SUSPEND; + } else if (priv->job.signals & QEMU_JOB_SIGNAL_SUSPEND) { + priv->job.signals ^= QEMU_JOB_SIGNAL_SUSPEND; VIR_DEBUG("Pausing domain for non-live migration"); if (qemuMigrationSetOffline(driver, vm) < 0) VIR_WARN("Unable to pause domain"); - } else if (priv->jobSignals & QEMU_JOB_SIGNAL_MIGRATE_DOWNTIME) { - unsigned long long ms = priv->jobSignalsData.migrateDowntime; + } else if (priv->job.signals & QEMU_JOB_SIGNAL_MIGRATE_DOWNTIME) { + unsigned long long ms = priv->job.signalsData.migrateDowntime; - priv->jobSignals ^= QEMU_JOB_SIGNAL_MIGRATE_DOWNTIME; - priv->jobSignalsData.migrateDowntime = 0; + priv->job.signals ^= QEMU_JOB_SIGNAL_MIGRATE_DOWNTIME; + priv->job.signalsData.migrateDowntime = 0; VIR_DEBUG("Setting migration downtime to %llums", ms); qemuDomainObjEnterMonitorWithDriver(driver, vm); ret = qemuMonitorSetMigrationDowntime(priv->mon, ms); qemuDomainObjExitMonitorWithDriver(driver, vm); if (ret < 0) VIR_WARN("Unable to set migration downtime"); - } else if (priv->jobSignals & QEMU_JOB_SIGNAL_MIGRATE_SPEED) { - unsigned long bandwidth = priv->jobSignalsData.migrateBandwidth; + } else if (priv->job.signals & QEMU_JOB_SIGNAL_MIGRATE_SPEED) { + unsigned long bandwidth = priv->job.signalsData.migrateBandwidth; - priv->jobSignals ^= QEMU_JOB_SIGNAL_MIGRATE_SPEED; - priv->jobSignalsData.migrateBandwidth = 0; + priv->job.signals ^= QEMU_JOB_SIGNAL_MIGRATE_SPEED; + priv->job.signalsData.migrateBandwidth = 0; VIR_DEBUG("Setting migration bandwidth to %luMbs", bandwidth); qemuDomainObjEnterMonitorWithDriver(driver, vm); ret = qemuMonitorSetMigrationSpeed(priv->mon, bandwidth); qemuDomainObjExitMonitorWithDriver(driver, vm); if (ret < 0) VIR_WARN("Unable to set migration speed"); - } else if (priv->jobSignals & QEMU_JOB_SIGNAL_BLKSTAT) { + } else if (priv->job.signals & QEMU_JOB_SIGNAL_BLKSTAT) { qemuDomainObjEnterMonitorWithDriver(driver, vm); ret = qemuMonitorGetBlockStatsInfo(priv->mon, - priv->jobSignalsData.statDevName, - &priv->jobSignalsData.blockStat->rd_req, - &priv->jobSignalsData.blockStat->rd_bytes, - &priv->jobSignalsData.blockStat->wr_req, - &priv->jobSignalsData.blockStat->wr_bytes, - &priv->jobSignalsData.blockStat->errs); + priv->job.signalsData.statDevName, + &priv->job.signalsData.blockStat->rd_req, + &priv->job.signalsData.blockStat->rd_bytes, + &priv->job.signalsData.blockStat->wr_req, + &priv->job.signalsData.blockStat->wr_bytes, + &priv->job.signalsData.blockStat->errs); qemuDomainObjExitMonitorWithDriver(driver, vm); - *priv->jobSignalsData.statRetCode = ret; - priv->jobSignals ^= QEMU_JOB_SIGNAL_BLKSTAT; + *priv->job.signalsData.statRetCode = ret; + priv->job.signals ^= QEMU_JOB_SIGNAL_BLKSTAT; if (ret < 0) VIR_WARN("Unable to get block statistics"); - } else if (priv->jobSignals & QEMU_JOB_SIGNAL_BLKINFO) { + } else if (priv->job.signals & QEMU_JOB_SIGNAL_BLKINFO) { qemuDomainObjEnterMonitorWithDriver(driver, vm); ret = qemuMonitorGetBlockExtent(priv->mon, - priv->jobSignalsData.infoDevName, - &priv->jobSignalsData.blockInfo->allocation); + priv->job.signalsData.infoDevName, + &priv->job.signalsData.blockInfo->allocation); qemuDomainObjExitMonitorWithDriver(driver, vm); - *priv->jobSignalsData.infoRetCode = ret; - priv->jobSignals ^= QEMU_JOB_SIGNAL_BLKINFO; + *priv->job.signalsData.infoRetCode = ret; + priv->job.signals ^= QEMU_JOB_SIGNAL_BLKINFO; if (ret < 0) VIR_WARN("Unable to get block information"); @@ -844,44 +844,44 @@ qemuMigrationUpdateJobStatus(struct qemud_driver *driver, &memTotal); qemuDomainObjExitMonitorWithDriver(driver, vm); - if (ret < 0 || virTimeMs(&priv->jobInfo.timeElapsed) < 0) { - priv->jobInfo.type = VIR_DOMAIN_JOB_FAILED; + if (ret < 0 || virTimeMs(&priv->job.info.timeElapsed) < 0) { + priv->job.info.type = VIR_DOMAIN_JOB_FAILED; return -1; } - priv->jobInfo.timeElapsed -= priv->jobStart; + priv->job.info.timeElapsed -= priv->job.start; switch (status) { case QEMU_MONITOR_MIGRATION_STATUS_INACTIVE: - priv->jobInfo.type = VIR_DOMAIN_JOB_NONE; + priv->job.info.type = VIR_DOMAIN_JOB_NONE; qemuReportError(VIR_ERR_OPERATION_FAILED, _("%s: %s"), job, _("is not active")); break; case QEMU_MONITOR_MIGRATION_STATUS_ACTIVE: - priv->jobInfo.dataTotal = memTotal; - priv->jobInfo.dataRemaining = memRemaining; - priv->jobInfo.dataProcessed = memProcessed; + priv->job.info.dataTotal = memTotal; + priv->job.info.dataRemaining = memRemaining; + priv->job.info.dataProcessed = memProcessed; - priv->jobInfo.memTotal = memTotal; - priv->jobInfo.memRemaining = memRemaining; - priv->jobInfo.memProcessed = memProcessed; + priv->job.info.memTotal = memTotal; + priv->job.info.memRemaining = memRemaining; + priv->job.info.memProcessed = memProcessed; ret = 0; break; case QEMU_MONITOR_MIGRATION_STATUS_COMPLETED: - priv->jobInfo.type = VIR_DOMAIN_JOB_COMPLETED; + priv->job.info.type = VIR_DOMAIN_JOB_COMPLETED; ret = 0; break; case QEMU_MONITOR_MIGRATION_STATUS_ERROR: - priv->jobInfo.type = VIR_DOMAIN_JOB_FAILED; + priv->job.info.type = VIR_DOMAIN_JOB_FAILED; qemuReportError(VIR_ERR_OPERATION_FAILED, _("%s: %s"), job, _("unexpectedly failed")); break; case QEMU_MONITOR_MIGRATION_STATUS_CANCELLED: - priv->jobInfo.type = VIR_DOMAIN_JOB_CANCELLED; + priv->job.info.type = VIR_DOMAIN_JOB_CANCELLED; qemuReportError(VIR_ERR_OPERATION_FAILED, _("%s: %s"), job, _("canceled by client")); break; @@ -897,7 +897,7 @@ qemuMigrationWaitForCompletion(struct qemud_driver *driver, virDomainObjPtr vm) qemuDomainObjPrivatePtr priv = vm->privateData; const char *job; - switch (priv->jobActive) { + switch (priv->job.active) { case QEMU_JOB_MIGRATION_OUT: job = _("migration job"); break; @@ -911,17 +911,17 @@ qemuMigrationWaitForCompletion(struct qemud_driver *driver, virDomainObjPtr vm) job = _("job"); } - priv->jobInfo.type = VIR_DOMAIN_JOB_UNBOUNDED; + priv->job.info.type = VIR_DOMAIN_JOB_UNBOUNDED; - while (priv->jobInfo.type == VIR_DOMAIN_JOB_UNBOUNDED) { + while (priv->job.info.type == VIR_DOMAIN_JOB_UNBOUNDED) { /* Poll every 50ms for progress & to allow cancellation */ struct timespec ts = { .tv_sec = 0, .tv_nsec = 50 * 1000 * 1000ull }; - while (priv->jobSignals) { + while (priv->job.signals) { if (qemuMigrationProcessJobSignals(driver, vm, job, false) < 0) goto cleanup; } - virCondSignal(&priv->signalCond); + virCondSignal(&priv->job.signalCond); if (qemuMigrationUpdateJobStatus(driver, vm, job) < 0) goto cleanup; @@ -937,12 +937,12 @@ qemuMigrationWaitForCompletion(struct qemud_driver *driver, virDomainObjPtr vm) } cleanup: - while (priv->jobSignals) { + while (priv->job.signals) { qemuMigrationProcessJobSignals(driver, vm, job, true); } - virCondBroadcast(&priv->signalCond); + virCondBroadcast(&priv->job.signalCond); - if (priv->jobInfo.type == VIR_DOMAIN_JOB_COMPLETED) + if (priv->job.info.type == VIR_DOMAIN_JOB_COMPLETED) return 0; else return -1; @@ -1112,7 +1112,7 @@ qemuMigrationPrepareTunnel(struct qemud_driver *driver, if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0) goto cleanup; - priv->jobActive = QEMU_JOB_MIGRATION_IN; + qemuDomainObjSetJob(vm, QEMU_JOB_MIGRATION_IN); /* Domain starts inactive, even if the domain XML had an id field. */ vm->def->id = -1; @@ -1185,9 +1185,9 @@ endjob: */ if (vm && virDomainObjIsActive(vm)) { - priv->jobActive = QEMU_JOB_MIGRATION_IN; - priv->jobInfo.type = VIR_DOMAIN_JOB_UNBOUNDED; - priv->jobStart = now; + qemuDomainObjSetJob(vm, QEMU_JOB_MIGRATION_IN); + priv->job.info.type = VIR_DOMAIN_JOB_UNBOUNDED; + priv->job.start = now; } cleanup: @@ -1348,7 +1348,7 @@ qemuMigrationPrepareDirect(struct qemud_driver *driver, if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0) goto cleanup; - priv->jobActive = QEMU_JOB_MIGRATION_IN; + qemuDomainObjSetJob(vm, QEMU_JOB_MIGRATION_IN); /* Domain starts inactive, even if the domain XML had an id field. */ vm->def->id = -1; @@ -1407,9 +1407,9 @@ endjob: */ if (vm && virDomainObjIsActive(vm)) { - priv->jobActive = QEMU_JOB_MIGRATION_IN; - priv->jobInfo.type = VIR_DOMAIN_JOB_UNBOUNDED; - priv->jobStart = now; + qemuDomainObjSetJob(vm, QEMU_JOB_MIGRATION_IN); + priv->job.info.type = VIR_DOMAIN_JOB_UNBOUNDED; + priv->job.start = now; } cleanup: @@ -2289,7 +2289,7 @@ int qemuMigrationPerform(struct qemud_driver *driver, if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0) goto cleanup; - priv->jobActive = QEMU_JOB_MIGRATION_OUT; + qemuDomainObjSetJob(vm, QEMU_JOB_MIGRATION_OUT); if (!virDomainObjIsActive(vm)) { qemuReportError(VIR_ERR_OPERATION_INVALID, @@ -2303,8 +2303,8 @@ int qemuMigrationPerform(struct qemud_driver *driver, goto endjob; } - memset(&priv->jobInfo, 0, sizeof(priv->jobInfo)); - priv->jobInfo.type = VIR_DOMAIN_JOB_UNBOUNDED; + memset(&priv->job.info, 0, sizeof(priv->job.info)); + priv->job.info.type = VIR_DOMAIN_JOB_UNBOUNDED; resume = virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING; @@ -2453,13 +2453,12 @@ qemuMigrationFinish(struct qemud_driver *driver, virErrorPtr orig_err = NULL; priv = vm->privateData; - if (priv->jobActive != QEMU_JOB_MIGRATION_IN) { + if (priv->job.active != QEMU_JOB_MIGRATION_IN) { qemuReportError(VIR_ERR_NO_DOMAIN, _("domain '%s' is not processing incoming migration"), vm->def->name); goto cleanup; } - priv->jobActive = QEMU_JOB_NONE; - memset(&priv->jobInfo, 0, sizeof(priv->jobInfo)); + qemuDomainObjDiscardJob(vm); if (!(mig = qemuMigrationEatCookie(driver, vm, cookiein, cookieinlen, 0))) goto cleanup; diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index aea59afc73..24557ddbc2 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3205,11 +3205,10 @@ static void qemuProcessAutoDestroyDom(void *payload, } priv = dom->privateData; - if (priv->jobActive == QEMU_JOB_MIGRATION_IN) { + if (priv->job.active == QEMU_JOB_MIGRATION_IN) { VIR_DEBUG("vm=%s has incoming migration active, cancelling", dom->def->name); - priv->jobActive = QEMU_JOB_NONE; - memset(&priv->jobInfo, 0, sizeof(priv->jobInfo)); + qemuDomainObjDiscardJob(dom); } if (qemuDomainObjBeginJobWithDriver(data->driver, dom) < 0)