|
|
a1c947 |
From b8c791a3fc2767e6d899e3e0c590a93cb0ee7e03 Mon Sep 17 00:00:00 2001
|
|
|
a1c947 |
Message-Id: <b8c791a3fc2767e6d899e3e0c590a93cb0ee7e03@dist-git>
|
|
|
a1c947 |
From: Jiri Denemark <jdenemar@redhat.com>
|
|
|
a1c947 |
Date: Thu, 30 Jun 2022 12:52:38 +0200
|
|
|
a1c947 |
Subject: [PATCH] qemu_migration: Apply max-postcopy-bandwidth on post-copy
|
|
|
a1c947 |
resume
|
|
|
a1c947 |
|
|
|
a1c947 |
When resuming post-copy migration users may want to limit the bandwidth
|
|
|
a1c947 |
used by the migration and use a value that is different from the one
|
|
|
a1c947 |
specified when the migration was originally started.
|
|
|
a1c947 |
|
|
|
a1c947 |
Resolves: https://gitlab.com/libvirt/libvirt/-/issues/333
|
|
|
a1c947 |
|
|
|
a1c947 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
a1c947 |
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
|
|
|
a1c947 |
(cherry picked from commit 766abdc291ba606379a7d197bff477fef25fb508)
|
|
|
a1c947 |
|
|
|
a1c947 |
https://bugzilla.redhat.com/show_bug.cgi?id=2111070
|
|
|
a1c947 |
|
|
|
a1c947 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
a1c947 |
---
|
|
|
a1c947 |
src/qemu/qemu_migration.c | 12 ++++++--
|
|
|
a1c947 |
src/qemu/qemu_migration_params.c | 45 ++++++++++++++++++----------
|
|
|
a1c947 |
src/qemu/qemu_migration_paramspriv.h | 3 +-
|
|
|
a1c947 |
tests/qemumigparamstest.c | 2 +-
|
|
|
a1c947 |
tests/qemumigrationcookiexmltest.c | 2 +-
|
|
|
a1c947 |
5 files changed, 42 insertions(+), 22 deletions(-)
|
|
|
a1c947 |
|
|
|
a1c947 |
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
|
|
|
a1c947 |
index 285a49c5ff..8a2f5b09a1 100644
|
|
|
a1c947 |
--- a/src/qemu/qemu_migration.c
|
|
|
a1c947 |
+++ b/src/qemu/qemu_migration.c
|
|
|
a1c947 |
@@ -5097,12 +5097,13 @@ qemuMigrationSrcRun(virQEMUDriver *driver,
|
|
|
a1c947 |
|
|
|
a1c947 |
static int
|
|
|
a1c947 |
qemuMigrationSrcResume(virDomainObj *vm,
|
|
|
a1c947 |
- qemuMigrationParams *migParams G_GNUC_UNUSED,
|
|
|
a1c947 |
+ qemuMigrationParams *migParams,
|
|
|
a1c947 |
const char *cookiein,
|
|
|
a1c947 |
int cookieinlen,
|
|
|
a1c947 |
char **cookieout,
|
|
|
a1c947 |
int *cookieoutlen,
|
|
|
a1c947 |
- qemuMigrationSpec *spec)
|
|
|
a1c947 |
+ qemuMigrationSpec *spec,
|
|
|
a1c947 |
+ unsigned long flags)
|
|
|
a1c947 |
{
|
|
|
a1c947 |
qemuDomainObjPrivate *priv = vm->privateData;
|
|
|
a1c947 |
virQEMUDriver *driver = priv->driver;
|
|
|
a1c947 |
@@ -5119,6 +5120,10 @@ qemuMigrationSrcResume(virDomainObj *vm,
|
|
|
a1c947 |
if (!mig)
|
|
|
a1c947 |
return -1;
|
|
|
a1c947 |
|
|
|
a1c947 |
+ if (qemuMigrationParamsApply(driver, vm, VIR_ASYNC_JOB_MIGRATION_OUT,
|
|
|
a1c947 |
+ migParams, flags) < 0)
|
|
|
a1c947 |
+ return -1;
|
|
|
a1c947 |
+
|
|
|
a1c947 |
if (qemuDomainObjEnterMonitorAsync(driver, vm,
|
|
|
a1c947 |
VIR_ASYNC_JOB_MIGRATION_OUT) < 0)
|
|
|
a1c947 |
return -1;
|
|
|
a1c947 |
@@ -5200,6 +5205,7 @@ qemuMigrationSrcPerformNative(virQEMUDriver *driver,
|
|
|
a1c947 |
|
|
|
a1c947 |
if (STREQ(uribits->scheme, "unix")) {
|
|
|
a1c947 |
if ((flags & VIR_MIGRATE_TLS) &&
|
|
|
a1c947 |
+ !(flags & VIR_MIGRATE_POSTCOPY_RESUME) &&
|
|
|
a1c947 |
!qemuMigrationParamsTLSHostnameIsSet(migParams)) {
|
|
|
a1c947 |
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
|
|
a1c947 |
_("Explicit destination hostname is required "
|
|
|
a1c947 |
@@ -5231,7 +5237,7 @@ qemuMigrationSrcPerformNative(virQEMUDriver *driver,
|
|
|
a1c947 |
|
|
|
a1c947 |
if (flags & VIR_MIGRATE_POSTCOPY_RESUME) {
|
|
|
a1c947 |
ret = qemuMigrationSrcResume(vm, migParams, cookiein, cookieinlen,
|
|
|
a1c947 |
- cookieout, cookieoutlen, &spec);
|
|
|
a1c947 |
+ cookieout, cookieoutlen, &spec, flags);
|
|
|
a1c947 |
} else {
|
|
|
a1c947 |
ret = qemuMigrationSrcRun(driver, vm, persist_xml, cookiein, cookieinlen,
|
|
|
a1c947 |
cookieout, cookieoutlen, flags, resource,
|
|
|
a1c947 |
diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c
|
|
|
a1c947 |
index a68aed9aa4..6ea0bde13a 100644
|
|
|
a1c947 |
--- a/src/qemu/qemu_migration_params.c
|
|
|
a1c947 |
+++ b/src/qemu/qemu_migration_params.c
|
|
|
a1c947 |
@@ -141,6 +141,7 @@ struct _qemuMigrationParamsTPMapItem {
|
|
|
a1c947 |
typedef struct _qemuMigrationParamInfoItem qemuMigrationParamInfoItem;
|
|
|
a1c947 |
struct _qemuMigrationParamInfoItem {
|
|
|
a1c947 |
qemuMigrationParamType type;
|
|
|
a1c947 |
+ bool applyOnPostcopyResume;
|
|
|
a1c947 |
};
|
|
|
a1c947 |
|
|
|
a1c947 |
/* Migration capabilities which should always be enabled as long as they
|
|
|
a1c947 |
@@ -265,6 +266,7 @@ static const qemuMigrationParamInfoItem qemuMigrationParamInfo[] = {
|
|
|
a1c947 |
},
|
|
|
a1c947 |
[QEMU_MIGRATION_PARAM_MAX_POSTCOPY_BANDWIDTH] = {
|
|
|
a1c947 |
.type = QEMU_MIGRATION_PARAM_TYPE_ULL,
|
|
|
a1c947 |
+ .applyOnPostcopyResume = true,
|
|
|
a1c947 |
},
|
|
|
a1c947 |
[QEMU_MIGRATION_PARAM_MULTIFD_CHANNELS] = {
|
|
|
a1c947 |
.type = QEMU_MIGRATION_PARAM_TYPE_INT,
|
|
|
a1c947 |
@@ -782,7 +784,8 @@ qemuMigrationParamsFromJSON(virJSONValue *params)
|
|
|
a1c947 |
|
|
|
a1c947 |
|
|
|
a1c947 |
virJSONValue *
|
|
|
a1c947 |
-qemuMigrationParamsToJSON(qemuMigrationParams *migParams)
|
|
|
a1c947 |
+qemuMigrationParamsToJSON(qemuMigrationParams *migParams,
|
|
|
a1c947 |
+ bool postcopyResume)
|
|
|
a1c947 |
{
|
|
|
a1c947 |
g_autoptr(virJSONValue) params = virJSONValueNewObject();
|
|
|
a1c947 |
size_t i;
|
|
|
a1c947 |
@@ -795,6 +798,9 @@ qemuMigrationParamsToJSON(qemuMigrationParams *migParams)
|
|
|
a1c947 |
if (!pv->set)
|
|
|
a1c947 |
continue;
|
|
|
a1c947 |
|
|
|
a1c947 |
+ if (postcopyResume && !qemuMigrationParamInfo[i].applyOnPostcopyResume)
|
|
|
a1c947 |
+ continue;
|
|
|
a1c947 |
+
|
|
|
a1c947 |
switch (qemuMigrationParamInfo[i].type) {
|
|
|
a1c947 |
case QEMU_MIGRATION_PARAM_TYPE_INT:
|
|
|
a1c947 |
rc = virJSONValueObjectAppendNumberInt(params, name, pv->value.i);
|
|
|
a1c947 |
@@ -868,6 +874,7 @@ qemuMigrationCapsToJSON(virBitmap *caps,
|
|
|
a1c947 |
*
|
|
|
a1c947 |
* Send parameters stored in @migParams to QEMU. If @apiFlags is non-zero, some
|
|
|
a1c947 |
* parameters that do not make sense for the enabled flags will be ignored.
|
|
|
a1c947 |
+ * VIR_MIGRATE_POSTCOPY_RESUME is the only flag checked currently.
|
|
|
a1c947 |
*
|
|
|
a1c947 |
* Returns 0 on success, -1 on failure.
|
|
|
a1c947 |
*/
|
|
|
a1c947 |
@@ -876,32 +883,38 @@ qemuMigrationParamsApply(virQEMUDriver *driver,
|
|
|
a1c947 |
virDomainObj *vm,
|
|
|
a1c947 |
int asyncJob,
|
|
|
a1c947 |
qemuMigrationParams *migParams,
|
|
|
a1c947 |
- unsigned long apiFlags G_GNUC_UNUSED)
|
|
|
a1c947 |
+ unsigned long apiFlags)
|
|
|
a1c947 |
{
|
|
|
a1c947 |
qemuDomainObjPrivate *priv = vm->privateData;
|
|
|
a1c947 |
bool xbzrleCacheSize_old = false;
|
|
|
a1c947 |
g_autoptr(virJSONValue) params = NULL;
|
|
|
a1c947 |
g_autoptr(virJSONValue) caps = NULL;
|
|
|
a1c947 |
qemuMigrationParam xbzrle = QEMU_MIGRATION_PARAM_XBZRLE_CACHE_SIZE;
|
|
|
a1c947 |
+ bool postcopyResume = !!(apiFlags & VIR_MIGRATE_POSTCOPY_RESUME);
|
|
|
a1c947 |
int ret = -1;
|
|
|
a1c947 |
|
|
|
a1c947 |
if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
|
|
|
a1c947 |
return -1;
|
|
|
a1c947 |
|
|
|
a1c947 |
- if (asyncJob == VIR_ASYNC_JOB_NONE) {
|
|
|
a1c947 |
- if (!virBitmapIsAllClear(migParams->caps)) {
|
|
|
a1c947 |
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
a1c947 |
- _("Migration capabilities can only be set by "
|
|
|
a1c947 |
- "a migration job"));
|
|
|
a1c947 |
- goto cleanup;
|
|
|
a1c947 |
- }
|
|
|
a1c947 |
- } else {
|
|
|
a1c947 |
- if (!(caps = qemuMigrationCapsToJSON(priv->migrationCaps, migParams->caps)))
|
|
|
a1c947 |
- goto cleanup;
|
|
|
a1c947 |
+ /* Changing capabilities is only allowed before migration starts, we need
|
|
|
a1c947 |
+ * to skip them when resuming post-copy migration.
|
|
|
a1c947 |
+ */
|
|
|
a1c947 |
+ if (!postcopyResume) {
|
|
|
a1c947 |
+ if (asyncJob == VIR_ASYNC_JOB_NONE) {
|
|
|
a1c947 |
+ if (!virBitmapIsAllClear(migParams->caps)) {
|
|
|
a1c947 |
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
a1c947 |
+ _("Migration capabilities can only be set by "
|
|
|
a1c947 |
+ "a migration job"));
|
|
|
a1c947 |
+ goto cleanup;
|
|
|
a1c947 |
+ }
|
|
|
a1c947 |
+ } else {
|
|
|
a1c947 |
+ if (!(caps = qemuMigrationCapsToJSON(priv->migrationCaps, migParams->caps)))
|
|
|
a1c947 |
+ goto cleanup;
|
|
|
a1c947 |
|
|
|
a1c947 |
- if (virJSONValueArraySize(caps) > 0 &&
|
|
|
a1c947 |
- qemuMonitorSetMigrationCapabilities(priv->mon, &caps) < 0)
|
|
|
a1c947 |
- goto cleanup;
|
|
|
a1c947 |
+ if (virJSONValueArraySize(caps) > 0 &&
|
|
|
a1c947 |
+ qemuMonitorSetMigrationCapabilities(priv->mon, &caps) < 0)
|
|
|
a1c947 |
+ goto cleanup;
|
|
|
a1c947 |
+ }
|
|
|
a1c947 |
}
|
|
|
a1c947 |
|
|
|
a1c947 |
/* If QEMU is too old to support xbzrle-cache-size migration parameter,
|
|
|
a1c947 |
@@ -917,7 +930,7 @@ qemuMigrationParamsApply(virQEMUDriver *driver,
|
|
|
a1c947 |
migParams->params[xbzrle].set = false;
|
|
|
a1c947 |
}
|
|
|
a1c947 |
|
|
|
a1c947 |
- if (!(params = qemuMigrationParamsToJSON(migParams)))
|
|
|
a1c947 |
+ if (!(params = qemuMigrationParamsToJSON(migParams, postcopyResume)))
|
|
|
a1c947 |
goto cleanup;
|
|
|
a1c947 |
|
|
|
a1c947 |
if (virJSONValueObjectKeysNumber(params) > 0 &&
|
|
|
a1c947 |
diff --git a/src/qemu/qemu_migration_paramspriv.h b/src/qemu/qemu_migration_paramspriv.h
|
|
|
a1c947 |
index f7e0f51fbd..34d51231ff 100644
|
|
|
a1c947 |
--- a/src/qemu/qemu_migration_paramspriv.h
|
|
|
a1c947 |
+++ b/src/qemu/qemu_migration_paramspriv.h
|
|
|
a1c947 |
@@ -26,7 +26,8 @@
|
|
|
a1c947 |
#pragma once
|
|
|
a1c947 |
|
|
|
a1c947 |
virJSONValue *
|
|
|
a1c947 |
-qemuMigrationParamsToJSON(qemuMigrationParams *migParams);
|
|
|
a1c947 |
+qemuMigrationParamsToJSON(qemuMigrationParams *migParams,
|
|
|
a1c947 |
+ bool postcopyResume);
|
|
|
a1c947 |
|
|
|
a1c947 |
qemuMigrationParams *
|
|
|
a1c947 |
qemuMigrationParamsFromJSON(virJSONValue *params);
|
|
|
a1c947 |
diff --git a/tests/qemumigparamstest.c b/tests/qemumigparamstest.c
|
|
|
a1c947 |
index bcdee5f32b..5d45a9dd58 100644
|
|
|
a1c947 |
--- a/tests/qemumigparamstest.c
|
|
|
a1c947 |
+++ b/tests/qemumigparamstest.c
|
|
|
a1c947 |
@@ -155,7 +155,7 @@ qemuMigParamsTestJSON(const void *opaque)
|
|
|
a1c947 |
if (!(migParams = qemuMigrationParamsFromJSON(paramsIn)))
|
|
|
a1c947 |
return -1;
|
|
|
a1c947 |
|
|
|
a1c947 |
- if (!(paramsOut = qemuMigrationParamsToJSON(migParams)) ||
|
|
|
a1c947 |
+ if (!(paramsOut = qemuMigrationParamsToJSON(migParams, false)) ||
|
|
|
a1c947 |
!(actualJSON = virJSONValueToString(paramsOut, true)))
|
|
|
a1c947 |
return -1;
|
|
|
a1c947 |
|
|
|
a1c947 |
diff --git a/tests/qemumigrationcookiexmltest.c b/tests/qemumigrationcookiexmltest.c
|
|
|
a1c947 |
index 316bfedd15..9731348b53 100644
|
|
|
a1c947 |
--- a/tests/qemumigrationcookiexmltest.c
|
|
|
a1c947 |
+++ b/tests/qemumigrationcookiexmltest.c
|
|
|
a1c947 |
@@ -333,7 +333,7 @@ testQemuMigrationCookieBlockDirtyBitmaps(const void *opaque)
|
|
|
a1c947 |
|
|
|
a1c947 |
qemuMigrationParamsSetBlockDirtyBitmapMapping(migParams, &migParamsBitmaps);
|
|
|
a1c947 |
|
|
|
a1c947 |
- if (!(paramsOut = qemuMigrationParamsToJSON(migParams)) ||
|
|
|
a1c947 |
+ if (!(paramsOut = qemuMigrationParamsToJSON(migParams, false)) ||
|
|
|
a1c947 |
!(actualJSON = virJSONValueToString(paramsOut, true)))
|
|
|
a1c947 |
return -1;
|
|
|
a1c947 |
|
|
|
a1c947 |
--
|
|
|
a1c947 |
2.35.1
|
|
|
a1c947 |
|