[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH 3/3] 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
---
 src/qemu/qemu_domain.h    |    2 +
 src/qemu/qemu_driver.c    |   51 ++++++++++++++++++++++++++++++++++++++++++++-
 src/qemu/qemu_migration.c |   11 +++++++++
 3 files changed, 63 insertions(+), 1 deletions(-)

diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index ebb2050..8258900 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -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;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 93cae00..fd2eced 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -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;
@@ -7122,7 +7171,7 @@ static virDriver qemuDriver = {
     qemuDomainGetJobInfo, /* domainGetJobInfo */
     qemuDomainAbortJob, /* domainAbortJob */
     qemuDomainMigrateSetMaxDowntime, /* domainMigrateSetMaxDowntime */
-    NULL, /* domainMigrateSetMaxSpeed */
+    qemuDomainMigrateSetMaxSpeed, /* domainMigrateSetMaxSpeed */
     qemuDomainEventRegisterAny, /* domainEventRegisterAny */
     qemuDomainEventDeregisterAny, /* domainEventDeregisterAny */
     qemuDomainManagedSave, /* domainManagedSave */
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index f450130..826e1bf 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -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
-- 
1.7.4


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]