Wire up virDomainMigrateSetSpeed into QEMU driver

Enhance the QEMU migration monitoring loop, so that it can get
a signal to change migration speed on the fly

* src/qemu/qemu_domain.h: Add signal for changing speed on the fly
* src/qemu/qemu_driver.c: Wire up virDomainMigrateSetSpeed driver
* src/qemu/qemu_migration.c: Support signal for changing speed
This commit is contained in:
Daniel P. Berrange 2011-02-17 14:33:00 +00:00
parent 118dd7d06e
commit 83cc3d1d55
3 changed files with 63 additions and 1 deletions

View File

@ -45,10 +45,12 @@ enum qemuDomainJobSignals {
QEMU_JOB_SIGNAL_CANCEL = 1 << 0, /* Request job cancellation */
QEMU_JOB_SIGNAL_SUSPEND = 1 << 1, /* Request VM suspend to finish live migration offline */
QEMU_JOB_SIGNAL_MIGRATE_DOWNTIME = 1 << 2, /* Request migration downtime change */
QEMU_JOB_SIGNAL_MIGRATE_SPEED = 1 << 3, /* Request migration speed change */
};
struct qemuDomainJobSignalsData {
unsigned long long migrateDowntime; /* Data for QEMU_JOB_SIGNAL_MIGRATE_DOWNTIME */
unsigned long migrateBandwidth; /* Data for QEMU_JOB_SIGNAL_MIGRATE_SPEED */
};
typedef struct _qemuDomainPCIAddressSet qemuDomainPCIAddressSet;

View File

@ -6071,6 +6071,55 @@ cleanup:
return ret;
}
static int
qemuDomainMigrateSetMaxSpeed(virDomainPtr dom,
unsigned long bandwidth,
unsigned int flags)
{
struct qemud_driver *driver = dom->conn->privateData;
virDomainObjPtr vm;
qemuDomainObjPrivatePtr priv;
int ret = -1;
virCheckFlags(0, -1);
qemuDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
virUUIDFormat(dom->uuid, uuidstr);
qemuReportError(VIR_ERR_NO_DOMAIN,
_("no domain with matching uuid '%s'"), uuidstr);
goto cleanup;
}
if (!virDomainObjIsActive(vm)) {
qemuReportError(VIR_ERR_OPERATION_INVALID,
"%s", _("domain is not running"));
goto cleanup;
}
priv = vm->privateData;
if (priv->jobActive != 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->jobSignals |= QEMU_JOB_SIGNAL_MIGRATE_SPEED;
priv->jobSignalsData.migrateBandwidth = bandwidth;
ret = 0;
cleanup:
if (vm)
virDomainObjUnlock(vm);
qemuDriverUnlock(driver);
return ret;
}
static char *qemuFindQemuImgBinary(void)
{
char *ret;
@ -7121,7 +7170,7 @@ static virDriver qemuDriver = {
qemuDomainGetJobInfo, /* domainGetJobInfo */
qemuDomainAbortJob, /* domainAbortJob */
qemuDomainMigrateSetMaxDowntime, /* domainMigrateSetMaxDowntime */
NULL, /* domainMigrateSetMaxSpeed */
qemuDomainMigrateSetMaxSpeed, /* domainMigrateSetMaxSpeed */
qemuDomainEventRegisterAny, /* domainEventRegisterAny */
qemuDomainEventDeregisterAny, /* domainEventDeregisterAny */
qemuDomainManagedSave, /* domainManagedSave */

View File

@ -144,6 +144,17 @@ qemuMigrationWaitForCompletion(struct qemud_driver *driver, virDomainObjPtr vm)
qemuDomainObjExitMonitorWithDriver(driver, vm);
if (rc < 0)
VIR_WARN0("Unable to set migration downtime");
} else if (priv->jobSignals & QEMU_JOB_SIGNAL_MIGRATE_SPEED) {
unsigned long bandwidth = priv->jobSignalsData.migrateBandwidth;
priv->jobSignals ^= QEMU_JOB_SIGNAL_MIGRATE_SPEED;
priv->jobSignalsData.migrateBandwidth = 0;
VIR_DEBUG("Setting migration bandwidth to %luMbs", bandwidth);
qemuDomainObjEnterMonitorWithDriver(driver, vm);
rc = qemuMonitorSetMigrationSpeed(priv->mon, bandwidth);
qemuDomainObjExitMonitorWithDriver(driver, vm);
if (rc < 0)
VIR_WARN0("Unable to set migration speed");
}
/* Repeat check because the job signals might have caused