qemu: support set parallel migration compression method

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 <jiangjiacheng@huawei.com>
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
This commit is contained in:
Jiang Jiacheng 2023-02-24 17:27:12 +08:00 committed by Jiri Denemark
parent 4ab5591c95
commit ffa258a39d
3 changed files with 82 additions and 5 deletions

View File

@ -86,6 +86,8 @@
VIR_MIGRATE_PARAM_AUTO_CONVERGE_INCREMENT, VIR_TYPED_PARAM_INT, \ VIR_MIGRATE_PARAM_AUTO_CONVERGE_INCREMENT, VIR_TYPED_PARAM_INT, \
VIR_MIGRATE_PARAM_BANDWIDTH_POSTCOPY, VIR_TYPED_PARAM_ULLONG, \ VIR_MIGRATE_PARAM_BANDWIDTH_POSTCOPY, VIR_TYPED_PARAM_ULLONG, \
VIR_MIGRATE_PARAM_PARALLEL_CONNECTIONS, VIR_TYPED_PARAM_INT, \ VIR_MIGRATE_PARAM_PARALLEL_CONNECTIONS, VIR_TYPED_PARAM_INT, \
VIR_MIGRATE_PARAM_COMPRESSION_ZLIB_LEVEL, VIR_TYPED_PARAM_INT, \
VIR_MIGRATE_PARAM_COMPRESSION_ZSTD_LEVEL, VIR_TYPED_PARAM_INT, \
VIR_MIGRATE_PARAM_TLS_DESTINATION, VIR_TYPED_PARAM_STRING, \ VIR_MIGRATE_PARAM_TLS_DESTINATION, VIR_TYPED_PARAM_STRING, \
VIR_MIGRATE_PARAM_DISKS_URI, VIR_TYPED_PARAM_STRING, \ VIR_MIGRATE_PARAM_DISKS_URI, VIR_TYPED_PARAM_STRING, \
NULL NULL

View File

@ -71,6 +71,8 @@ struct _qemuMigrationParams {
typedef enum { typedef enum {
QEMU_MIGRATION_COMPRESS_XBZRLE = 0, QEMU_MIGRATION_COMPRESS_XBZRLE = 0,
QEMU_MIGRATION_COMPRESS_MT, QEMU_MIGRATION_COMPRESS_MT,
QEMU_MIGRATION_COMPRESS_ZLIB,
QEMU_MIGRATION_COMPRESS_ZSTD,
QEMU_MIGRATION_COMPRESS_LAST QEMU_MIGRATION_COMPRESS_LAST
} qemuMigrationCompressMethod; } qemuMigrationCompressMethod;
@ -79,6 +81,8 @@ VIR_ENUM_IMPL(qemuMigrationCompressMethod,
QEMU_MIGRATION_COMPRESS_LAST, QEMU_MIGRATION_COMPRESS_LAST,
"xbzrle", "xbzrle",
"mt", "mt",
"zlib",
"zstd",
); );
VIR_ENUM_IMPL(qemuMigrationCapability, VIR_ENUM_IMPL(qemuMigrationCapability,
@ -114,6 +118,9 @@ VIR_ENUM_IMPL(qemuMigrationParam,
"xbzrle-cache-size", "xbzrle-cache-size",
"max-postcopy-bandwidth", "max-postcopy-bandwidth",
"multifd-channels", "multifd-channels",
"multifd-compression",
"multifd-zlib-level",
"multifd-zstd-level",
); );
typedef struct _qemuMigrationParamsAlwaysOnItem qemuMigrationParamsAlwaysOnItem; typedef struct _qemuMigrationParamsAlwaysOnItem qemuMigrationParamsAlwaysOnItem;
@ -225,6 +232,14 @@ static const qemuMigrationParamsTPMapItem qemuMigrationParamsTPMap[] = {
.param = QEMU_MIGRATION_PARAM_MULTIFD_CHANNELS, .param = QEMU_MIGRATION_PARAM_MULTIFD_CHANNELS,
.party = QEMU_MIGRATION_SOURCE | QEMU_MIGRATION_DESTINATION}, .party = QEMU_MIGRATION_SOURCE | QEMU_MIGRATION_DESTINATION},
{.typedParam = VIR_MIGRATE_PARAM_COMPRESSION_ZLIB_LEVEL,
.param = QEMU_MIGRATION_PARAM_MULTIFD_ZLIB_LEVEL,
.party = QEMU_MIGRATION_SOURCE | QEMU_MIGRATION_DESTINATION},
{.typedParam = VIR_MIGRATE_PARAM_COMPRESSION_ZSTD_LEVEL,
.param = QEMU_MIGRATION_PARAM_MULTIFD_ZSTD_LEVEL,
.party = QEMU_MIGRATION_SOURCE | QEMU_MIGRATION_DESTINATION},
{.typedParam = VIR_MIGRATE_PARAM_TLS_DESTINATION, {.typedParam = VIR_MIGRATE_PARAM_TLS_DESTINATION,
.param = QEMU_MIGRATION_PARAM_TLS_HOSTNAME, .param = QEMU_MIGRATION_PARAM_TLS_HOSTNAME,
.party = QEMU_MIGRATION_SOURCE}, .party = QEMU_MIGRATION_SOURCE},
@ -271,6 +286,15 @@ static const qemuMigrationParamInfoItem qemuMigrationParamInfo[] = {
[QEMU_MIGRATION_PARAM_MULTIFD_CHANNELS] = { [QEMU_MIGRATION_PARAM_MULTIFD_CHANNELS] = {
.type = QEMU_MIGRATION_PARAM_TYPE_INT, .type = QEMU_MIGRATION_PARAM_TYPE_INT,
}, },
[QEMU_MIGRATION_PARAM_MULTIFD_COMPRESSION] = {
.type = QEMU_MIGRATION_PARAM_TYPE_STRING,
},
[QEMU_MIGRATION_PARAM_MULTIFD_ZLIB_LEVEL] = {
.type = QEMU_MIGRATION_PARAM_TYPE_INT,
},
[QEMU_MIGRATION_PARAM_MULTIFD_ZSTD_LEVEL] = {
.type = QEMU_MIGRATION_PARAM_TYPE_INT,
},
}; };
G_STATIC_ASSERT(G_N_ELEMENTS(qemuMigrationParamInfo) == QEMU_MIGRATION_PARAM_LAST); G_STATIC_ASSERT(G_N_ELEMENTS(qemuMigrationParamInfo) == QEMU_MIGRATION_PARAM_LAST);
@ -514,7 +538,6 @@ qemuMigrationParamsSetCompression(virTypedParameterPtr params,
{ {
size_t i; size_t i;
int method; int method;
qemuMigrationCapability cap;
for (i = 0; i < nparams; i++) { for (i = 0; i < nparams; i++) {
if (STRNEQ(params[i].field, VIR_MIGRATE_PARAM_COMPRESSION)) if (STRNEQ(params[i].field, VIR_MIGRATE_PARAM_COMPRESSION))
@ -535,22 +558,51 @@ qemuMigrationParamsSetCompression(virTypedParameterPtr params,
return -1; return -1;
} }
if ((method == QEMU_MIGRATION_COMPRESS_MT ||
method == QEMU_MIGRATION_COMPRESS_XBZRLE) &&
flags & VIR_MIGRATE_PARALLEL) {
virReportError(VIR_ERR_INVALID_ARG,
_("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_PARALLEL)) {
virReportError(VIR_ERR_INVALID_ARG,
_("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; migParams->compMethods |= 1ULL << method;
switch ((qemuMigrationCompressMethod) method) { switch ((qemuMigrationCompressMethod) method) {
case QEMU_MIGRATION_COMPRESS_XBZRLE: case QEMU_MIGRATION_COMPRESS_XBZRLE:
cap = QEMU_MIGRATION_CAP_XBZRLE; ignore_value(virBitmapSetBit(migParams->caps, QEMU_MIGRATION_CAP_XBZRLE));
break; break;
case QEMU_MIGRATION_COMPRESS_MT: case QEMU_MIGRATION_COMPRESS_MT:
cap = QEMU_MIGRATION_CAP_COMPRESS; ignore_value(virBitmapSetBit(migParams->caps, QEMU_MIGRATION_CAP_COMPRESS));
break;
case QEMU_MIGRATION_COMPRESS_ZLIB:
case QEMU_MIGRATION_COMPRESS_ZSTD:
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; break;
case QEMU_MIGRATION_COMPRESS_LAST: case QEMU_MIGRATION_COMPRESS_LAST:
default: default:
continue; break;
} }
ignore_value(virBitmapSetBit(migParams->caps, cap));
} }
if ((migParams->params[QEMU_MIGRATION_PARAM_COMPRESS_LEVEL].set || if ((migParams->params[QEMU_MIGRATION_PARAM_COMPRESS_LEVEL].set ||
@ -569,7 +621,27 @@ qemuMigrationParamsSetCompression(virTypedParameterPtr params,
return -1; 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;
}
if (!migParams->compMethods && (flags & VIR_MIGRATE_COMPRESSED)) { 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; migParams->compMethods = 1ULL << QEMU_MIGRATION_COMPRESS_XBZRLE;
ignore_value(virBitmapSetBit(migParams->caps, ignore_value(virBitmapSetBit(migParams->caps,
QEMU_MIGRATION_CAP_XBZRLE)); QEMU_MIGRATION_CAP_XBZRLE));

View File

@ -59,6 +59,9 @@ typedef enum {
QEMU_MIGRATION_PARAM_XBZRLE_CACHE_SIZE, QEMU_MIGRATION_PARAM_XBZRLE_CACHE_SIZE,
QEMU_MIGRATION_PARAM_MAX_POSTCOPY_BANDWIDTH, QEMU_MIGRATION_PARAM_MAX_POSTCOPY_BANDWIDTH,
QEMU_MIGRATION_PARAM_MULTIFD_CHANNELS, 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 QEMU_MIGRATION_PARAM_LAST
} qemuMigrationParam; } qemuMigrationParam;