On Fri, Feb 24, 2023 at 17:27:12 +0800, Jiang Jiacheng wrote:
> Add new compress methods zlib and zstd for parallel migration,
> these method should be used with migration option --comp-methods
> and will be processed in 'qemuMigrationParamsSetCompression'.
> Note that only one compress method could be chosen for parallel
> migration and they cann't be used in compress migration.
>
> Signed-off-by: Jiang Jiacheng <[email protected]>
> ---
> src/qemu/qemu_migration.h | 2 +
> src/qemu/qemu_migration_params.c | 80 +++++++++++++++++++++++++++++++-
> src/qemu/qemu_migration_params.h | 3 ++
> 3 files changed, 83 insertions(+), 2 deletions(-)
>
...
> diff --git a/src/qemu/qemu_migration_params.c
> b/src/qemu/qemu_migration_params.c
> index bd09dcfb23..3c224131c5 100644
> --- a/src/qemu/qemu_migration_params.c
> +++ b/src/qemu/qemu_migration_params.c
...
> @@ -504,8 +528,6 @@ qemuMigrationParamsSetTPString(qemuMigrationParams
> *migParams,
> migParams->params[param].value.s);
> }
>
> -
> -
Spurious whitespace change.
> static int
> qemuMigrationParamsSetCompression(virTypedParameterPtr params,
> int nparams,
> @@ -520,6 +542,13 @@ qemuMigrationParamsSetCompression(virTypedParameterPtr
> params,
> if (STRNEQ(params[i].field, VIR_MIGRATE_PARAM_COMPRESSION))
> continue;
>
> + if (migParams->params[QEMU_MIGRATION_PARAM_MULTIFD_COMPRESSION].set)
> {
> + virReportError(VIR_ERR_INVALID_ARG, "%s",
> + _("Only one compression method could be specified
> with "
> + "parallel compression"));
The error message should all be on a single line. And I'd move this
check a bit further below the two new compatibility checks: [1].
> + return -1;
> + }
> +
> method =
> qemuMigrationCompressMethodTypeFromString(params[i].value.s);
> if (method < 0) {
> virReportError(VIR_ERR_INVALID_ARG,
> @@ -535,15 +564,43 @@ qemuMigrationParamsSetCompression(virTypedParameterPtr
> params,
> return -1;
> }
>
> + if ((method == QEMU_MIGRATION_COMPRESS_MT ||
> + method == QEMU_MIGRATION_COMPRESS_XBZRLE) &&
> + flags & VIR_MIGRATE_PARALLEL) {
> + virReportError(VIR_ERR_INVALID_ARG,
> + _("Compression method '%s' isn't supported with
> parallel migration"),
Recent changes (made after you sent this patch) require %1$s format
string to be used instead of %s
> + params[i].value.s);
> + return -1;
> + }
> +
> + if ((method == QEMU_MIGRATION_COMPRESS_ZLIB ||
> + method == QEMU_MIGRATION_COMPRESS_ZSTD) &&
> + flags & VIR_MIGRATE_COMPRESSED) {
> + virReportError(VIR_ERR_INVALID_ARG,
> + _("Compression method '%s' isn't supported with
> compress migration"),
> + params[i].value.s);
> + return -1;
> + }
> +
[1]
> migParams->compMethods |= 1ULL << method;
>
> switch ((qemuMigrationCompressMethod) method) {
> case QEMU_MIGRATION_COMPRESS_XBZRLE:
> cap = QEMU_MIGRATION_CAP_XBZRLE;
> + flags |= VIR_MIGRATE_COMPRESSED;
We do not magically enable flags based on other flags. We just report an
error if the required flag is not set.
> break;
>
> case QEMU_MIGRATION_COMPRESS_MT:
> cap = QEMU_MIGRATION_CAP_COMPRESS;
> + flags |= VIR_MIGRATE_COMPRESSED;
The same here.
> + break;
> +
> + case QEMU_MIGRATION_COMPRESS_ZLIB:
> + case QEMU_MIGRATION_COMPRESS_ZSTD:
> + flags |= VIR_MIGRATE_PARALLEL;
> + cap = QEMU_MIGRATION_CAP_MULTIFD;
And same here (for both flags and cap);
> +
> migParams->params[QEMU_MIGRATION_PARAM_MULTIFD_COMPRESSION].value.s =
> g_strdup(params[i].value.s);
> + migParams->params[QEMU_MIGRATION_PARAM_MULTIFD_COMPRESSION].set
> = true;
> break;
>
> case QEMU_MIGRATION_COMPRESS_LAST:
> @@ -569,6 +626,20 @@ qemuMigrationParamsSetCompression(virTypedParameterPtr
> params,
> return -1;
> }
>
> + if (migParams->params[QEMU_MIGRATION_PARAM_MULTIFD_ZLIB_LEVEL].set &&
> + !(migParams->compMethods & (1ULL << QEMU_MIGRATION_COMPRESS_ZLIB))) {
> + virReportError(VIR_ERR_INVALID_ARG, "%s",
> + _("Turn zlib compression on to tune it"));
> + return -1;
> + }
> +
> + if (migParams->params[QEMU_MIGRATION_PARAM_MULTIFD_ZSTD_LEVEL].set &&
> + !(migParams->compMethods & (1ULL << QEMU_MIGRATION_COMPRESS_ZSTD))) {
> + virReportError(VIR_ERR_INVALID_ARG, "%s",
> + _("Turn zstd compression on to tune it"));
> + return -1;
> + }
> +
The idea was to consistently use
--compressed --comp-method=... --comp-...-...
regardless on selected compression method or whether parallel migration
is turned on or not. Specifically,
--parallel --compressed --comp-method=zlib --comp-zlib-...
--parallel --compressed --comp-method=zstd --comp-zstd-...
--compressed --comp-method=mt --comp-mt-...
--compressed --comp-method=xbzrle,mt --comp-xbzrle-... --comp-mt-...
--compressed
are all ok, while
--compressed --comp-method=zlib
--compressed --comp-method=zstd
should report an error about missing --parallel option and
--parallel --compressed --comp-method=xbzrle
--parallel --compressed --comp-method=mt
should report an error saying the selected method cannot be used with
parallel migration.
Actually looking at the current code (confirmed also by an experiment)
the --compressed parameter is not required. It's mostly a shortcut for a
default method, which is xbzrle for non-parallel migration. The default
for parallel migration is documented as "no compression", which would
mean
--parallel --compressed
is equivalent to
--parallel
I think it would be better to just forbid --compressed with --parallel
unless there is a compression method specified with --comp-method to
avoid a strange semantics of --compressed not providing any compression
at all.
> if (!migParams->compMethods && (flags & VIR_MIGRATE_COMPRESSED)) {
> migParams->compMethods = 1ULL << QEMU_MIGRATION_COMPRESS_XBZRLE;
> ignore_value(virBitmapSetBit(migParams->caps,
> @@ -690,6 +761,11 @@ qemuMigrationParamsDump(qemuMigrationParams *migParams,
> *flags |= VIR_MIGRATE_COMPRESSED;
> }
>
> + if (migParams->compMethods == 1ULL << QEMU_MIGRATION_COMPRESS_ZLIB ||
> + migParams->compMethods == 1ULL << QEMU_MIGRATION_COMPRESS_ZSTD) {
> + *flags |= VIR_MIGRATE_PARALLEL;
> + }
> +
This is not needed as the VIR_MIGRATE_PARALLEL flag has to be set
explicitly.
> for (i = 0; i < QEMU_MIGRATION_COMPRESS_LAST; ++i) {
> if ((migParams->compMethods & (1ULL << i)) &&
> virTypedParamsAddString(params, nparams, maxparams,
> diff --git a/src/qemu/qemu_migration_params.h
> b/src/qemu/qemu_migration_params.h
> index e7c65f6a21..5857673227 100644
> --- a/src/qemu/qemu_migration_params.h
> +++ b/src/qemu/qemu_migration_params.h
> @@ -59,6 +59,9 @@ typedef enum {
> QEMU_MIGRATION_PARAM_XBZRLE_CACHE_SIZE,
> QEMU_MIGRATION_PARAM_MAX_POSTCOPY_BANDWIDTH,
> QEMU_MIGRATION_PARAM_MULTIFD_CHANNELS,
> + QEMU_MIGRATION_PARAM_MULTIFD_COMPRESSION,
> + QEMU_MIGRATION_PARAM_MULTIFD_ZLIB_LEVEL,
> + QEMU_MIGRATION_PARAM_MULTIFD_ZSTD_LEVEL,
>
> QEMU_MIGRATION_PARAM_LAST
> } qemuMigrationParam;
With the following suggested changes
Reviewed-by: Jiri Denemark <[email protected]>
diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c
index ee23cec23d..807cccd86e 100644
--- a/src/qemu/qemu_migration_params.c
+++ b/src/qemu/qemu_migration_params.c
@@ -528,6 +528,8 @@ qemuMigrationParamsSetTPString(qemuMigrationParams
*migParams,
migParams->params[param].value.s);
}
+
+
static int
qemuMigrationParamsSetCompression(virTypedParameterPtr params,
int nparams,
@@ -536,19 +538,11 @@ qemuMigrationParamsSetCompression(virTypedParameterPtr
params,
{
size_t i;
int method;
- qemuMigrationCapability cap;
for (i = 0; i < nparams; i++) {
if (STRNEQ(params[i].field, VIR_MIGRATE_PARAM_COMPRESSION))
continue;
- if (migParams->params[QEMU_MIGRATION_PARAM_MULTIFD_COMPRESSION].set) {
- virReportError(VIR_ERR_INVALID_ARG, "%s",
- _("Only one compression method could be specified
with "
- "parallel compression"));
- return -1;
- }
-
method = qemuMigrationCompressMethodTypeFromString(params[i].value.s);
if (method < 0) {
virReportError(VIR_ERR_INVALID_ARG,
@@ -568,46 +562,47 @@ qemuMigrationParamsSetCompression(virTypedParameterPtr
params,
method == QEMU_MIGRATION_COMPRESS_XBZRLE) &&
flags & VIR_MIGRATE_PARALLEL) {
virReportError(VIR_ERR_INVALID_ARG,
- _("Compression method '%s' isn't supported with
parallel migration"),
+ _("Compression method '%1$s' isn't supported with
parallel migration"),
params[i].value.s);
return -1;
}
if ((method == QEMU_MIGRATION_COMPRESS_ZLIB ||
method == QEMU_MIGRATION_COMPRESS_ZSTD) &&
- flags & VIR_MIGRATE_COMPRESSED) {
+ !(flags & VIR_MIGRATE_PARALLEL)) {
virReportError(VIR_ERR_INVALID_ARG,
- _("Compression method '%s' isn't supported with
compress migration"),
+ _("Compression method '%1$s' is only supported with
parallel migration"),
params[i].value.s);
return -1;
}
+ if (migParams->params[QEMU_MIGRATION_PARAM_MULTIFD_COMPRESSION].set) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("Only one compression method could be specified
with parallel compression"));
+ return -1;
+ }
+
migParams->compMethods |= 1ULL << method;
switch ((qemuMigrationCompressMethod) method) {
case QEMU_MIGRATION_COMPRESS_XBZRLE:
- cap = QEMU_MIGRATION_CAP_XBZRLE;
- flags |= VIR_MIGRATE_COMPRESSED;
+ ignore_value(virBitmapSetBit(migParams->caps,
QEMU_MIGRATION_CAP_XBZRLE));
break;
case QEMU_MIGRATION_COMPRESS_MT:
- cap = QEMU_MIGRATION_CAP_COMPRESS;
- flags |= VIR_MIGRATE_COMPRESSED;
+ ignore_value(virBitmapSetBit(migParams->caps,
QEMU_MIGRATION_CAP_COMPRESS));
break;
case QEMU_MIGRATION_COMPRESS_ZLIB:
case QEMU_MIGRATION_COMPRESS_ZSTD:
- flags |= VIR_MIGRATE_PARALLEL;
- cap = QEMU_MIGRATION_CAP_MULTIFD;
migParams->params[QEMU_MIGRATION_PARAM_MULTIFD_COMPRESSION].value.s =
g_strdup(params[i].value.s);
migParams->params[QEMU_MIGRATION_PARAM_MULTIFD_COMPRESSION].set =
true;
break;
case QEMU_MIGRATION_COMPRESS_LAST:
default:
- continue;
+ break;
}
- ignore_value(virBitmapSetBit(migParams->caps, cap));
}
if ((migParams->params[QEMU_MIGRATION_PARAM_COMPRESS_LEVEL].set ||
@@ -641,6 +636,12 @@ qemuMigrationParamsSetCompression(virTypedParameterPtr
params,
}
if (!migParams->compMethods && (flags & VIR_MIGRATE_COMPRESSED)) {
+ if (flags & VIR_MIGRATE_PARALLEL) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("No compression algorithm selected for parallel
migration"));
+ return -1;
+ }
+
migParams->compMethods = 1ULL << QEMU_MIGRATION_COMPRESS_XBZRLE;
ignore_value(virBitmapSetBit(migParams->caps,
QEMU_MIGRATION_CAP_XBZRLE));
@@ -761,11 +762,6 @@ qemuMigrationParamsDump(qemuMigrationParams *migParams,
*flags |= VIR_MIGRATE_COMPRESSED;
}
- if (migParams->compMethods == 1ULL << QEMU_MIGRATION_COMPRESS_ZLIB ||
- migParams->compMethods == 1ULL << QEMU_MIGRATION_COMPRESS_ZSTD) {
- *flags |= VIR_MIGRATE_PARALLEL;
- }
-
for (i = 0; i < QEMU_MIGRATION_COMPRESS_LAST; ++i) {
if ((migParams->compMethods & (1ULL << i)) &&
virTypedParamsAddString(params, nparams, maxparams,