1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-03-07 17:28:15 +00:00

qemu: Implement VIR_DOMAIN_MIGRATE_MAX_SPEED_POSTCOPY flag

This flag tells virDomainMigrateSetMaxSpeed and
virDomainMigrateGetMaxSpeed APIs to work on post-copy migration
bandwidth.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Jiri Denemark 2019-02-04 17:10:38 +01:00
parent c830187a01
commit 12977fba8b

View File

@ -14275,10 +14275,12 @@ qemuDomainMigrateSetMaxSpeed(virDomainPtr dom,
virQEMUDriverPtr driver = dom->conn->privateData; virQEMUDriverPtr driver = dom->conn->privateData;
virDomainObjPtr vm; virDomainObjPtr vm;
qemuDomainObjPrivatePtr priv; qemuDomainObjPrivatePtr priv;
int rc; bool postcopy = !!(flags & VIR_DOMAIN_MIGRATE_MAX_SPEED_POSTCOPY);
VIR_AUTOPTR(qemuMigrationParams) migParams = NULL;
unsigned long long max;
int ret = -1; int ret = -1;
virCheckFlags(0, -1); virCheckFlags(VIR_DOMAIN_MIGRATE_MAX_SPEED_POSTCOPY, -1);
if (!(vm = qemuDomObjFromDomain(dom))) if (!(vm = qemuDomObjFromDomain(dom)))
goto cleanup; goto cleanup;
@ -14288,14 +14290,18 @@ qemuDomainMigrateSetMaxSpeed(virDomainPtr dom,
if (virDomainMigrateSetMaxSpeedEnsureACL(dom->conn, vm->def) < 0) if (virDomainMigrateSetMaxSpeedEnsureACL(dom->conn, vm->def) < 0)
goto cleanup; goto cleanup;
if (bandwidth > QEMU_DOMAIN_MIG_BANDWIDTH_MAX) { if (postcopy)
max = ULLONG_MAX / 1024 / 1024;
else
max = QEMU_DOMAIN_MIG_BANDWIDTH_MAX;
if (bandwidth > max) {
virReportError(VIR_ERR_OVERFLOW, virReportError(VIR_ERR_OVERFLOW,
_("bandwidth must be less than %llu"), _("bandwidth must be less than %llu"), max + 1);
QEMU_DOMAIN_MIG_BANDWIDTH_MAX + 1ULL);
goto cleanup; goto cleanup;
} }
if (!virDomainObjIsActive(vm)) { if (!postcopy && !virDomainObjIsActive(vm)) {
priv->migMaxBandwidth = bandwidth; priv->migMaxBandwidth = bandwidth;
ret = 0; ret = 0;
goto cleanup; goto cleanup;
@ -14308,12 +14314,29 @@ qemuDomainMigrateSetMaxSpeed(virDomainPtr dom,
goto endjob; goto endjob;
VIR_DEBUG("Setting migration bandwidth to %luMbs", bandwidth); VIR_DEBUG("Setting migration bandwidth to %luMbs", bandwidth);
qemuDomainObjEnterMonitor(driver, vm);
rc = qemuMonitorSetMigrationSpeed(priv->mon, bandwidth);
if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
goto endjob;
priv->migMaxBandwidth = bandwidth; if (postcopy) {
if (!(migParams = qemuMigrationParamsNew()))
goto endjob;
if (qemuMigrationParamsSetULL(migParams,
QEMU_MIGRATION_PARAM_MAX_POSTCOPY_BANDWIDTH,
bandwidth * 1024 * 1024) < 0)
goto endjob;
if (qemuMigrationParamsApply(driver, vm, QEMU_ASYNC_JOB_NONE,
migParams) < 0)
goto endjob;
} else {
int rc;
qemuDomainObjEnterMonitor(driver, vm);
rc = qemuMonitorSetMigrationSpeed(priv->mon, bandwidth);
if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
goto endjob;
priv->migMaxBandwidth = bandwidth;
}
ret = 0; ret = 0;
@ -14325,16 +14348,71 @@ qemuDomainMigrateSetMaxSpeed(virDomainPtr dom,
return ret; return ret;
} }
static int
qemuDomainMigrationGetPostcopyBandwidth(virQEMUDriverPtr driver,
virDomainObjPtr vm,
unsigned long *bandwidth)
{
VIR_AUTOPTR(qemuMigrationParams) migParams = NULL;
unsigned long long bw;
int rc;
int ret = -1;
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
return -1;
if (virDomainObjCheckActive(vm) < 0)
goto cleanup;
if (qemuMigrationParamsFetch(driver, vm, QEMU_ASYNC_JOB_NONE,
&migParams) < 0)
goto cleanup;
if ((rc = qemuMigrationParamsGetULL(migParams,
QEMU_MIGRATION_PARAM_MAX_POSTCOPY_BANDWIDTH,
&bw)) < 0)
goto cleanup;
if (rc == 1) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("querying maximum post-copy migration speed is "
"not supported by QEMU binary"));
goto cleanup;
}
/* QEMU reports B/s while we use MiB/s */
bw /= 1024 * 1024;
if (bw > ULONG_MAX) {
virReportError(VIR_ERR_OVERFLOW,
_("bandwidth %llu is greater than %lu which is the "
"maximum value supported by this API"),
bw, ULONG_MAX);
goto cleanup;
}
*bandwidth = bw;
ret = 0;
cleanup:
qemuDomainObjEndJob(driver, vm);
return ret;
}
static int static int
qemuDomainMigrateGetMaxSpeed(virDomainPtr dom, qemuDomainMigrateGetMaxSpeed(virDomainPtr dom,
unsigned long *bandwidth, unsigned long *bandwidth,
unsigned int flags) unsigned int flags)
{ {
virQEMUDriverPtr driver = dom->conn->privateData;
virDomainObjPtr vm; virDomainObjPtr vm;
qemuDomainObjPrivatePtr priv; qemuDomainObjPrivatePtr priv;
bool postcopy = !!(flags & VIR_DOMAIN_MIGRATE_MAX_SPEED_POSTCOPY);
int ret = -1; int ret = -1;
virCheckFlags(0, -1); virCheckFlags(VIR_DOMAIN_MIGRATE_MAX_SPEED_POSTCOPY, -1);
if (!(vm = qemuDomObjFromDomain(dom))) if (!(vm = qemuDomObjFromDomain(dom)))
goto cleanup; goto cleanup;
@ -14344,7 +14422,13 @@ qemuDomainMigrateGetMaxSpeed(virDomainPtr dom,
if (virDomainMigrateGetMaxSpeedEnsureACL(dom->conn, vm->def) < 0) if (virDomainMigrateGetMaxSpeedEnsureACL(dom->conn, vm->def) < 0)
goto cleanup; goto cleanup;
*bandwidth = priv->migMaxBandwidth; if (postcopy) {
if (qemuDomainMigrationGetPostcopyBandwidth(driver, vm, bandwidth) < 0)
goto cleanup;
} else {
*bandwidth = priv->migMaxBandwidth;
}
ret = 0; ret = 0;
cleanup: cleanup: