提交 792a5a61 编写于 作者: D Daniel P. Berrange

Refactor migration completion loop to allow code reuse

The qemuMigrationWaitForCompletion method contains a loop which
repeatedly queries QEMU to check migration progress, and also
processes job signals (pause, setspeed, setbandwidth, cancel).

The tunnelled migration loop does not currently support this
functionality, but should. Refactor the code to allow it to
be used with tunnelled migration.
上级 2d5caf7a
......@@ -583,53 +583,27 @@ qemuMigrationSetOffline(struct qemud_driver *driver,
}
int
qemuMigrationWaitForCompletion(struct qemud_driver *driver, virDomainObjPtr vm)
static int
qemuMigrationProcessJobSignals(struct qemud_driver *driver,
virDomainObjPtr vm,
const char *job)
{
int ret = -1;
int status;
unsigned long long memProcessed;
unsigned long long memRemaining;
unsigned long long memTotal;
qemuDomainObjPrivatePtr priv = vm->privateData;
priv->jobInfo.type = VIR_DOMAIN_JOB_UNBOUNDED;
while (priv->jobInfo.type == VIR_DOMAIN_JOB_UNBOUNDED) {
/* Poll every 50ms for progress & to allow cancellation */
struct timespec ts = { .tv_sec = 0, .tv_nsec = 50 * 1000 * 1000ull };
struct timeval now;
int rc;
const char *job;
switch (priv->jobActive) {
case QEMU_JOB_MIGRATION_OUT:
job = _("migration job");
break;
case QEMU_JOB_SAVE:
job = _("domain save job");
break;
case QEMU_JOB_DUMP:
job = _("domain core dump job");
break;
default:
job = _("job");
}
int ret = -1;
if (!virDomainObjIsActive(vm)) {
qemuReportError(VIR_ERR_INTERNAL_ERROR, _("%s: %s"),
job, _("guest unexpectedly quit"));
goto cleanup;
return -1;
}
if (priv->jobSignals & QEMU_JOB_SIGNAL_CANCEL) {
priv->jobSignals ^= QEMU_JOB_SIGNAL_CANCEL;
VIR_DEBUG("Cancelling job at client request");
qemuDomainObjEnterMonitorWithDriver(driver, vm);
rc = qemuMonitorMigrateCancel(priv->mon);
ret = qemuMonitorMigrateCancel(priv->mon);
qemuDomainObjExitMonitorWithDriver(driver, vm);
if (rc < 0) {
if (ret < 0) {
VIR_WARN("Unable to cancel job");
}
} else if (priv->jobSignals & QEMU_JOB_SIGNAL_SUSPEND) {
......@@ -644,9 +618,9 @@ qemuMigrationWaitForCompletion(struct qemud_driver *driver, virDomainObjPtr vm)
priv->jobSignalsData.migrateDowntime = 0;
VIR_DEBUG("Setting migration downtime to %llums", ms);
qemuDomainObjEnterMonitorWithDriver(driver, vm);
rc = qemuMonitorSetMigrationDowntime(priv->mon, ms);
ret = qemuMonitorSetMigrationDowntime(priv->mon, ms);
qemuDomainObjExitMonitorWithDriver(driver, vm);
if (rc < 0)
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;
......@@ -655,39 +629,55 @@ qemuMigrationWaitForCompletion(struct qemud_driver *driver, virDomainObjPtr vm)
priv->jobSignalsData.migrateBandwidth = 0;
VIR_DEBUG("Setting migration bandwidth to %luMbs", bandwidth);
qemuDomainObjEnterMonitorWithDriver(driver, vm);
rc = qemuMonitorSetMigrationSpeed(priv->mon, bandwidth);
ret = qemuMonitorSetMigrationSpeed(priv->mon, bandwidth);
qemuDomainObjExitMonitorWithDriver(driver, vm);
if (rc < 0)
if (ret < 0)
VIR_WARN("Unable to set migration speed");
} else {
ret = 0;
}
/* Repeat check because the job signals might have caused
* guest to die
*/
return ret;
}
static int
qemuMigrationUpdateJobStatus(struct qemud_driver *driver,
virDomainObjPtr vm,
const char *job)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
int ret = -1;
int status;
unsigned long long memProcessed;
unsigned long long memRemaining;
unsigned long long memTotal;
struct timeval now;
if (!virDomainObjIsActive(vm)) {
qemuReportError(VIR_ERR_INTERNAL_ERROR, _("%s: %s"),
job, _("guest unexpectedly quit"));
goto cleanup;
return -1;
}
qemuDomainObjEnterMonitorWithDriver(driver, vm);
rc = qemuMonitorGetMigrationStatus(priv->mon,
ret = qemuMonitorGetMigrationStatus(priv->mon,
&status,
&memProcessed,
&memRemaining,
&memTotal);
qemuDomainObjExitMonitorWithDriver(driver, vm);
if (rc < 0) {
if (ret < 0) {
priv->jobInfo.type = VIR_DOMAIN_JOB_FAILED;
goto cleanup;
return -1;
}
if (gettimeofday(&now, NULL) < 0) {
priv->jobInfo.type = VIR_DOMAIN_JOB_FAILED;
virReportSystemError(errno, "%s",
_("cannot get time of day"));
goto cleanup;
return -1;
}
priv->jobInfo.timeElapsed = timeval_to_ms(now) - priv->jobStart;
......@@ -706,6 +696,8 @@ qemuMigrationWaitForCompletion(struct qemud_driver *driver, virDomainObjPtr vm)
priv->jobInfo.memTotal = memTotal;
priv->jobInfo.memRemaining = memRemaining;
priv->jobInfo.memProcessed = memProcessed;
ret = 0;
break;
case QEMU_MONITOR_MIGRATION_STATUS_COMPLETED:
......@@ -726,6 +718,43 @@ qemuMigrationWaitForCompletion(struct qemud_driver *driver, virDomainObjPtr vm)
break;
}
return ret;
}
int
qemuMigrationWaitForCompletion(struct qemud_driver *driver, virDomainObjPtr vm)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
priv->jobInfo.type = VIR_DOMAIN_JOB_UNBOUNDED;
while (priv->jobInfo.type == VIR_DOMAIN_JOB_UNBOUNDED) {
/* Poll every 50ms for progress & to allow cancellation */
struct timespec ts = { .tv_sec = 0, .tv_nsec = 50 * 1000 * 1000ull };
const char *job;
switch (priv->jobActive) {
case QEMU_JOB_MIGRATION_OUT:
job = _("migration job");
break;
case QEMU_JOB_SAVE:
job = _("domain save job");
break;
case QEMU_JOB_DUMP:
job = _("domain core dump job");
break;
default:
job = _("job");
}
if (qemuMigrationProcessJobSignals(driver, vm, job) < 0)
goto cleanup;
if (qemuMigrationUpdateJobStatus(driver, vm, job) < 0)
goto cleanup;
virDomainObjUnlock(vm);
qemuDriverUnlock(driver);
......@@ -736,7 +765,10 @@ qemuMigrationWaitForCompletion(struct qemud_driver *driver, virDomainObjPtr vm)
}
cleanup:
return ret;
if (priv->jobInfo.type == VIR_DOMAIN_JOB_COMPLETED)
return 0;
else
return -1;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册