diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 59d322c8f364600c3f681e70f5e12f239637c3f8..b47085febb730322c998457d2d7b342a5cec20f1 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -14051,6 +14051,7 @@ qemuDomainMigrateSetMaxSpeed(virDomainPtr dom, qemuDomainObjPrivatePtr priv; bool postcopy = !!(flags & VIR_DOMAIN_MIGRATE_MAX_SPEED_POSTCOPY); g_autoptr(qemuMigrationParams) migParams = NULL; + bool bwParam; unsigned long long max; int ret = -1; @@ -14089,12 +14090,20 @@ qemuDomainMigrateSetMaxSpeed(virDomainPtr dom, VIR_DEBUG("Setting migration bandwidth to %luMbs", bandwidth); - if (postcopy) { + bwParam = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_PARAM_BANDWIDTH); + + if (postcopy || bwParam) { + qemuMigrationParam param; + if (!(migParams = qemuMigrationParamsNew())) goto endjob; - if (qemuMigrationParamsSetULL(migParams, - QEMU_MIGRATION_PARAM_MAX_POSTCOPY_BANDWIDTH, + if (postcopy) + param = QEMU_MIGRATION_PARAM_MAX_POSTCOPY_BANDWIDTH; + else + param = QEMU_MIGRATION_PARAM_MAX_BANDWIDTH; + + if (qemuMigrationParamsSetULL(migParams, param, bandwidth * 1024 * 1024) < 0) goto endjob; @@ -14108,9 +14117,10 @@ qemuDomainMigrateSetMaxSpeed(virDomainPtr dom, rc = qemuMonitorSetMigrationSpeed(priv->mon, bandwidth); if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0) goto endjob; + } + if (!postcopy) priv->migMaxBandwidth = bandwidth; - } ret = 0; diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 7ee5b5eda85eedb36296961c3d4e29dcb9db6114..13427c1203083a7afe1a51aa6efad66180371753 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -3495,6 +3495,7 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, unsigned int cookieFlags = 0; bool abort_on_error = !!(flags & VIR_MIGRATE_ABORT_ON_ERROR); bool events = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT); + bool bwParam = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_PARAM_BANDWIDTH); bool cancel = false; unsigned int waitFlags; virDomainDefPtr persistDef = NULL; @@ -3582,6 +3583,11 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, goto error; } + if (bwParam && + qemuMigrationParamsSetULL(migParams, QEMU_MIGRATION_PARAM_MAX_BANDWIDTH, + migrate_speed * 1024 * 1024) < 0) + goto error; + if (qemuMigrationParamsApply(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, migParams) < 0) goto error; @@ -3644,7 +3650,8 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, goto exit_monitor; } - if (qemuMonitorSetMigrationSpeed(priv->mon, migrate_speed) < 0) + if (!bwParam && + qemuMonitorSetMigrationSpeed(priv->mon, migrate_speed) < 0) goto exit_monitor; /* connect to the destination qemu if needed */ @@ -5299,24 +5306,41 @@ qemuMigrationSrcToFile(virQEMUDriverPtr driver, virDomainObjPtr vm, qemuDomainAsyncJob asyncJob) { qemuDomainObjPrivatePtr priv = vm->privateData; + bool bwParam = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_PARAM_BANDWIDTH); int rc; int ret = -1; int pipeFD[2] = { -1, -1 }; unsigned long saveMigBandwidth = priv->migMaxBandwidth; char *errbuf = NULL; virErrorPtr orig_err = NULL; + g_autoptr(qemuMigrationParams) migParams = NULL; if (qemuMigrationSetDBusVMState(driver, vm) < 0) return -1; /* Increase migration bandwidth to unlimited since target is a file. * Failure to change migration speed is not fatal. */ - if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) { - qemuMonitorSetMigrationSpeed(priv->mon, - QEMU_DOMAIN_MIG_BANDWIDTH_MAX); - priv->migMaxBandwidth = QEMU_DOMAIN_MIG_BANDWIDTH_MAX; - if (qemuDomainObjExitMonitor(driver, vm) < 0) + if (bwParam) { + if (!(migParams = qemuMigrationParamsNew())) + return -1; + + if (qemuMigrationParamsSetULL(migParams, + QEMU_MIGRATION_PARAM_MAX_BANDWIDTH, + QEMU_DOMAIN_MIG_BANDWIDTH_MAX * 1024 * 1024) < 0) + return -1; + + if (qemuMigrationParamsApply(driver, vm, asyncJob, migParams) < 0) return -1; + + priv->migMaxBandwidth = QEMU_DOMAIN_MIG_BANDWIDTH_MAX; + } else { + if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) { + qemuMonitorSetMigrationSpeed(priv->mon, + QEMU_DOMAIN_MIG_BANDWIDTH_MAX); + priv->migMaxBandwidth = QEMU_DOMAIN_MIG_BANDWIDTH_MAX; + if (qemuDomainObjExitMonitor(driver, vm) < 0) + return -1; + } } if (!virDomainObjIsActive(vm)) { @@ -5397,11 +5421,20 @@ qemuMigrationSrcToFile(virQEMUDriverPtr driver, virDomainObjPtr vm, virErrorPreserveLast(&orig_err); /* Restore max migration bandwidth */ - if (virDomainObjIsActive(vm) && - qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) { - qemuMonitorSetMigrationSpeed(priv->mon, saveMigBandwidth); + if (virDomainObjIsActive(vm)) { + if (bwParam) { + if (qemuMigrationParamsSetULL(migParams, + QEMU_MIGRATION_PARAM_MAX_BANDWIDTH, + saveMigBandwidth * 1024 * 1024) == 0) + ignore_value(qemuMigrationParamsApply(driver, vm, asyncJob, + migParams)); + } else { + if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) { + qemuMonitorSetMigrationSpeed(priv->mon, saveMigBandwidth); + ignore_value(qemuDomainObjExitMonitor(driver, vm)); + } + } priv->migMaxBandwidth = saveMigBandwidth; - ignore_value(qemuDomainObjExitMonitor(driver, vm)); } VIR_FORCE_CLOSE(pipeFD[0]); diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index 6d5a1d5fe2e255bd61bd088cbad5ed4a0aa869bc..e8a0508c539fc2d4086a0d09f0a4759faa1e9ec8 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -3220,7 +3220,7 @@ mymain(void) DO_TEST_GEN_DEPRECATED(qemuMonitorJSONChangeMedia, true); DO_TEST_GEN(qemuMonitorJSONSaveVirtualMemory); DO_TEST_GEN(qemuMonitorJSONSavePhysicalMemory); - DO_TEST_GEN_DEPRECATED(qemuMonitorJSONSetMigrationSpeed, false); + DO_TEST_GEN_DEPRECATED(qemuMonitorJSONSetMigrationSpeed, true); DO_TEST_GEN_DEPRECATED(qemuMonitorJSONSetMigrationDowntime, false); DO_TEST_GEN(qemuMonitorJSONMigrate); DO_TEST_GEN(qemuMonitorJSONDump);