mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-30 18:50:18 +03:00
qemu: Add support for parallel save and restore
Add support for parallel save and restore by mapping libvirt's "parallel-channels" parameter to QEMU's "multifd-channels" migration parameter. Signed-off-by: Jim Fehlig <jfehlig@suse.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
3637c4dd8b
commit
f0169f4d6c
@ -2579,6 +2579,8 @@ qemuDomainSaveInternal(virQEMUDriver *driver,
|
||||
int format,
|
||||
virCommand *compressor,
|
||||
const char *xmlin,
|
||||
virTypedParameterPtr params,
|
||||
int nparams,
|
||||
unsigned int flags)
|
||||
{
|
||||
g_autofree char *xml = NULL;
|
||||
@ -2668,7 +2670,8 @@ qemuDomainSaveInternal(virQEMUDriver *driver,
|
||||
goto endjob;
|
||||
xml = NULL;
|
||||
|
||||
if (!(saveParams = qemuMigrationParamsForSave(format == QEMU_SAVE_FORMAT_SPARSE,
|
||||
if (!(saveParams = qemuMigrationParamsForSave(params, nparams,
|
||||
format == QEMU_SAVE_FORMAT_SPARSE,
|
||||
flags)))
|
||||
goto endjob;
|
||||
|
||||
@ -2752,7 +2755,7 @@ qemuDomainManagedSaveHelper(virQEMUDriver *driver,
|
||||
VIR_INFO("Saving state of domain '%s' to '%s'", vm->def->name, path);
|
||||
|
||||
if (qemuDomainSaveInternal(driver, vm, path, cfg->saveImageFormat,
|
||||
compressor, dxml, flags) < 0)
|
||||
compressor, dxml, NULL, 0, flags) < 0)
|
||||
return -1;
|
||||
|
||||
vm->hasManagedSave = true;
|
||||
@ -2788,7 +2791,7 @@ qemuDomainSaveFlags(virDomainPtr dom, const char *path, const char *dxml,
|
||||
goto cleanup;
|
||||
|
||||
ret = qemuDomainSaveInternal(driver, vm, path, cfg->saveImageFormat,
|
||||
compressor, dxml, flags);
|
||||
compressor, dxml, NULL, 0, flags);
|
||||
|
||||
cleanup:
|
||||
virDomainObjEndAPI(&vm);
|
||||
@ -2819,7 +2822,8 @@ qemuDomainSaveParams(virDomainPtr dom,
|
||||
|
||||
virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE |
|
||||
VIR_DOMAIN_SAVE_RUNNING |
|
||||
VIR_DOMAIN_SAVE_PAUSED, -1);
|
||||
VIR_DOMAIN_SAVE_PAUSED |
|
||||
VIR_DOMAIN_SAVE_PARALLEL, -1);
|
||||
|
||||
if (virTypedParamsValidate(params, nparams,
|
||||
VIR_DOMAIN_SAVE_PARAM_FILE,
|
||||
@ -2828,6 +2832,8 @@ qemuDomainSaveParams(virDomainPtr dom,
|
||||
VIR_TYPED_PARAM_STRING,
|
||||
VIR_DOMAIN_SAVE_PARAM_IMAGE_FORMAT,
|
||||
VIR_TYPED_PARAM_STRING,
|
||||
VIR_DOMAIN_SAVE_PARAM_PARALLEL_CHANNELS,
|
||||
VIR_TYPED_PARAM_INT,
|
||||
NULL) < 0)
|
||||
return -1;
|
||||
|
||||
@ -2865,7 +2871,7 @@ qemuDomainSaveParams(virDomainPtr dom,
|
||||
goto cleanup;
|
||||
|
||||
ret = qemuDomainSaveInternal(driver, vm, to, format,
|
||||
compressor, dxml, flags);
|
||||
compressor, dxml, params, nparams, flags);
|
||||
|
||||
cleanup:
|
||||
virDomainObjEndAPI(&vm);
|
||||
@ -5733,6 +5739,8 @@ static int
|
||||
qemuDomainRestoreInternal(virConnectPtr conn,
|
||||
const char *path,
|
||||
const char *dxml,
|
||||
virTypedParameterPtr params,
|
||||
int nparams,
|
||||
unsigned int flags,
|
||||
int (*ensureACL)(virConnectPtr, virDomainDef *))
|
||||
{
|
||||
@ -5754,7 +5762,8 @@ qemuDomainRestoreInternal(virConnectPtr conn,
|
||||
virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE |
|
||||
VIR_DOMAIN_SAVE_RUNNING |
|
||||
VIR_DOMAIN_SAVE_PAUSED |
|
||||
VIR_DOMAIN_SAVE_RESET_NVRAM, -1);
|
||||
VIR_DOMAIN_SAVE_RESET_NVRAM |
|
||||
VIR_DOMAIN_SAVE_PARALLEL, -1);
|
||||
|
||||
if (flags & VIR_DOMAIN_SAVE_RESET_NVRAM)
|
||||
reset_nvram = true;
|
||||
@ -5763,7 +5772,7 @@ qemuDomainRestoreInternal(virConnectPtr conn,
|
||||
goto cleanup;
|
||||
|
||||
sparse = data->header.format == QEMU_SAVE_FORMAT_SPARSE;
|
||||
if (!(restoreParams = qemuMigrationParamsForSave(sparse, flags)))
|
||||
if (!(restoreParams = qemuMigrationParamsForSave(params, nparams, sparse, flags)))
|
||||
goto cleanup;
|
||||
|
||||
fd = qemuSaveImageOpen(driver, path,
|
||||
@ -5845,7 +5854,7 @@ qemuDomainRestoreFlags(virConnectPtr conn,
|
||||
const char *dxml,
|
||||
unsigned int flags)
|
||||
{
|
||||
return qemuDomainRestoreInternal(conn, path, dxml, flags,
|
||||
return qemuDomainRestoreInternal(conn, path, dxml, NULL, 0, flags,
|
||||
virDomainRestoreFlagsEnsureACL);
|
||||
}
|
||||
|
||||
@ -5853,7 +5862,7 @@ static int
|
||||
qemuDomainRestore(virConnectPtr conn,
|
||||
const char *path)
|
||||
{
|
||||
return qemuDomainRestoreInternal(conn, path, NULL, 0,
|
||||
return qemuDomainRestoreInternal(conn, path, NULL, NULL, 0, 0,
|
||||
virDomainRestoreEnsureACL);
|
||||
}
|
||||
|
||||
@ -5869,6 +5878,7 @@ qemuDomainRestoreParams(virConnectPtr conn,
|
||||
if (virTypedParamsValidate(params, nparams,
|
||||
VIR_DOMAIN_SAVE_PARAM_FILE, VIR_TYPED_PARAM_STRING,
|
||||
VIR_DOMAIN_SAVE_PARAM_DXML, VIR_TYPED_PARAM_STRING,
|
||||
VIR_DOMAIN_SAVE_PARAM_PARALLEL_CHANNELS, VIR_TYPED_PARAM_INT,
|
||||
NULL) < 0)
|
||||
return -1;
|
||||
|
||||
@ -5885,7 +5895,7 @@ qemuDomainRestoreParams(virConnectPtr conn,
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = qemuDomainRestoreInternal(conn, path, dxml, flags,
|
||||
ret = qemuDomainRestoreInternal(conn, path, dxml, params, nparams, flags,
|
||||
virDomainRestoreParamsEnsureACL);
|
||||
return ret;
|
||||
}
|
||||
@ -6097,7 +6107,7 @@ qemuDomainObjRestore(virConnectPtr conn,
|
||||
}
|
||||
|
||||
sparse = data->header.format == QEMU_SAVE_FORMAT_SPARSE;
|
||||
if (!(restoreParams = qemuMigrationParamsForSave(sparse,
|
||||
if (!(restoreParams = qemuMigrationParamsForSave(NULL, 0, sparse,
|
||||
bypass_cache ? VIR_DOMAIN_SAVE_BYPASS_CACHE : 0)))
|
||||
return -1;
|
||||
|
||||
|
@ -797,10 +797,19 @@ qemuMigrationParamsFromFlags(virTypedParameterPtr params,
|
||||
|
||||
|
||||
qemuMigrationParams *
|
||||
qemuMigrationParamsForSave(bool sparse, unsigned int flags)
|
||||
qemuMigrationParamsForSave(virTypedParameterPtr params,
|
||||
int nparams,
|
||||
bool sparse,
|
||||
unsigned int flags)
|
||||
{
|
||||
g_autoptr(qemuMigrationParams) saveParams = NULL;
|
||||
|
||||
if (flags & VIR_DOMAIN_SAVE_PARALLEL && !sparse) {
|
||||
virReportError(VIR_ERR_INVALID_ARG, "%s",
|
||||
_("Parallel save is only supported with the 'sparse' save image format"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(saveParams = qemuMigrationParamsNew()))
|
||||
return NULL;
|
||||
|
||||
@ -809,7 +818,25 @@ qemuMigrationParamsForSave(bool sparse, unsigned int flags)
|
||||
return NULL;
|
||||
if (virBitmapSetBit(saveParams->caps, QEMU_MIGRATION_CAP_MULTIFD) < 0)
|
||||
return NULL;
|
||||
saveParams->params[QEMU_MIGRATION_PARAM_MULTIFD_CHANNELS].value.i = 1;
|
||||
|
||||
if (flags & VIR_DOMAIN_SAVE_PARALLEL) {
|
||||
int nchannels;
|
||||
|
||||
if (params && virTypedParamsGetInt(params, nparams,
|
||||
VIR_DOMAIN_SAVE_PARAM_PARALLEL_CHANNELS,
|
||||
&nchannels) < 0)
|
||||
return NULL;
|
||||
|
||||
if (nchannels < 1) {
|
||||
virReportError(VIR_ERR_INVALID_ARG, "%s",
|
||||
_("number of parallel save channels cannot be less than 1"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
saveParams->params[QEMU_MIGRATION_PARAM_MULTIFD_CHANNELS].value.i = nchannels;
|
||||
} else {
|
||||
saveParams->params[QEMU_MIGRATION_PARAM_MULTIFD_CHANNELS].value.i = 1;
|
||||
}
|
||||
saveParams->params[QEMU_MIGRATION_PARAM_MULTIFD_CHANNELS].set = true;
|
||||
|
||||
if (flags & VIR_DOMAIN_SAVE_BYPASS_CACHE) {
|
||||
|
@ -89,7 +89,10 @@ qemuMigrationParamsFromFlags(virTypedParameterPtr params,
|
||||
qemuMigrationParty party);
|
||||
|
||||
qemuMigrationParams *
|
||||
qemuMigrationParamsForSave(bool sparse, unsigned int flags);
|
||||
qemuMigrationParamsForSave(virTypedParameterPtr params,
|
||||
int nparams,
|
||||
bool sparse,
|
||||
unsigned int flags);
|
||||
|
||||
int
|
||||
qemuMigrationParamsDump(qemuMigrationParams *migParams,
|
||||
|
Loading…
x
Reference in New Issue
Block a user