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;
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;
qemuDomainGetJobInfo, /* domainGetJobInfo */
qemuDomainAbortJob, /* domainAbortJob */
qemuDomainMigrateSetMaxDowntime, /* domainMigrateSetMaxDowntime */
- NULL, /* domainMigrateSetMaxSpeed */
+ qemuDomainMigrateSetMaxSpeed, /* domainMigrateSetMaxSpeed */
qemuDomainEventRegisterAny, /* domainEventRegisterAny */
qemuDomainEventDeregisterAny, /* domainEventDeregisterAny */
qemuDomainManagedSave, /* domainManagedSave */
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