[libvirt] [PATCH v2 00/73] qemu: Refactor migration parameters

This series changes the way we handle migration parameters and capabilities with several goals: - make it all consistent and avoid storing the same parameters in several structs - reduce the number of QMP commands we use for setting migration capabilities - concentrate the logic in a separate file and make the code for migration parameters and capabilities in qemu_migration.c less complicated - reset all parameters and capabilities at the end of migration - make adding new parameters and capabilities easier Version 2: - qemuDomainCheckMigrationCapabilities is moved to qemu_migration_params.c (rather than to qemu_migration.c) - supported migration capabilities are sent via migration cookie so that some caps may be automatically enabled only when both sides support them Jiri Denemark (73): qemu: Rename qemuMigrationAnyCapsGet as qemuMigrationCapsGet qemu: Rename qemuMigrationParams qemu: New file for all APIs related to migration parameters qemu: Move qemuDomainCheckMigrationCapabilities qemu: Move qemuMigrationCapsGet qemu: Reindent qemuMigrationParamsSetEmptyTLS qemu: Make qemuMigrationParamsFree follow common pattern qemu: Allocate struct for migration parameters qemu: Drop qemuMigrationParamsClear qemu: Move qemuMigrationCompression struct qemu: Introduce qemuMigrationParams struct qemu: Reset migration parameters in qemuMigrationSrcCleanup qemu: Store original migration params in job qemu: Typedef struct qemuDomainJobObj qemu: Pass job object to qemuProcessRecoverMigration{In,Out} qemu: Reset all migration parameters qemu: Drop qemuMigrationParamsCheckSetupTLS qemu: Drop qemuMigrationParamsCheckTLSCreds qemu: Rename qemuMigrationParamsSetEmptyTLS qemu: Rename qemuMigrationParamsAddTLSObjects qemu: Set tlsHostname inside qemuMigrationParamsEnableTLS qemu: Hide cfg inside qemuMigrationParamsEnableTLS qemu: Rename qemuMigrationParamsSet qemu: Hide internals of qemuMigrationParams struct qemu: Introduce qemuMonitorSetMigrationCapabilities qemu: Set migration caps via migration params APIs qemu: Do not use qemuMonitorSetMigrationCapability qemu: Drop unused qemuMonitorSetMigrationCapability qemu: Add support for xbzrle-cache-size migration parameter qemu: Set XBZRLE cache size via migration parameters qemu: Move ParamsCheck closer to ParamsApply on Dst side qemu: Move ParamsCheck closer to ParamsApply on Src side qemu: Check supported caps in qemuMigrationParamsCheck qemu: Introduce qemuMigrationParty enum qemu: Use qemuMigrationParamsFromFlags everywhere qemu: Hide qemuMigrationParamsNew qemu: Drop qemuMigrationParamsSetPostCopy qemu: Set always-on migration caps in ParamsCheck qemu: Set migration capabilities automatically qemu: Call qemuMigrationAnyCompressionParse only from driver qemu: Generalize macro for getting VIR_MIGRATE_* typed params qemu: Drop qemuMigrationParamsSetCapability qemu: Move qemuMigrationParamsSetCompression qemu: Move qemuMigrationAnyCompression* qemu: Hide qemuMigrationParamsSetCompression qemu: Replace qemuMigrationAnyCompressionDump qemu: Drop qemuMigrationCompression structure qemu: Introduce qemuMigrationParamsFetch qemu: Limit usage of qemuMonitorMigrationParams qemumonitorjsontest: Drop migration params test util: Introduce virJSONValueObjectStealObject qemu: Move migration parameters JSON parsing qemu: Move migration parameters JSON formatting qemu: Export qemuMigrationParams{To,From}JSON for tests qemu: Move qemuMonitorMigrationParams structure qemu: Refactor qemuMigrationParams qemu: Move migration capabilities JSON formatting qemu: Move qemuMonitorMigrationCaps enum qemu: Add support for sending capabilities in migration cookie qemu: Check remote caps when enabling always-on capabilities qemu: Generalize qemuMigrationParamsGetDowntimeLimit qemu: Set migration parameters automatically qemu: Properly reset migration params when libvirtd restarts tests: Add tests for QEMU migration parameters qemumigparamstest: Add basic test data qemumigparamstest: Add test data for TLS parameters qemu: Store API flags for async jobs in qemuDomainJobObj qemu: Properly avoid cancelling memory-only dump qemu: Drop priv->job.dump_memory_only bool qemu: Drop priv->job.postcopyEnabled bool qemu: Store API flags for async jobs in status XML qemu: Don't delete TLS objects unless TLS migration was requested qemuxml2xmltest: Add status XML tests for migration params po/POTFILES.in | 1 + src/libvirt_private.syms | 1 + src/qemu/Makefile.inc.am | 3 + src/qemu/qemu_domain.c | 110 +- src/qemu/qemu_domain.h | 25 +- src/qemu/qemu_driver.c | 175 ++- src/qemu/qemu_migration.c | 926 ++--------- src/qemu/qemu_migration.h | 66 +- src/qemu/qemu_migration_cookie.c | 136 +- src/qemu/qemu_migration_cookie.h | 15 + src/qemu/qemu_migration_params.c | 1351 +++++++++++++++++ src/qemu/qemu_migration_params.h | 156 ++ src/qemu/qemu_migration_paramspriv.h | 35 + src/qemu/qemu_monitor.c | 76 +- src/qemu/qemu_monitor.h | 56 +- src/qemu/qemu_monitor_json.c | 133 +- src/qemu/qemu_monitor_json.h | 9 +- src/qemu/qemu_process.c | 30 +- src/qemu/qemu_process.h | 3 +- src/util/virjson.c | 8 + src/util/virjson.h | 2 + tests/Makefile.am | 12 + tests/qemumigparamsdata/basic.json | 9 + tests/qemumigparamsdata/basic.reply | 12 + tests/qemumigparamsdata/basic.xml | 11 + tests/qemumigparamsdata/empty.json | 3 + tests/qemumigparamsdata/empty.reply | 5 + tests/qemumigparamsdata/empty.xml | 4 + tests/qemumigparamsdata/tls-enabled.json | 11 + tests/qemumigparamsdata/tls-enabled.reply | 14 + tests/qemumigparamsdata/tls-enabled.xml | 13 + tests/qemumigparamsdata/tls-hostname.json | 11 + tests/qemumigparamsdata/tls-hostname.reply | 14 + tests/qemumigparamsdata/tls-hostname.xml | 13 + tests/qemumigparamsdata/tls.json | 11 + tests/qemumigparamsdata/tls.reply | 14 + tests/qemumigparamsdata/tls.xml | 13 + tests/qemumigparamsdata/unsupported.json | 3 + tests/qemumigparamsdata/unsupported.reply | 7 + tests/qemumigparamsdata/unsupported.xml | 4 + tests/qemumigparamstest.c | 242 +++ tests/qemumonitorjsontest.c | 123 +- .../migration-in-params-in.xml | 400 +++++ .../migration-in-params-out.xml | 1 + .../migration-out-nbd-out.xml | 450 +++++- .../migration-out-params-in.xml | 414 +++++ .../migration-out-params-out.xml | 1 + tests/qemuxml2xmltest.c | 2 + 48 files changed, 3766 insertions(+), 1368 deletions(-) create mode 100644 src/qemu/qemu_migration_params.c create mode 100644 src/qemu/qemu_migration_params.h create mode 100644 src/qemu/qemu_migration_paramspriv.h create mode 100644 tests/qemumigparamsdata/basic.json create mode 100644 tests/qemumigparamsdata/basic.reply create mode 100644 tests/qemumigparamsdata/basic.xml create mode 100644 tests/qemumigparamsdata/empty.json create mode 100644 tests/qemumigparamsdata/empty.reply create mode 100644 tests/qemumigparamsdata/empty.xml create mode 100644 tests/qemumigparamsdata/tls-enabled.json create mode 100644 tests/qemumigparamsdata/tls-enabled.reply create mode 100644 tests/qemumigparamsdata/tls-enabled.xml create mode 100644 tests/qemumigparamsdata/tls-hostname.json create mode 100644 tests/qemumigparamsdata/tls-hostname.reply create mode 100644 tests/qemumigparamsdata/tls-hostname.xml create mode 100644 tests/qemumigparamsdata/tls.json create mode 100644 tests/qemumigparamsdata/tls.reply create mode 100644 tests/qemumigparamsdata/tls.xml create mode 100644 tests/qemumigparamsdata/unsupported.json create mode 100644 tests/qemumigparamsdata/unsupported.reply create mode 100644 tests/qemumigparamsdata/unsupported.xml create mode 100644 tests/qemumigparamstest.c create mode 100644 tests/qemustatusxml2xmldata/migration-in-params-in.xml create mode 120000 tests/qemustatusxml2xmldata/migration-in-params-out.xml mode change 120000 => 100644 tests/qemustatusxml2xmldata/migration-out-nbd-out.xml create mode 100644 tests/qemustatusxml2xmldata/migration-out-params-in.xml create mode 120000 tests/qemustatusxml2xmldata/migration-out-params-out.xml -- 2.17.0

Signed-off-by: Jiri Denemark <jdenemar@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com> --- src/qemu/qemu_driver.c | 4 ++-- src/qemu/qemu_migration.c | 10 +++++----- src/qemu/qemu_migration.h | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 5c31dfdd58..cc431ae045 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -13615,7 +13615,7 @@ qemuDomainMigrateGetCompressionCache(virDomainPtr dom, priv = vm->privateData; - if (!qemuMigrationAnyCapsGet(vm, QEMU_MONITOR_MIGRATION_CAPS_XBZRLE)) { + if (!qemuMigrationCapsGet(vm, QEMU_MONITOR_MIGRATION_CAPS_XBZRLE)) { virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", _("Compressed migration is not supported by " "QEMU binary")); @@ -13666,7 +13666,7 @@ qemuDomainMigrateSetCompressionCache(virDomainPtr dom, priv = vm->privateData; - if (!qemuMigrationAnyCapsGet(vm, QEMU_MONITOR_MIGRATION_CAPS_XBZRLE)) { + if (!qemuMigrationCapsGet(vm, QEMU_MONITOR_MIGRATION_CAPS_XBZRLE)) { virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", _("Compressed migration is not supported by " "QEMU binary")); diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 256b994bd9..3890a29d7e 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -1335,7 +1335,7 @@ qemuMigrationOptionSet(virQEMUDriverPtr driver, qemuDomainObjPrivatePtr priv = vm->privateData; int ret; - if (!qemuMigrationAnyCapsGet(vm, capability)) { + if (!qemuMigrationCapsGet(vm, capability)) { if (!state) { /* Unsupported but we want it off anyway */ return 0; @@ -3869,7 +3869,7 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) goto error; - if (qemuMigrationAnyCapsGet(vm, QEMU_MONITOR_MIGRATION_CAPS_PAUSE_BEFORE_SWITCHOVER) && + if (qemuMigrationCapsGet(vm, QEMU_MONITOR_MIGRATION_CAPS_PAUSE_BEFORE_SWITCHOVER) && qemuMigrationOptionSet(driver, vm, QEMU_MONITOR_MIGRATION_CAPS_PAUSE_BEFORE_SWITCHOVER, true, QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) @@ -6095,7 +6095,7 @@ qemuMigrationParamsReset(virQEMUDriverPtr driver, goto cleanup; for (cap = 0; cap < QEMU_MONITOR_MIGRATION_CAPS_LAST; cap++) { - if (qemuMigrationAnyCapsGet(vm, cap) && + if (qemuMigrationCapsGet(vm, cap) && qemuMigrationOptionSet(driver, vm, cap, false, job) < 0) goto cleanup; } @@ -6160,8 +6160,8 @@ qemuMigrationSrcFetchMirrorStats(virQEMUDriverPtr driver, bool -qemuMigrationAnyCapsGet(virDomainObjPtr vm, - qemuMonitorMigrationCaps cap) +qemuMigrationCapsGet(virDomainObjPtr vm, + qemuMonitorMigrationCaps cap) { qemuDomainObjPrivatePtr priv = vm->privateData; bool enabled = false; diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h index a075aec124..af96854a73 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -309,7 +309,7 @@ qemuMigrationSrcFetchMirrorStats(virQEMUDriverPtr driver, qemuDomainJobInfoPtr jobInfo); bool -qemuMigrationAnyCapsGet(virDomainObjPtr vm, - qemuMonitorMigrationCaps cap); +qemuMigrationCapsGet(virDomainObjPtr vm, + qemuMonitorMigrationCaps cap); #endif /* __QEMU_MIGRATION_H__ */ -- 2.17.0

The function is now called qemuMigrationParamsFromFlags to better reflect what it is doing: taking migration flags and params and producing a struct with QEMU migration parameters. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com> --- src/qemu/qemu_driver.c | 2 +- src/qemu/qemu_migration.c | 6 +++--- src/qemu/qemu_migration.h | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index cc431ae045..f7ad211077 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -12758,7 +12758,7 @@ qemuDomainMigratePerform3Params(virDomainPtr dom, if (nmigrate_disks < 0) goto cleanup; - if (!(migParams = qemuMigrationParams(params, nparams, flags))) + if (!(migParams = qemuMigrationParamsFromFlags(params, nparams, flags))) goto cleanup; if (!(compression = qemuMigrationAnyCompressionParse(params, nparams, flags))) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 3890a29d7e..a0071cc089 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2471,9 +2471,9 @@ qemuMigrationParamsSetEmptyTLS(virQEMUDriverPtr driver, qemuMonitorMigrationParamsPtr -qemuMigrationParams(virTypedParameterPtr params, - int nparams, - unsigned long flags) +qemuMigrationParamsFromFlags(virTypedParameterPtr params, + int nparams, + unsigned long flags) { qemuMonitorMigrationParamsPtr migParams; diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h index af96854a73..3424404dc4 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -143,9 +143,9 @@ void qemuMigrationParamsFree(qemuMonitorMigrationParamsPtr *migParams); qemuMonitorMigrationParamsPtr -qemuMigrationParams(virTypedParameterPtr params, - int nparams, - unsigned long flags); +qemuMigrationParamsFromFlags(virTypedParameterPtr params, + int nparams, + unsigned long flags); int qemuMigrationSrcSetOffline(virQEMUDriverPtr driver, -- 2.17.0

In the end, this will allow us to have most of the logic around migration parameters and capabilities done in one place. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- po/POTFILES.in | 1 + src/qemu/Makefile.inc.am | 2 + src/qemu/qemu_driver.c | 1 + src/qemu/qemu_migration.c | 421 +--------------------------- src/qemu/qemu_migration.h | 24 +- src/qemu/qemu_migration_params.c | 454 +++++++++++++++++++++++++++++++ src/qemu/qemu_migration_params.h | 82 ++++++ src/qemu/qemu_process.c | 1 + 8 files changed, 550 insertions(+), 436 deletions(-) create mode 100644 src/qemu/qemu_migration_params.c create mode 100644 src/qemu/qemu_migration_params.h diff --git a/po/POTFILES.in b/po/POTFILES.in index 0dcd1cab28..be2874487c 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -136,6 +136,7 @@ src/qemu/qemu_hotplug.c src/qemu/qemu_interface.c src/qemu/qemu_migration.c src/qemu/qemu_migration_cookie.c +src/qemu/qemu_migration_params.c src/qemu/qemu_monitor.c src/qemu/qemu_monitor_json.c src/qemu/qemu_monitor_text.c diff --git a/src/qemu/Makefile.inc.am b/src/qemu/Makefile.inc.am index 8ef290a6c1..25706ba4bc 100644 --- a/src/qemu/Makefile.inc.am +++ b/src/qemu/Makefile.inc.am @@ -33,6 +33,8 @@ QEMU_DRIVER_SOURCES = \ qemu/qemu_migration.h \ qemu/qemu_migration_cookie.c \ qemu/qemu_migration_cookie.h \ + qemu/qemu_migration_params.c \ + qemu/qemu_migration_params.h \ qemu/qemu_monitor.c \ qemu/qemu_monitor.h \ qemu/qemu_monitor_text.c \ diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index f7ad211077..519bd767c1 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -57,6 +57,7 @@ #include "qemu_monitor.h" #include "qemu_process.h" #include "qemu_migration.h" +#include "qemu_migration_params.h" #include "qemu_blockjob.h" #include "qemu_security.h" diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index a0071cc089..34eb3eb9e5 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -29,6 +29,7 @@ #include "qemu_migration.h" #include "qemu_migration_cookie.h" +#include "qemu_migration_params.h" #include "qemu_monitor.h" #include "qemu_domain.h" #include "qemu_process.h" @@ -81,8 +82,6 @@ VIR_ENUM_IMPL(qemuMigrationCompressMethod, QEMU_MIGRATION_COMPRESS_LAST, "mt", ); -#define QEMU_MIGRATION_TLS_ALIAS_BASE "libvirt_migrate" - static int qemuMigrationJobStart(virQEMUDriverPtr driver, virDomainObjPtr vm, @@ -115,156 +114,6 @@ qemuMigrationJobFinish(virQEMUDriverPtr driver, virDomainObjPtr obj) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); -/* qemuMigrationParamsCheckTLSCreds - * @driver: pointer to qemu driver - * @vm: domain object - * @asyncJob: migration job to join - * - * Query the migration parameters looking for the 'tls-creds' parameter. - * If found, then we can support setting or clearing the parameters and thus - * can support TLS for migration. - * - * Returns 0 if we were able to successfully fetch the params and - * additionally if the tls-creds parameter exists, saves it in the - * private domain structure. Returns -1 on failure. - */ -static int -qemuMigrationParamsCheckTLSCreds(virQEMUDriverPtr driver, - virDomainObjPtr vm, - qemuDomainAsyncJob asyncJob) -{ - int ret = -1; - qemuDomainObjPrivatePtr priv = vm->privateData; - qemuMonitorMigrationParams migParams = { 0 }; - - if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) - return -1; - - if (qemuMonitorGetMigrationParams(priv->mon, &migParams) < 0) - goto cleanup; - - /* NB: Could steal NULL pointer too! Let caller decide what to do. */ - VIR_STEAL_PTR(priv->migTLSAlias, migParams.tlsCreds); - - ret = 0; - - cleanup: - if (qemuDomainObjExitMonitor(driver, vm) < 0) - ret = -1; - - qemuMigrationParamsClear(&migParams); - - return ret; -} - - -/* qemuMigrationParamsCheckSetupTLS - * @driver: pointer to qemu driver - * @vm: domain object - * @cfg: configuration pointer - * @asyncJob: migration job to join - * - * Check if TLS is possible and set up the environment. Assumes the caller - * desires to use TLS (e.g. caller found VIR_MIGRATE_TLS flag). - * - * Ensure the qemu.conf has been properly configured to add an entry for - * "migrate_tls_x509_cert_dir". Also check if the "tls-creds" parameter - * was present from a query of migration parameters - * - * Returns 0 on success, -1 on error/failure - */ -static int -qemuMigrationParamsCheckSetupTLS(virQEMUDriverPtr driver, - virQEMUDriverConfigPtr cfg, - virDomainObjPtr vm, - qemuDomainAsyncJob asyncJob) -{ - qemuDomainObjPrivatePtr priv = vm->privateData; - - if (!cfg->migrateTLSx509certdir) { - virReportError(VIR_ERR_OPERATION_INVALID, "%s", - _("host migration TLS directory not configured")); - return -1; - } - - if (qemuMigrationParamsCheckTLSCreds(driver, vm, asyncJob) < 0) - return -1; - - if (!priv->migTLSAlias) { - virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", - _("TLS migration is not supported with this " - "QEMU binary")); - return -1; - } - - /* If there's a secret, then grab/store it now using the connection */ - if (cfg->migrateTLSx509secretUUID && - !(priv->migSecinfo = - qemuDomainSecretInfoTLSNew(priv, QEMU_MIGRATION_TLS_ALIAS_BASE, - cfg->migrateTLSx509secretUUID))) - return -1; - - return 0; -} - - -/* qemuMigrationParamsAddTLSObjects - * @driver: pointer to qemu driver - * @vm: domain object - * @cfg: configuration pointer - * @tlsListen: server or client - * @asyncJob: Migration job to join - * @tlsAlias: alias to be generated for TLS object - * @secAlias: alias to be generated for a secinfo object - * @migParams: migration parameters to set - * - * Create the TLS objects for the migration and set the migParams value - * - * Returns 0 on success, -1 on failure - */ -static int -qemuMigrationParamsAddTLSObjects(virQEMUDriverPtr driver, - virDomainObjPtr vm, - virQEMUDriverConfigPtr cfg, - bool tlsListen, - qemuDomainAsyncJob asyncJob, - char **tlsAlias, - char **secAlias, - qemuMonitorMigrationParamsPtr migParams) -{ - qemuDomainObjPrivatePtr priv = vm->privateData; - virJSONValuePtr tlsProps = NULL; - virJSONValuePtr secProps = NULL; - - if (qemuDomainGetTLSObjects(priv->qemuCaps, priv->migSecinfo, - cfg->migrateTLSx509certdir, tlsListen, - cfg->migrateTLSx509verify, - QEMU_MIGRATION_TLS_ALIAS_BASE, - &tlsProps, tlsAlias, &secProps, secAlias) < 0) - goto error; - - /* Ensure the domain doesn't already have the TLS objects defined... - * This should prevent any issues just in case some cleanup wasn't - * properly completed (both src and dst use the same alias) or - * some other error path between now and perform . */ - qemuDomainDelTLSObjects(driver, vm, asyncJob, *secAlias, *tlsAlias); - - if (qemuDomainAddTLSObjects(driver, vm, asyncJob, *secAlias, &secProps, - *tlsAlias, &tlsProps) < 0) - goto error; - - if (VIR_STRDUP(migParams->tlsCreds, *tlsAlias) < 0) - goto error; - - return 0; - - error: - virJSONValueFree(tlsProps); - virJSONValueFree(secProps); - return -1; -} - - static void qemuMigrationSrcStoreDomainState(virDomainObjPtr vm) { @@ -1325,7 +1174,7 @@ qemuMigrationAnyPostcopyFailed(virQEMUDriverPtr driver, } -static int +int qemuMigrationOptionSet(virQEMUDriverPtr driver, virDomainObjPtr vm, qemuMonitorMigrationCaps capability, @@ -2363,238 +2212,6 @@ qemuMigrationDstPrepare(virDomainObjPtr vm, return inc; } -static int -qemuMigrationParamsSetCompression(virQEMUDriverPtr driver, - virDomainObjPtr vm, - qemuDomainAsyncJob job, - qemuMigrationCompressionPtr compression, - qemuMonitorMigrationParamsPtr migParams) -{ - int ret = -1; - qemuDomainObjPrivatePtr priv = vm->privateData; - - if (qemuMigrationOptionSet(driver, vm, - QEMU_MONITOR_MIGRATION_CAPS_XBZRLE, - compression->methods & - (1ULL << QEMU_MIGRATION_COMPRESS_XBZRLE), - job) < 0) - return -1; - - if (qemuMigrationOptionSet(driver, vm, - QEMU_MONITOR_MIGRATION_CAPS_COMPRESS, - compression->methods & - (1ULL << QEMU_MIGRATION_COMPRESS_MT), - job) < 0) - return -1; - - if (qemuDomainObjEnterMonitorAsync(driver, vm, job) < 0) - return -1; - - migParams->compressLevel_set = compression->level_set; - migParams->compressLevel = compression->level; - - migParams->compressThreads_set = compression->threads_set; - migParams->compressThreads = compression->threads; - - migParams->decompressThreads_set = compression->dthreads_set; - migParams->decompressThreads = compression->dthreads; - - if (compression->xbzrle_cache_set && - qemuMonitorSetMigrationCacheSize(priv->mon, - compression->xbzrle_cache) < 0) - goto cleanup; - - ret = 0; - - cleanup: - if (qemuDomainObjExitMonitor(driver, vm) < 0) - ret = -1; - - return ret; -} - - -void -qemuMigrationParamsClear(qemuMonitorMigrationParamsPtr migParams) -{ - if (!migParams) - return; - - VIR_FREE(migParams->tlsCreds); - VIR_FREE(migParams->tlsHostname); -} - - -void -qemuMigrationParamsFree(qemuMonitorMigrationParamsPtr *migParams) -{ - if (!*migParams) - return; - - qemuMigrationParamsClear(*migParams); - VIR_FREE(*migParams); -} - - -/* qemuMigrationParamsSetEmptyTLS - * @driver: pointer to qemu driver - * @vm: domain object - * @asyncJob: migration job to join - * @migParams: Pointer to a migration parameters block - * - * If we support setting the tls-creds, then set both tls-creds and - * tls-hostname to the empty string ("") which indicates to not use - * TLS on this migration. - * - * Returns 0 on success, -1 on failure - */ -static int -qemuMigrationParamsSetEmptyTLS(virQEMUDriverPtr driver, - virDomainObjPtr vm, - qemuDomainAsyncJob asyncJob, - qemuMonitorMigrationParamsPtr migParams) -{ - qemuDomainObjPrivatePtr priv = vm->privateData; - - if (qemuMigrationParamsCheckTLSCreds(driver, vm, asyncJob) < 0) - return -1; - - if (!priv->migTLSAlias) - return 0; - - if (VIR_STRDUP(migParams->tlsCreds, "") < 0 || - VIR_STRDUP(migParams->tlsHostname, "") < 0) - return -1; - - return 0; -} - - -qemuMonitorMigrationParamsPtr -qemuMigrationParamsFromFlags(virTypedParameterPtr params, - int nparams, - unsigned long flags) -{ - qemuMonitorMigrationParamsPtr migParams; - - if (VIR_ALLOC(migParams) < 0) - return NULL; - - if (!params) - return migParams; - -#define GET(PARAM, VAR) \ - do { \ - int rc; \ - if ((rc = virTypedParamsGetInt(params, nparams, \ - VIR_MIGRATE_PARAM_ ## PARAM, \ - &migParams->VAR)) < 0) \ - goto error; \ - \ - if (rc == 1) \ - migParams->VAR ## _set = true; \ - } while (0) - - GET(AUTO_CONVERGE_INITIAL, cpuThrottleInitial); - GET(AUTO_CONVERGE_INCREMENT, cpuThrottleIncrement); - -#undef GET - - if ((migParams->cpuThrottleInitial_set || - migParams->cpuThrottleIncrement_set) && - !(flags & VIR_MIGRATE_AUTO_CONVERGE)) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("Turn auto convergence on to tune it")); - goto error; - } - - return migParams; - - error: - qemuMigrationParamsFree(&migParams); - return NULL; -} - - -static int -qemuMigrationParamsSet(virQEMUDriverPtr driver, - virDomainObjPtr vm, - qemuDomainAsyncJob job, - qemuMonitorMigrationParamsPtr migParams) -{ - qemuDomainObjPrivatePtr priv = vm->privateData; - int ret = -1; - - if (qemuDomainObjEnterMonitorAsync(driver, vm, job) < 0) - return -1; - - if (qemuMonitorSetMigrationParams(priv->mon, migParams) < 0) - goto cleanup; - - ret = 0; - - cleanup: - if (qemuDomainObjExitMonitor(driver, vm) < 0) - ret = -1; - - return ret; -} - - -/* qemuMigrationParamsResetTLS - * @driver: pointer to qemu driver - * @vm: domain object - * @asyncJob: migration job to join - * - * Deconstruct all the setup possibly done for TLS - delete the TLS and - * security objects, free the secinfo, and reset the migration params to "". - * - * Returns 0 on success, -1 on failure - */ -static int -qemuMigrationParamsResetTLS(virQEMUDriverPtr driver, - virDomainObjPtr vm, - qemuDomainAsyncJob asyncJob) -{ - qemuDomainObjPrivatePtr priv = vm->privateData; - char *tlsAlias = NULL; - char *secAlias = NULL; - qemuMonitorMigrationParams migParams = { 0 }; - int ret = -1; - - if (qemuMigrationParamsCheckTLSCreds(driver, vm, asyncJob) < 0) - return -1; - - /* If the tls-creds doesn't exist or if they're set to "" then there's - * nothing to do since we never set anything up */ - if (!priv->migTLSAlias || !*priv->migTLSAlias) - return 0; - - /* NB: If either or both fail to allocate memory we can still proceed - * since the next time we migrate another deletion attempt will be - * made after successfully generating the aliases. */ - tlsAlias = qemuAliasTLSObjFromSrcAlias(QEMU_MIGRATION_TLS_ALIAS_BASE); - secAlias = qemuDomainGetSecretAESAlias(QEMU_MIGRATION_TLS_ALIAS_BASE, false); - - qemuDomainDelTLSObjects(driver, vm, asyncJob, secAlias, tlsAlias); - qemuDomainSecretInfoFree(&priv->migSecinfo); - - if (VIR_STRDUP(migParams.tlsCreds, "") < 0 || - VIR_STRDUP(migParams.tlsHostname, "") < 0 || - qemuMigrationParamsSet(driver, vm, asyncJob, &migParams) < 0) - goto cleanup; - - ret = 0; - - cleanup: - VIR_FREE(tlsAlias); - VIR_FREE(secAlias); - qemuMigrationParamsClear(&migParams); - - return ret; -} - - static int qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, virConnectPtr dconn, @@ -6074,40 +5691,6 @@ qemuMigrationAnyCompressionDump(qemuMigrationCompressionPtr compression, } -/* - * qemuMigrationParamsReset: - * - * Reset all migration parameters so that the next job which internally uses - * migration (save, managedsave, snapshots, dump) will not try to use them. - */ -void -qemuMigrationParamsReset(virQEMUDriverPtr driver, - virDomainObjPtr vm, - qemuDomainAsyncJob job) -{ - qemuMonitorMigrationCaps cap; - virErrorPtr err = virSaveLastError(); - - if (!virDomainObjIsActive(vm)) - goto cleanup; - - if (qemuMigrationParamsResetTLS(driver, vm, job) < 0) - goto cleanup; - - for (cap = 0; cap < QEMU_MONITOR_MIGRATION_CAPS_LAST; cap++) { - if (qemuMigrationCapsGet(vm, cap) && - qemuMigrationOptionSet(driver, vm, cap, false, job) < 0) - goto cleanup; - } - - cleanup: - if (err) { - virSetError(err); - virFreeError(err); - } -} - - int qemuMigrationSrcFetchMirrorStats(virQEMUDriverPtr driver, virDomainObjPtr vm, diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h index 3424404dc4..adf788c909 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -34,7 +34,6 @@ * * Exceptions: * - * - qemuMigrationParamsXXX - runs on source or dest host * - qemuMigrationOptionXXX - runs on source or dest host * - qemuMigrationJobXXX - runs on source or dest host */ @@ -136,17 +135,6 @@ qemuMigrationAnyCompressionDump(qemuMigrationCompressionPtr compression, int *maxparams, unsigned long *flags); -void -qemuMigrationParamsClear(qemuMonitorMigrationParamsPtr migParams); - -void -qemuMigrationParamsFree(qemuMonitorMigrationParamsPtr *migParams); - -qemuMonitorMigrationParamsPtr -qemuMigrationParamsFromFlags(virTypedParameterPtr params, - int nparams, - unsigned long flags); - int qemuMigrationSrcSetOffline(virQEMUDriverPtr driver, virDomainObjPtr vm); @@ -297,11 +285,6 @@ void qemuMigrationAnyPostcopyFailed(virQEMUDriverPtr driver, virDomainObjPtr vm); -void -qemuMigrationParamsReset(virQEMUDriverPtr driver, - virDomainObjPtr vm, - qemuDomainAsyncJob job); - int qemuMigrationSrcFetchMirrorStats(virQEMUDriverPtr driver, virDomainObjPtr vm, @@ -312,4 +295,11 @@ bool qemuMigrationCapsGet(virDomainObjPtr vm, qemuMonitorMigrationCaps cap); +int +qemuMigrationOptionSet(virQEMUDriverPtr driver, + virDomainObjPtr vm, + qemuMonitorMigrationCaps capability, + bool state, + qemuDomainAsyncJob job); + #endif /* __QEMU_MIGRATION_H__ */ diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c new file mode 100644 index 0000000000..72ecafd057 --- /dev/null +++ b/src/qemu/qemu_migration_params.c @@ -0,0 +1,454 @@ +/* + * qemu_migration_params.c: QEMU migration parameters handling + * + * Copyright (C) 2006-2018 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include <config.h> + +#include "virlog.h" +#include "virerror.h" +#include "viralloc.h" +#include "virstring.h" + +#include "qemu_alias.h" +#include "qemu_hotplug.h" +#include "qemu_migration.h" +#include "qemu_migration_params.h" + +#define VIR_FROM_THIS VIR_FROM_QEMU + +VIR_LOG_INIT("qemu.qemu_migration_params"); + +#define QEMU_MIGRATION_TLS_ALIAS_BASE "libvirt_migrate" + + +void +qemuMigrationParamsClear(qemuMonitorMigrationParamsPtr migParams) +{ + if (!migParams) + return; + + VIR_FREE(migParams->tlsCreds); + VIR_FREE(migParams->tlsHostname); +} + + +void +qemuMigrationParamsFree(qemuMonitorMigrationParamsPtr *migParams) +{ + if (!*migParams) + return; + + qemuMigrationParamsClear(*migParams); + VIR_FREE(*migParams); +} + + +qemuMonitorMigrationParamsPtr +qemuMigrationParamsFromFlags(virTypedParameterPtr params, + int nparams, + unsigned long flags) +{ + qemuMonitorMigrationParamsPtr migParams; + + if (VIR_ALLOC(migParams) < 0) + return NULL; + + if (!params) + return migParams; + +#define GET(PARAM, VAR) \ + do { \ + int rc; \ + if ((rc = virTypedParamsGetInt(params, nparams, \ + VIR_MIGRATE_PARAM_ ## PARAM, \ + &migParams->VAR)) < 0) \ + goto error; \ + \ + if (rc == 1) \ + migParams->VAR ## _set = true; \ + } while (0) + + GET(AUTO_CONVERGE_INITIAL, cpuThrottleInitial); + GET(AUTO_CONVERGE_INCREMENT, cpuThrottleIncrement); + +#undef GET + + if ((migParams->cpuThrottleInitial_set || + migParams->cpuThrottleIncrement_set) && + !(flags & VIR_MIGRATE_AUTO_CONVERGE)) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("Turn auto convergence on to tune it")); + goto error; + } + + return migParams; + + error: + qemuMigrationParamsFree(&migParams); + return NULL; +} + + +int +qemuMigrationParamsSet(virQEMUDriverPtr driver, + virDomainObjPtr vm, + int asyncJob, + qemuMonitorMigrationParamsPtr migParams) +{ + qemuDomainObjPrivatePtr priv = vm->privateData; + int ret = -1; + + if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) + return -1; + + if (qemuMonitorSetMigrationParams(priv->mon, migParams) < 0) + goto cleanup; + + ret = 0; + + cleanup: + if (qemuDomainObjExitMonitor(driver, vm) < 0) + ret = -1; + + return ret; +} + + +/* qemuMigrationParamsCheckTLSCreds + * @driver: pointer to qemu driver + * @vm: domain object + * @asyncJob: migration job to join + * + * Query the migration parameters looking for the 'tls-creds' parameter. + * If found, then we can support setting or clearing the parameters and thus + * can support TLS for migration. + * + * Returns 0 if we were able to successfully fetch the params and + * additionally if the tls-creds parameter exists, saves it in the + * private domain structure. Returns -1 on failure. + */ +static int +qemuMigrationParamsCheckTLSCreds(virQEMUDriverPtr driver, + virDomainObjPtr vm, + int asyncJob) +{ + int ret = -1; + qemuDomainObjPrivatePtr priv = vm->privateData; + qemuMonitorMigrationParams migParams = { 0 }; + + if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) + return -1; + + if (qemuMonitorGetMigrationParams(priv->mon, &migParams) < 0) + goto cleanup; + + /* NB: Could steal NULL pointer too! Let caller decide what to do. */ + VIR_STEAL_PTR(priv->migTLSAlias, migParams.tlsCreds); + + ret = 0; + + cleanup: + if (qemuDomainObjExitMonitor(driver, vm) < 0) + ret = -1; + + qemuMigrationParamsClear(&migParams); + + return ret; +} + + +/* qemuMigrationParamsCheckSetupTLS + * @driver: pointer to qemu driver + * @vm: domain object + * @cfg: configuration pointer + * @asyncJob: migration job to join + * + * Check if TLS is possible and set up the environment. Assumes the caller + * desires to use TLS (e.g. caller found VIR_MIGRATE_TLS flag). + * + * Ensure the qemu.conf has been properly configured to add an entry for + * "migrate_tls_x509_cert_dir". Also check if the "tls-creds" parameter + * was present from a query of migration parameters + * + * Returns 0 on success, -1 on error/failure + */ +int +qemuMigrationParamsCheckSetupTLS(virQEMUDriverPtr driver, + virQEMUDriverConfigPtr cfg, + virDomainObjPtr vm, + int asyncJob) +{ + qemuDomainObjPrivatePtr priv = vm->privateData; + + if (!cfg->migrateTLSx509certdir) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("host migration TLS directory not configured")); + return -1; + } + + if (qemuMigrationParamsCheckTLSCreds(driver, vm, asyncJob) < 0) + return -1; + + if (!priv->migTLSAlias) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("TLS migration is not supported with this " + "QEMU binary")); + return -1; + } + + /* If there's a secret, then grab/store it now using the connection */ + if (cfg->migrateTLSx509secretUUID && + !(priv->migSecinfo = + qemuDomainSecretInfoTLSNew(priv, QEMU_MIGRATION_TLS_ALIAS_BASE, + cfg->migrateTLSx509secretUUID))) + return -1; + + return 0; +} + + +/* qemuMigrationParamsAddTLSObjects + * @driver: pointer to qemu driver + * @vm: domain object + * @cfg: configuration pointer + * @tlsListen: server or client + * @asyncJob: Migration job to join + * @tlsAlias: alias to be generated for TLS object + * @secAlias: alias to be generated for a secinfo object + * @migParams: migration parameters to set + * + * Create the TLS objects for the migration and set the migParams value + * + * Returns 0 on success, -1 on failure + */ +int +qemuMigrationParamsAddTLSObjects(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virQEMUDriverConfigPtr cfg, + bool tlsListen, + int asyncJob, + char **tlsAlias, + char **secAlias, + qemuMonitorMigrationParamsPtr migParams) +{ + qemuDomainObjPrivatePtr priv = vm->privateData; + virJSONValuePtr tlsProps = NULL; + virJSONValuePtr secProps = NULL; + + if (qemuDomainGetTLSObjects(priv->qemuCaps, priv->migSecinfo, + cfg->migrateTLSx509certdir, tlsListen, + cfg->migrateTLSx509verify, + QEMU_MIGRATION_TLS_ALIAS_BASE, + &tlsProps, tlsAlias, &secProps, secAlias) < 0) + goto error; + + /* Ensure the domain doesn't already have the TLS objects defined... + * This should prevent any issues just in case some cleanup wasn't + * properly completed (both src and dst use the same alias) or + * some other error path between now and perform . */ + qemuDomainDelTLSObjects(driver, vm, asyncJob, *secAlias, *tlsAlias); + + if (qemuDomainAddTLSObjects(driver, vm, asyncJob, *secAlias, &secProps, + *tlsAlias, &tlsProps) < 0) + goto error; + + if (VIR_STRDUP(migParams->tlsCreds, *tlsAlias) < 0) + goto error; + + return 0; + + error: + virJSONValueFree(tlsProps); + virJSONValueFree(secProps); + return -1; +} + + +/* qemuMigrationParamsSetEmptyTLS + * @driver: pointer to qemu driver + * @vm: domain object + * @asyncJob: migration job to join + * @migParams: Pointer to a migration parameters block + * + * If we support setting the tls-creds, then set both tls-creds and + * tls-hostname to the empty string ("") which indicates to not use + * TLS on this migration. + * + * Returns 0 on success, -1 on failure + */ +int +qemuMigrationParamsSetEmptyTLS(virQEMUDriverPtr driver, + virDomainObjPtr vm, + int asyncJob, + qemuMonitorMigrationParamsPtr migParams) +{ + qemuDomainObjPrivatePtr priv = vm->privateData; + + if (qemuMigrationParamsCheckTLSCreds(driver, vm, asyncJob) < 0) + return -1; + + if (!priv->migTLSAlias) + return 0; + + if (VIR_STRDUP(migParams->tlsCreds, "") < 0 || + VIR_STRDUP(migParams->tlsHostname, "") < 0) + return -1; + + return 0; +} + + +int +qemuMigrationParamsSetCompression(virQEMUDriverPtr driver, + virDomainObjPtr vm, + int asyncJob, + qemuMigrationCompressionPtr compression, + qemuMonitorMigrationParamsPtr migParams) +{ + int ret = -1; + qemuDomainObjPrivatePtr priv = vm->privateData; + + if (qemuMigrationOptionSet(driver, vm, + QEMU_MONITOR_MIGRATION_CAPS_XBZRLE, + compression->methods & + (1ULL << QEMU_MIGRATION_COMPRESS_XBZRLE), + asyncJob) < 0) + return -1; + + if (qemuMigrationOptionSet(driver, vm, + QEMU_MONITOR_MIGRATION_CAPS_COMPRESS, + compression->methods & + (1ULL << QEMU_MIGRATION_COMPRESS_MT), + asyncJob) < 0) + return -1; + + if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) + return -1; + + migParams->compressLevel_set = compression->level_set; + migParams->compressLevel = compression->level; + + migParams->compressThreads_set = compression->threads_set; + migParams->compressThreads = compression->threads; + + migParams->decompressThreads_set = compression->dthreads_set; + migParams->decompressThreads = compression->dthreads; + + if (compression->xbzrle_cache_set && + qemuMonitorSetMigrationCacheSize(priv->mon, + compression->xbzrle_cache) < 0) + goto cleanup; + + ret = 0; + + cleanup: + if (qemuDomainObjExitMonitor(driver, vm) < 0) + ret = -1; + + return ret; +} + + +/* qemuMigrationParamsResetTLS + * @driver: pointer to qemu driver + * @vm: domain object + * @asyncJob: migration job to join + * + * Deconstruct all the setup possibly done for TLS - delete the TLS and + * security objects, free the secinfo, and reset the migration params to "". + * + * Returns 0 on success, -1 on failure + */ +static int +qemuMigrationParamsResetTLS(virQEMUDriverPtr driver, + virDomainObjPtr vm, + int asyncJob) +{ + qemuDomainObjPrivatePtr priv = vm->privateData; + char *tlsAlias = NULL; + char *secAlias = NULL; + qemuMonitorMigrationParams migParams = { 0 }; + int ret = -1; + + if (qemuMigrationParamsCheckTLSCreds(driver, vm, asyncJob) < 0) + return -1; + + /* If the tls-creds doesn't exist or if they're set to "" then there's + * nothing to do since we never set anything up */ + if (!priv->migTLSAlias || !*priv->migTLSAlias) + return 0; + + /* NB: If either or both fail to allocate memory we can still proceed + * since the next time we migrate another deletion attempt will be + * made after successfully generating the aliases. */ + tlsAlias = qemuAliasTLSObjFromSrcAlias(QEMU_MIGRATION_TLS_ALIAS_BASE); + secAlias = qemuDomainGetSecretAESAlias(QEMU_MIGRATION_TLS_ALIAS_BASE, false); + + qemuDomainDelTLSObjects(driver, vm, asyncJob, secAlias, tlsAlias); + qemuDomainSecretInfoFree(&priv->migSecinfo); + + if (VIR_STRDUP(migParams.tlsCreds, "") < 0 || + VIR_STRDUP(migParams.tlsHostname, "") < 0 || + qemuMigrationParamsSet(driver, vm, asyncJob, &migParams) < 0) + goto cleanup; + + ret = 0; + + cleanup: + VIR_FREE(tlsAlias); + VIR_FREE(secAlias); + qemuMigrationParamsClear(&migParams); + + return ret; +} + + +/* + * qemuMigrationParamsReset: + * + * Reset all migration parameters so that the next job which internally uses + * migration (save, managedsave, snapshots, dump) will not try to use them. + */ +void +qemuMigrationParamsReset(virQEMUDriverPtr driver, + virDomainObjPtr vm, + int asyncJob) +{ + qemuMonitorMigrationCaps cap; + virErrorPtr err = virSaveLastError(); + + if (!virDomainObjIsActive(vm)) + goto cleanup; + + if (qemuMigrationParamsResetTLS(driver, vm, asyncJob) < 0) + goto cleanup; + + for (cap = 0; cap < QEMU_MONITOR_MIGRATION_CAPS_LAST; cap++) { + if (qemuMigrationCapsGet(vm, cap) && + qemuMigrationOptionSet(driver, vm, cap, false, asyncJob) < 0) + goto cleanup; + } + + cleanup: + if (err) { + virSetError(err); + virFreeError(err); + } +} diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h new file mode 100644 index 0000000000..33b3c27e51 --- /dev/null +++ b/src/qemu/qemu_migration_params.h @@ -0,0 +1,82 @@ +/* + * qemu_migration_params.h: QEMU migration parameters handling + * + * Copyright (C) 2006-2018 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#ifndef __QEMU_MIGRATION_PARAMS_H__ +# define __QEMU_MIGRATION_PARAMS_H__ + +# include "internal.h" + +# include "qemu_monitor.h" +# include "qemu_conf.h" + + +qemuMonitorMigrationParamsPtr +qemuMigrationParamsFromFlags(virTypedParameterPtr params, + int nparams, + unsigned long flags); + +void +qemuMigrationParamsClear(qemuMonitorMigrationParamsPtr migParams); + +void +qemuMigrationParamsFree(qemuMonitorMigrationParamsPtr *migParams); + +int +qemuMigrationParamsSet(virQEMUDriverPtr driver, + virDomainObjPtr vm, + int asyncJob, + qemuMonitorMigrationParamsPtr migParams); + +int +qemuMigrationParamsCheckSetupTLS(virQEMUDriverPtr driver, + virQEMUDriverConfigPtr cfg, + virDomainObjPtr vm, + int asyncJob); + +int +qemuMigrationParamsAddTLSObjects(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virQEMUDriverConfigPtr cfg, + bool tlsListen, + int asyncJob, + char **tlsAlias, + char **secAlias, + qemuMonitorMigrationParamsPtr migParams); + +int +qemuMigrationParamsSetEmptyTLS(virQEMUDriverPtr driver, + virDomainObjPtr vm, + int asyncJob, + qemuMonitorMigrationParamsPtr migParams); + +int +qemuMigrationParamsSetCompression(virQEMUDriverPtr driver, + virDomainObjPtr vm, + int asyncJob, + qemuMigrationCompressionPtr compression, + qemuMonitorMigrationParamsPtr migParams); + +void +qemuMigrationParamsReset(virQEMUDriverPtr driver, + virDomainObjPtr vm, + int asyncJob); + +#endif /* __QEMU_MIGRATION_PARAMS_H__ */ diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index f02114c693..7d678046c8 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -45,6 +45,7 @@ #include "qemu_hostdev.h" #include "qemu_hotplug.h" #include "qemu_migration.h" +#include "qemu_migration_params.h" #include "qemu_interface.h" #include "qemu_security.h" -- 2.17.0

On Wed, Apr 11, 2018 at 04:40:53PM +0200, Jiri Denemark wrote:
In the end, this will allow us to have most of the logic around migration parameters and capabilities done in one place.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- po/POTFILES.in | 1 + src/qemu/Makefile.inc.am | 2 + src/qemu/qemu_driver.c | 1 + src/qemu/qemu_migration.c | 421 +--------------------------- src/qemu/qemu_migration.h | 24 +- src/qemu/qemu_migration_params.c | 454 +++++++++++++++++++++++++++++++ src/qemu/qemu_migration_params.h | 82 ++++++ src/qemu/qemu_process.c | 1 + 8 files changed, 550 insertions(+), 436 deletions(-) create mode 100644 src/qemu/qemu_migration_params.c create mode 100644 src/qemu/qemu_migration_params.h
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Since the function is tightly connected to migration, it was renamed as qemuMigrationCapsCheck and moved to qemu_migration_params.c. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_domain.c | 72 -------------------------------- src/qemu/qemu_domain.h | 4 -- src/qemu/qemu_migration_params.c | 72 ++++++++++++++++++++++++++++++++ src/qemu/qemu_migration_params.h | 5 +++ src/qemu/qemu_process.c | 2 +- 5 files changed, 78 insertions(+), 77 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 100304fd05..84476de11b 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -11798,78 +11798,6 @@ qemuDomainCheckCCWS390AddressSupport(const virDomainDef *def, } -int -qemuDomainCheckMigrationCapabilities(virQEMUDriverPtr driver, - virDomainObjPtr vm, - qemuDomainAsyncJob asyncJob) -{ - qemuDomainObjPrivatePtr priv = vm->privateData; - char **caps = NULL; - char **capStr; - int ret = -1; - int rc; - - if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) - return -1; - - rc = qemuMonitorGetMigrationCapabilities(priv->mon, &caps); - - if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0) - goto cleanup; - - if (!caps) { - ret = 0; - goto cleanup; - } - - priv->migrationCaps = virBitmapNew(QEMU_MONITOR_MIGRATION_CAPS_LAST); - if (!priv->migrationCaps) - goto cleanup; - - for (capStr = caps; *capStr; capStr++) { - int cap = qemuMonitorMigrationCapsTypeFromString(*capStr); - - if (cap < 0) { - VIR_DEBUG("Unknown migration capability: '%s'", *capStr); - } else { - ignore_value(virBitmapSetBit(priv->migrationCaps, cap)); - VIR_DEBUG("Found migration capability: '%s'", *capStr); - } - } - - if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT)) { - if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) - goto cleanup; - - rc = qemuMonitorSetMigrationCapability(priv->mon, - QEMU_MONITOR_MIGRATION_CAPS_EVENTS, - true); - - if (qemuDomainObjExitMonitor(driver, vm) < 0) - goto cleanup; - - if (rc < 0) { - virResetLastError(); - VIR_DEBUG("Cannot enable migration events; clearing capability"); - virQEMUCapsClear(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT); - } - } - - /* Migration events capability must always be enabled, clearing it from - * migration capabilities bitmap makes sure it won't be touched anywhere - * else. - */ - ignore_value(virBitmapClearBit(priv->migrationCaps, - QEMU_MONITOR_MIGRATION_CAPS_EVENTS)); - - ret = 0; - - cleanup: - virStringListFree(caps); - return ret; -} - - /** * qemuDomainPrepareDiskSourceChain: * diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 21e12f6594..415b2ca093 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -988,10 +988,6 @@ bool qemuDomainCheckCCWS390AddressSupport(const virDomainDef *def, const char *devicename); int -qemuDomainCheckMigrationCapabilities(virQEMUDriverPtr driver, - virDomainObjPtr vm, - qemuDomainAsyncJob asyncJob); -int qemuDomainPrepareDiskSourceChain(virDomainDiskDefPtr disk, virStorageSourcePtr src, virQEMUDriverConfigPtr cfg, diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 72ecafd057..461df876db 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -452,3 +452,75 @@ qemuMigrationParamsReset(virQEMUDriverPtr driver, virFreeError(err); } } + + +int +qemuMigrationCapsCheck(virQEMUDriverPtr driver, + virDomainObjPtr vm, + int asyncJob) +{ + qemuDomainObjPrivatePtr priv = vm->privateData; + char **caps = NULL; + char **capStr; + int ret = -1; + int rc; + + if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) + return -1; + + rc = qemuMonitorGetMigrationCapabilities(priv->mon, &caps); + + if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0) + goto cleanup; + + if (!caps) { + ret = 0; + goto cleanup; + } + + priv->migrationCaps = virBitmapNew(QEMU_MONITOR_MIGRATION_CAPS_LAST); + if (!priv->migrationCaps) + goto cleanup; + + for (capStr = caps; *capStr; capStr++) { + int cap = qemuMonitorMigrationCapsTypeFromString(*capStr); + + if (cap < 0) { + VIR_DEBUG("Unknown migration capability: '%s'", *capStr); + } else { + ignore_value(virBitmapSetBit(priv->migrationCaps, cap)); + VIR_DEBUG("Found migration capability: '%s'", *capStr); + } + } + + if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT)) { + if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) + goto cleanup; + + rc = qemuMonitorSetMigrationCapability(priv->mon, + QEMU_MONITOR_MIGRATION_CAPS_EVENTS, + true); + + if (qemuDomainObjExitMonitor(driver, vm) < 0) + goto cleanup; + + if (rc < 0) { + virResetLastError(); + VIR_DEBUG("Cannot enable migration events; clearing capability"); + virQEMUCapsClear(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT); + } + } + + /* Migration events capability must always be enabled, clearing it from + * migration capabilities bitmap makes sure it won't be touched anywhere + * else. + */ + ignore_value(virBitmapClearBit(priv->migrationCaps, + QEMU_MONITOR_MIGRATION_CAPS_EVENTS)); + + ret = 0; + + cleanup: + virStringListFree(caps); + return ret; +} diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index 33b3c27e51..a006357825 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -79,4 +79,9 @@ qemuMigrationParamsReset(virQEMUDriverPtr driver, virDomainObjPtr vm, int asyncJob); +int +qemuMigrationCapsCheck(virQEMUDriverPtr driver, + virDomainObjPtr vm, + int asyncJob); + #endif /* __QEMU_MIGRATION_PARAMS_H__ */ diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 7d678046c8..11276dace9 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -1840,7 +1840,7 @@ qemuConnectMonitor(virQEMUDriverPtr driver, virDomainObjPtr vm, int asyncJob, if (qemuProcessInitMonitor(driver, vm, asyncJob) < 0) return -1; - if (qemuDomainCheckMigrationCapabilities(driver, vm, asyncJob) < 0) + if (qemuMigrationCapsCheck(driver, vm, asyncJob) < 0) return -1; return 0; -- 2.17.0

On Wed, Apr 11, 2018 at 04:40:54PM +0200, Jiri Denemark wrote:
Since the function is tightly connected to migration, it was renamed as qemuMigrationCapsCheck and moved to qemu_migration_params.c.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_domain.c | 72 -------------------------------- src/qemu/qemu_domain.h | 4 -- src/qemu/qemu_migration_params.c | 72 ++++++++++++++++++++++++++++++++ src/qemu/qemu_migration_params.h | 5 +++ src/qemu/qemu_process.c | 2 +- 5 files changed, 78 insertions(+), 77 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

The function is connected with the code which handles migration parameters and capabilities, let's move it to qemu_migration_params.c. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 14 -------------- src/qemu/qemu_migration.h | 4 ---- src/qemu/qemu_migration_params.c | 14 ++++++++++++++ src/qemu/qemu_migration_params.h | 4 ++++ 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 34eb3eb9e5..57903c7b17 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -5740,17 +5740,3 @@ qemuMigrationSrcFetchMirrorStats(virQEMUDriverPtr driver, virHashFree(blockinfo); return 0; } - - -bool -qemuMigrationCapsGet(virDomainObjPtr vm, - qemuMonitorMigrationCaps cap) -{ - qemuDomainObjPrivatePtr priv = vm->privateData; - bool enabled = false; - - if (priv->migrationCaps) - ignore_value(virBitmapGetBit(priv->migrationCaps, cap, &enabled)); - - return enabled; -} diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h index adf788c909..3f33d3013d 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -291,10 +291,6 @@ qemuMigrationSrcFetchMirrorStats(virQEMUDriverPtr driver, qemuDomainAsyncJob asyncJob, qemuDomainJobInfoPtr jobInfo); -bool -qemuMigrationCapsGet(virDomainObjPtr vm, - qemuMonitorMigrationCaps cap); - int qemuMigrationOptionSet(virQEMUDriverPtr driver, virDomainObjPtr vm, diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 461df876db..f78e9ad875 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -524,3 +524,17 @@ qemuMigrationCapsCheck(virQEMUDriverPtr driver, virStringListFree(caps); return ret; } + + +bool +qemuMigrationCapsGet(virDomainObjPtr vm, + qemuMonitorMigrationCaps cap) +{ + qemuDomainObjPrivatePtr priv = vm->privateData; + bool enabled = false; + + if (priv->migrationCaps) + ignore_value(virBitmapGetBit(priv->migrationCaps, cap, &enabled)); + + return enabled; +} diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index a006357825..0a68bc0e39 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -84,4 +84,8 @@ qemuMigrationCapsCheck(virQEMUDriverPtr driver, virDomainObjPtr vm, int asyncJob); +bool +qemuMigrationCapsGet(virDomainObjPtr vm, + qemuMonitorMigrationCaps cap); + #endif /* __QEMU_MIGRATION_PARAMS_H__ */ -- 2.17.0

On Wed, Apr 11, 2018 at 04:40:55PM +0200, Jiri Denemark wrote:
The function is connected with the code which handles migration parameters and capabilities, let's move it to qemu_migration_params.c.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 14 -------------- src/qemu/qemu_migration.h | 4 ---- src/qemu/qemu_migration_params.c | 14 ++++++++++++++ src/qemu/qemu_migration_params.h | 4 ++++ 4 files changed, 18 insertions(+), 18 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index f78e9ad875..36a9fd3509 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -299,17 +299,17 @@ qemuMigrationParamsSetEmptyTLS(virQEMUDriverPtr driver, int asyncJob, qemuMonitorMigrationParamsPtr migParams) { - qemuDomainObjPrivatePtr priv = vm->privateData; + qemuDomainObjPrivatePtr priv = vm->privateData; - if (qemuMigrationParamsCheckTLSCreds(driver, vm, asyncJob) < 0) - return -1; + if (qemuMigrationParamsCheckTLSCreds(driver, vm, asyncJob) < 0) + return -1; - if (!priv->migTLSAlias) - return 0; + if (!priv->migTLSAlias) + return 0; - if (VIR_STRDUP(migParams->tlsCreds, "") < 0 || - VIR_STRDUP(migParams->tlsHostname, "") < 0) - return -1; + if (VIR_STRDUP(migParams->tlsCreds, "") < 0 || + VIR_STRDUP(migParams->tlsHostname, "") < 0) + return -1; return 0; } -- 2.17.0

On Wed, Apr 11, 2018 at 04:40:56PM +0200, Jiri Denemark wrote:
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
Thank you. Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Our *Free functions usually do not take a double pointer and the caller has to make sure it doesn't use the stale pointer after the *Free function returns. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_driver.c | 2 +- src/qemu/qemu_migration_params.c | 10 +++++----- src/qemu/qemu_migration_params.h | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 519bd767c1..bf6c0d0826 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -12781,7 +12781,7 @@ qemuDomainMigratePerform3Params(virDomainPtr dom, flags, dname, bandwidth, true); cleanup: VIR_FREE(compression); - qemuMigrationParamsFree(&migParams); + qemuMigrationParamsFree(migParams); VIR_FREE(migrate_disks); return ret; } diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 36a9fd3509..784b1b9254 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -50,13 +50,13 @@ qemuMigrationParamsClear(qemuMonitorMigrationParamsPtr migParams) void -qemuMigrationParamsFree(qemuMonitorMigrationParamsPtr *migParams) +qemuMigrationParamsFree(qemuMonitorMigrationParamsPtr migParams) { - if (!*migParams) + if (!migParams) return; - qemuMigrationParamsClear(*migParams); - VIR_FREE(*migParams); + qemuMigrationParamsClear(migParams); + VIR_FREE(migParams); } @@ -101,7 +101,7 @@ qemuMigrationParamsFromFlags(virTypedParameterPtr params, return migParams; error: - qemuMigrationParamsFree(&migParams); + qemuMigrationParamsFree(migParams); return NULL; } diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index 0a68bc0e39..1f28d8d606 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -37,7 +37,7 @@ void qemuMigrationParamsClear(qemuMonitorMigrationParamsPtr migParams); void -qemuMigrationParamsFree(qemuMonitorMigrationParamsPtr *migParams); +qemuMigrationParamsFree(qemuMonitorMigrationParamsPtr migParams); int qemuMigrationParamsSet(virQEMUDriverPtr driver, -- 2.17.0

On Wed, Apr 11, 2018 at 04:40:57PM +0200, Jiri Denemark wrote:
Our *Free functions usually do not take a double pointer and the caller has to make sure it doesn't use the stale pointer after the *Free function returns.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_driver.c | 2 +- src/qemu/qemu_migration_params.c | 10 +++++----- src/qemu/qemu_migration_params.h | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

It will get a bit more complicated soon and storing it on a stack with {0} initializer will no longer work. We need a proper constructor. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_driver.c | 20 +++++++++++------ src/qemu/qemu_migration.c | 28 ++++++++++++++--------- src/qemu/qemu_migration_params.c | 38 +++++++++++++++++++++++--------- src/qemu/qemu_migration_params.h | 3 +++ 4 files changed, 61 insertions(+), 28 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index bf6c0d0826..c157ff9bb0 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -12241,7 +12241,7 @@ qemuDomainMigratePerform(virDomainPtr dom, int ret = -1; const char *dconnuri = NULL; qemuMigrationCompressionPtr compression = NULL; - qemuMonitorMigrationParams migParams = { 0 }; + qemuMonitorMigrationParamsPtr migParams = NULL; virCheckFlags(QEMU_MIGRATION_FLAGS, -1); @@ -12252,6 +12252,9 @@ qemuDomainMigratePerform(virDomainPtr dom, goto cleanup; } + if (!(migParams = qemuMigrationParamsNew())) + goto cleanup; + if (!(compression = qemuMigrationAnyCompressionParse(NULL, 0, flags))) goto cleanup; @@ -12276,12 +12279,12 @@ qemuDomainMigratePerform(virDomainPtr dom, */ ret = qemuMigrationSrcPerform(driver, dom->conn, vm, NULL, NULL, dconnuri, uri, NULL, NULL, 0, NULL, 0, - compression, &migParams, cookie, cookielen, + compression, migParams, cookie, cookielen, NULL, NULL, /* No output cookies in v2 */ flags, dname, resource, false); cleanup: - qemuMigrationParamsClear(&migParams); + qemuMigrationParamsFree(migParams); VIR_FREE(compression); return ret; } @@ -12666,13 +12669,16 @@ qemuDomainMigratePerform3(virDomainPtr dom, virQEMUDriverPtr driver = dom->conn->privateData; virDomainObjPtr vm; qemuMigrationCompressionPtr compression = NULL; - qemuMonitorMigrationParams migParams = { 0 }; + qemuMonitorMigrationParamsPtr migParams = NULL; int ret = -1; virCheckFlags(QEMU_MIGRATION_FLAGS, -1); + if (!(migParams = qemuMigrationParamsNew())) + goto cleanup; + if (!(compression = qemuMigrationAnyCompressionParse(NULL, 0, flags))) - return -1; + goto cleanup; if (!(vm = qemuDomObjFromDomain(dom))) goto cleanup; @@ -12684,13 +12690,13 @@ qemuDomainMigratePerform3(virDomainPtr dom, ret = qemuMigrationSrcPerform(driver, dom->conn, vm, xmlin, NULL, dconnuri, uri, NULL, NULL, 0, NULL, 0, - compression, &migParams, + compression, migParams, cookiein, cookieinlen, cookieout, cookieoutlen, flags, dname, resource, true); cleanup: - qemuMigrationParamsClear(&migParams); + qemuMigrationParamsFree(migParams); VIR_FREE(compression); return ret; } diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 57903c7b17..a0061c8c83 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2251,7 +2251,7 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, int rv; char *tlsAlias = NULL; char *secAlias = NULL; - qemuMonitorMigrationParams migParams = { 0 }; + qemuMonitorMigrationParamsPtr migParams = NULL; virNWFilterReadLockFilterUpdates(); @@ -2301,6 +2301,9 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, if (!qemuMigrationSrcIsAllowedHostdev(*def)) goto cleanup; + if (!(migParams = qemuMigrationParamsNew())) + goto cleanup; + /* Let migration hook filter domain XML */ if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) { char *xml; @@ -2445,7 +2448,7 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, } if (qemuMigrationParamsSetCompression(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN, - compression, &migParams) < 0) + compression, migParams) < 0) goto stopjob; /* Migrations using TLS need to add the "tls-creds-x509" object and @@ -2458,17 +2461,17 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, if (qemuMigrationParamsAddTLSObjects(driver, vm, cfg, true, QEMU_ASYNC_JOB_MIGRATION_IN, - &tlsAlias, &secAlias, &migParams) < 0) + &tlsAlias, &secAlias, migParams) < 0) goto stopjob; /* Force reset of 'tls-hostname', it's a source only parameter */ - if (VIR_STRDUP(migParams.tlsHostname, "") < 0) + if (VIR_STRDUP(migParams->tlsHostname, "") < 0) goto stopjob; } else { if (qemuMigrationParamsSetEmptyTLS(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN, - &migParams) < 0) + migParams) < 0) goto stopjob; } @@ -2489,7 +2492,7 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, goto stopjob; if (qemuMigrationParamsSet(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN, - &migParams) < 0) + migParams) < 0) goto stopjob; if (mig->nbd && @@ -2577,7 +2580,7 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, virDomainObjRemoveTransientDef(vm); qemuDomainRemoveInactiveJob(driver, vm); } - qemuMigrationParamsClear(&migParams); + qemuMigrationParamsFree(migParams); virDomainObjEndAPI(&vm); qemuDomainEventQueue(driver, event); qemuMigrationCookieFree(mig); @@ -3881,7 +3884,7 @@ qemuMigrationSrcPerformPeer2Peer2(virQEMUDriverPtr driver, virStreamPtr st = NULL; unsigned long destflags; qemuMigrationCompressionPtr compression = NULL; - qemuMonitorMigrationParams migParams = { 0 }; + qemuMonitorMigrationParamsPtr migParams = NULL; VIR_DEBUG("driver=%p, sconn=%p, dconn=%p, vm=%p, dconnuri=%s, " "flags=0x%lx, dname=%s, resource=%lu", @@ -3903,6 +3906,9 @@ qemuMigrationSrcPerformPeer2Peer2(virQEMUDriverPtr driver, destflags = flags & ~(VIR_MIGRATE_ABORT_ON_ERROR | VIR_MIGRATE_AUTO_CONVERGE); + if (!(migParams = qemuMigrationParamsNew())) + goto cleanup; + if (!(compression = qemuMigrationAnyCompressionParse(NULL, 0, flags))) goto cleanup; @@ -3958,13 +3964,13 @@ qemuMigrationSrcPerformPeer2Peer2(virQEMUDriverPtr driver, ret = qemuMigrationSrcPerformTunnel(driver, vm, st, NULL, NULL, 0, NULL, NULL, flags, resource, dconn, - NULL, 0, NULL, compression, &migParams); + NULL, 0, NULL, compression, migParams); else ret = qemuMigrationSrcPerformNative(driver, vm, NULL, uri_out, cookie, cookielen, NULL, NULL, /* No out cookie with v2 migration */ flags, resource, dconn, NULL, 0, NULL, - compression, &migParams); + compression, migParams); /* Perform failed. Make sure Finish doesn't overwrite the error */ if (ret < 0) @@ -4004,7 +4010,7 @@ qemuMigrationSrcPerformPeer2Peer2(virQEMUDriverPtr driver, virSetError(orig_err); virFreeError(orig_err); } - qemuMigrationParamsClear(&migParams); + qemuMigrationParamsFree(migParams); VIR_FREE(uri_out); VIR_FREE(cookie); VIR_FREE(compression); diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 784b1b9254..95ceed4e14 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -38,6 +38,18 @@ VIR_LOG_INIT("qemu.qemu_migration_params"); #define QEMU_MIGRATION_TLS_ALIAS_BASE "libvirt_migrate" +qemuMonitorMigrationParamsPtr +qemuMigrationParamsNew(void) +{ + qemuMonitorMigrationParamsPtr params; + + if (VIR_ALLOC(params) < 0) + return NULL; + + return params; +} + + void qemuMigrationParamsClear(qemuMonitorMigrationParamsPtr migParams) { @@ -67,7 +79,7 @@ qemuMigrationParamsFromFlags(virTypedParameterPtr params, { qemuMonitorMigrationParamsPtr migParams; - if (VIR_ALLOC(migParams) < 0) + if (!(migParams = qemuMigrationParamsNew())) return NULL; if (!params) @@ -151,16 +163,19 @@ qemuMigrationParamsCheckTLSCreds(virQEMUDriverPtr driver, { int ret = -1; qemuDomainObjPrivatePtr priv = vm->privateData; - qemuMonitorMigrationParams migParams = { 0 }; + qemuMonitorMigrationParamsPtr migParams = NULL; if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) return -1; - if (qemuMonitorGetMigrationParams(priv->mon, &migParams) < 0) + if (!(migParams = qemuMigrationParamsNew())) + goto cleanup; + + if (qemuMonitorGetMigrationParams(priv->mon, migParams) < 0) goto cleanup; /* NB: Could steal NULL pointer too! Let caller decide what to do. */ - VIR_STEAL_PTR(priv->migTLSAlias, migParams.tlsCreds); + VIR_STEAL_PTR(priv->migTLSAlias, migParams->tlsCreds); ret = 0; @@ -168,7 +183,7 @@ qemuMigrationParamsCheckTLSCreds(virQEMUDriverPtr driver, if (qemuDomainObjExitMonitor(driver, vm) < 0) ret = -1; - qemuMigrationParamsClear(&migParams); + qemuMigrationParamsFree(migParams); return ret; } @@ -384,7 +399,7 @@ qemuMigrationParamsResetTLS(virQEMUDriverPtr driver, qemuDomainObjPrivatePtr priv = vm->privateData; char *tlsAlias = NULL; char *secAlias = NULL; - qemuMonitorMigrationParams migParams = { 0 }; + qemuMonitorMigrationParamsPtr migParams = NULL; int ret = -1; if (qemuMigrationParamsCheckTLSCreds(driver, vm, asyncJob) < 0) @@ -395,6 +410,9 @@ qemuMigrationParamsResetTLS(virQEMUDriverPtr driver, if (!priv->migTLSAlias || !*priv->migTLSAlias) return 0; + if (!(migParams = qemuMigrationParamsNew())) + goto cleanup; + /* NB: If either or both fail to allocate memory we can still proceed * since the next time we migrate another deletion attempt will be * made after successfully generating the aliases. */ @@ -404,9 +422,9 @@ qemuMigrationParamsResetTLS(virQEMUDriverPtr driver, qemuDomainDelTLSObjects(driver, vm, asyncJob, secAlias, tlsAlias); qemuDomainSecretInfoFree(&priv->migSecinfo); - if (VIR_STRDUP(migParams.tlsCreds, "") < 0 || - VIR_STRDUP(migParams.tlsHostname, "") < 0 || - qemuMigrationParamsSet(driver, vm, asyncJob, &migParams) < 0) + if (VIR_STRDUP(migParams->tlsCreds, "") < 0 || + VIR_STRDUP(migParams->tlsHostname, "") < 0 || + qemuMigrationParamsSet(driver, vm, asyncJob, migParams) < 0) goto cleanup; ret = 0; @@ -414,7 +432,7 @@ qemuMigrationParamsResetTLS(virQEMUDriverPtr driver, cleanup: VIR_FREE(tlsAlias); VIR_FREE(secAlias); - qemuMigrationParamsClear(&migParams); + qemuMigrationParamsFree(migParams); return ret; } diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index 1f28d8d606..cbc63b9cbf 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -28,6 +28,9 @@ # include "qemu_conf.h" +qemuMonitorMigrationParamsPtr +qemuMigrationParamsNew(void); + qemuMonitorMigrationParamsPtr qemuMigrationParamsFromFlags(virTypedParameterPtr params, int nparams, -- 2.17.0

On Wed, Apr 11, 2018 at 04:40:58PM +0200, Jiri Denemark wrote:
It will get a bit more complicated soon and storing it on a stack with {0} initializer will no longer work. We need a proper constructor.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_driver.c | 20 +++++++++++------ src/qemu/qemu_migration.c | 28 ++++++++++++++--------- src/qemu/qemu_migration_params.c | 38 +++++++++++++++++++++++--------- src/qemu/qemu_migration_params.h | 3 +++ 4 files changed, 61 insertions(+), 28 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

It's no longer used since we do not store the struct on a stack anymore. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 12 +----------- src/qemu/qemu_migration_params.h | 3 --- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 95ceed4e14..c315810728 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -51,23 +51,13 @@ qemuMigrationParamsNew(void) void -qemuMigrationParamsClear(qemuMonitorMigrationParamsPtr migParams) +qemuMigrationParamsFree(qemuMonitorMigrationParamsPtr migParams) { if (!migParams) return; VIR_FREE(migParams->tlsCreds); VIR_FREE(migParams->tlsHostname); -} - - -void -qemuMigrationParamsFree(qemuMonitorMigrationParamsPtr migParams) -{ - if (!migParams) - return; - - qemuMigrationParamsClear(migParams); VIR_FREE(migParams); } diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index cbc63b9cbf..f11315cb9d 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -36,9 +36,6 @@ qemuMigrationParamsFromFlags(virTypedParameterPtr params, int nparams, unsigned long flags); -void -qemuMigrationParamsClear(qemuMonitorMigrationParamsPtr migParams); - void qemuMigrationParamsFree(qemuMonitorMigrationParamsPtr migParams); -- 2.17.0

On Wed, Apr 11, 2018 at 04:40:59PM +0200, Jiri Denemark wrote:
It's no longer used since we do not store the struct on a stack anymore.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 12 +----------- src/qemu/qemu_migration_params.h | 3 --- 2 files changed, 1 insertion(+), 14 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

It provides just another view on some migration parameters so let's move it close to them. The end goal is to merge compression parameters with the rest of migration parameters since it doesn't make any sense to handle them differently. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.h | 20 +------------------- src/qemu/qemu_migration_params.h | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h index 3f33d3013d..4e7b33445b 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -24,6 +24,7 @@ # include "qemu_conf.h" # include "qemu_domain.h" +# include "qemu_migration_params.h" /* * General function naming conventions: @@ -38,9 +39,6 @@ * - qemuMigrationJobXXX - runs on source or dest host */ -typedef struct _qemuMigrationCompression qemuMigrationCompression; -typedef qemuMigrationCompression *qemuMigrationCompressionPtr; - /* All supported qemu migration flags. */ # define QEMU_MIGRATION_FLAGS \ (VIR_MIGRATE_LIVE | \ @@ -108,22 +106,6 @@ typedef enum { } qemuMigrationCompressMethod; VIR_ENUM_DECL(qemuMigrationCompressMethod) -struct _qemuMigrationCompression { - unsigned long long methods; - - bool level_set; - int level; - - bool threads_set; - int threads; - - bool dthreads_set; - int dthreads; - - bool xbzrle_cache_set; - unsigned long long xbzrle_cache; -}; - qemuMigrationCompressionPtr qemuMigrationAnyCompressionParse(virTypedParameterPtr params, int nparams, diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index f11315cb9d..bb38d34cd6 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -28,6 +28,25 @@ # include "qemu_conf.h" +typedef struct _qemuMigrationCompression qemuMigrationCompression; +typedef qemuMigrationCompression *qemuMigrationCompressionPtr; +struct _qemuMigrationCompression { + unsigned long long methods; + + bool level_set; + int level; + + bool threads_set; + int threads; + + bool dthreads_set; + int dthreads; + + bool xbzrle_cache_set; + unsigned long long xbzrle_cache; +}; + + qemuMonitorMigrationParamsPtr qemuMigrationParamsNew(void); -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:00PM +0200, Jiri Denemark wrote:
It provides just another view on some migration parameters so let's move it close to them. The end goal is to merge compression parameters with the rest of migration parameters since it doesn't make any sense to handle them differently.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.h | 20 +------------------- src/qemu/qemu_migration_params.h | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 19 deletions(-)
diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index f11315cb9d..bb38d34cd6 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -28,6 +28,25 @@ # include "qemu_conf.h"
+typedef struct _qemuMigrationCompression qemuMigrationCompression; +typedef qemuMigrationCompression *qemuMigrationCompressionPtr; +struct _qemuMigrationCompression { + unsigned long long methods; + + bool level_set; + int level; + + bool threads_set; + int threads; + + bool dthreads_set; + int dthreads; + + bool xbzrle_cache_set; + unsigned long long xbzrle_cache;
I'm still impressed by your ability to pronounce this [0] Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano [0] https://tools.ietf.org/html/rfc5513#section-2.1

Currently migration parameters are stored in a structure which mimics the QEMU migration parameters handled by query-migrate-parameters and migrate-set-parameters. The new structure will become a libvirt's abstraction on top of QEMU migration parameters, capabilities, and related stuff. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_driver.c | 6 ++-- src/qemu/qemu_migration.c | 26 +++++++------- src/qemu/qemu_migration.h | 2 +- src/qemu/qemu_migration_params.c | 62 ++++++++++++++++---------------- src/qemu/qemu_migration_params.h | 21 +++++++---- 5 files changed, 62 insertions(+), 55 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index c157ff9bb0..6e6fc130c5 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -12241,7 +12241,7 @@ qemuDomainMigratePerform(virDomainPtr dom, int ret = -1; const char *dconnuri = NULL; qemuMigrationCompressionPtr compression = NULL; - qemuMonitorMigrationParamsPtr migParams = NULL; + qemuMigrationParamsPtr migParams = NULL; virCheckFlags(QEMU_MIGRATION_FLAGS, -1); @@ -12669,7 +12669,7 @@ qemuDomainMigratePerform3(virDomainPtr dom, virQEMUDriverPtr driver = dom->conn->privateData; virDomainObjPtr vm; qemuMigrationCompressionPtr compression = NULL; - qemuMonitorMigrationParamsPtr migParams = NULL; + qemuMigrationParamsPtr migParams = NULL; int ret = -1; virCheckFlags(QEMU_MIGRATION_FLAGS, -1); @@ -12725,7 +12725,7 @@ qemuDomainMigratePerform3Params(virDomainPtr dom, unsigned long long bandwidth = 0; int nbdPort = 0; qemuMigrationCompressionPtr compression = NULL; - qemuMonitorMigrationParamsPtr migParams = NULL; + qemuMigrationParamsPtr migParams = NULL; int ret = -1; virCheckFlags(QEMU_MIGRATION_FLAGS, -1); diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index a0061c8c83..055d8a674a 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2251,7 +2251,7 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, int rv; char *tlsAlias = NULL; char *secAlias = NULL; - qemuMonitorMigrationParamsPtr migParams = NULL; + qemuMigrationParamsPtr migParams = NULL; virNWFilterReadLockFilterUpdates(); @@ -2465,7 +2465,7 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, goto stopjob; /* Force reset of 'tls-hostname', it's a source only parameter */ - if (VIR_STRDUP(migParams->tlsHostname, "") < 0) + if (VIR_STRDUP(migParams->params.tlsHostname, "") < 0) goto stopjob; } else { @@ -3337,7 +3337,7 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, size_t nmigrate_disks, const char **migrate_disks, qemuMigrationCompressionPtr compression, - qemuMonitorMigrationParamsPtr migParams) + qemuMigrationParamsPtr migParams) { int ret = -1; unsigned int migrate_flags = QEMU_MONITOR_MIGRATE_BACKGROUND; @@ -3426,11 +3426,11 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, * connect directly to the destination. */ if (spec->destType == MIGRATION_DEST_CONNECT_HOST || spec->destType == MIGRATION_DEST_FD) { - if (VIR_STRDUP(migParams->tlsHostname, spec->dest.host.name) < 0) + if (VIR_STRDUP(migParams->params.tlsHostname, spec->dest.host.name) < 0) goto error; } else { /* Be sure there's nothing from a previous migration */ - if (VIR_STRDUP(migParams->tlsHostname, "") < 0) + if (VIR_STRDUP(migParams->params.tlsHostname, "") < 0) goto error; } } else { @@ -3733,7 +3733,7 @@ qemuMigrationSrcPerformNative(virQEMUDriverPtr driver, size_t nmigrate_disks, const char **migrate_disks, qemuMigrationCompressionPtr compression, - qemuMonitorMigrationParamsPtr migParams) + qemuMigrationParamsPtr migParams) { qemuDomainObjPrivatePtr priv = vm->privateData; virURIPtr uribits = NULL; @@ -3812,7 +3812,7 @@ qemuMigrationSrcPerformTunnel(virQEMUDriverPtr driver, size_t nmigrate_disks, const char **migrate_disks, qemuMigrationCompressionPtr compression, - qemuMonitorMigrationParamsPtr migParams) + qemuMigrationParamsPtr migParams) { int ret = -1; qemuMigrationSpec spec; @@ -3884,7 +3884,7 @@ qemuMigrationSrcPerformPeer2Peer2(virQEMUDriverPtr driver, virStreamPtr st = NULL; unsigned long destflags; qemuMigrationCompressionPtr compression = NULL; - qemuMonitorMigrationParamsPtr migParams = NULL; + qemuMigrationParamsPtr migParams = NULL; VIR_DEBUG("driver=%p, sconn=%p, dconn=%p, vm=%p, dconnuri=%s, " "flags=0x%lx, dname=%s, resource=%lu", @@ -4039,7 +4039,7 @@ qemuMigrationSrcPerformPeer2Peer3(virQEMUDriverPtr driver, const char **migrate_disks, int nbdPort, qemuMigrationCompressionPtr compression, - qemuMonitorMigrationParamsPtr migParams, + qemuMigrationParamsPtr migParams, unsigned long long bandwidth, bool useParams, unsigned long flags) @@ -4398,7 +4398,7 @@ qemuMigrationSrcPerformPeer2Peer(virQEMUDriverPtr driver, const char **migrate_disks, int nbdPort, qemuMigrationCompressionPtr compression, - qemuMonitorMigrationParamsPtr migParams, + qemuMigrationParamsPtr migParams, unsigned long flags, const char *dname, unsigned long resource, @@ -4563,7 +4563,7 @@ qemuMigrationSrcPerformJob(virQEMUDriverPtr driver, const char **migrate_disks, int nbdPort, qemuMigrationCompressionPtr compression, - qemuMonitorMigrationParamsPtr migParams, + qemuMigrationParamsPtr migParams, const char *cookiein, int cookieinlen, char **cookieout, @@ -4676,7 +4676,7 @@ qemuMigrationSrcPerformPhase(virQEMUDriverPtr driver, size_t nmigrate_disks, const char **migrate_disks, qemuMigrationCompressionPtr compression, - qemuMonitorMigrationParamsPtr migParams, + qemuMigrationParamsPtr migParams, const char *cookiein, int cookieinlen, char **cookieout, @@ -4750,7 +4750,7 @@ qemuMigrationSrcPerform(virQEMUDriverPtr driver, const char **migrate_disks, int nbdPort, qemuMigrationCompressionPtr compression, - qemuMonitorMigrationParamsPtr migParams, + qemuMigrationParamsPtr migParams, const char *cookiein, int cookieinlen, char **cookieout, diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h index 4e7b33445b..e59296fd63 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -182,7 +182,7 @@ qemuMigrationSrcPerform(virQEMUDriverPtr driver, const char **migrate_disks, int nbdPort, qemuMigrationCompressionPtr compression, - qemuMonitorMigrationParamsPtr migParams, + qemuMigrationParamsPtr migParams, const char *cookiein, int cookieinlen, char **cookieout, diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index c315810728..3a1816c2b9 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -38,10 +38,10 @@ VIR_LOG_INIT("qemu.qemu_migration_params"); #define QEMU_MIGRATION_TLS_ALIAS_BASE "libvirt_migrate" -qemuMonitorMigrationParamsPtr +qemuMigrationParamsPtr qemuMigrationParamsNew(void) { - qemuMonitorMigrationParamsPtr params; + qemuMigrationParamsPtr params; if (VIR_ALLOC(params) < 0) return NULL; @@ -51,23 +51,23 @@ qemuMigrationParamsNew(void) void -qemuMigrationParamsFree(qemuMonitorMigrationParamsPtr migParams) +qemuMigrationParamsFree(qemuMigrationParamsPtr migParams) { if (!migParams) return; - VIR_FREE(migParams->tlsCreds); - VIR_FREE(migParams->tlsHostname); + VIR_FREE(migParams->params.tlsCreds); + VIR_FREE(migParams->params.tlsHostname); VIR_FREE(migParams); } -qemuMonitorMigrationParamsPtr +qemuMigrationParamsPtr qemuMigrationParamsFromFlags(virTypedParameterPtr params, int nparams, unsigned long flags) { - qemuMonitorMigrationParamsPtr migParams; + qemuMigrationParamsPtr migParams; if (!(migParams = qemuMigrationParamsNew())) return NULL; @@ -80,11 +80,11 @@ qemuMigrationParamsFromFlags(virTypedParameterPtr params, int rc; \ if ((rc = virTypedParamsGetInt(params, nparams, \ VIR_MIGRATE_PARAM_ ## PARAM, \ - &migParams->VAR)) < 0) \ + &migParams->params.VAR)) < 0) \ goto error; \ \ if (rc == 1) \ - migParams->VAR ## _set = true; \ + migParams->params.VAR ## _set = true; \ } while (0) GET(AUTO_CONVERGE_INITIAL, cpuThrottleInitial); @@ -92,8 +92,8 @@ qemuMigrationParamsFromFlags(virTypedParameterPtr params, #undef GET - if ((migParams->cpuThrottleInitial_set || - migParams->cpuThrottleIncrement_set) && + if ((migParams->params.cpuThrottleInitial_set || + migParams->params.cpuThrottleIncrement_set) && !(flags & VIR_MIGRATE_AUTO_CONVERGE)) { virReportError(VIR_ERR_INVALID_ARG, "%s", _("Turn auto convergence on to tune it")); @@ -112,7 +112,7 @@ int qemuMigrationParamsSet(virQEMUDriverPtr driver, virDomainObjPtr vm, int asyncJob, - qemuMonitorMigrationParamsPtr migParams) + qemuMigrationParamsPtr migParams) { qemuDomainObjPrivatePtr priv = vm->privateData; int ret = -1; @@ -120,7 +120,7 @@ qemuMigrationParamsSet(virQEMUDriverPtr driver, if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) return -1; - if (qemuMonitorSetMigrationParams(priv->mon, migParams) < 0) + if (qemuMonitorSetMigrationParams(priv->mon, &migParams->params) < 0) goto cleanup; ret = 0; @@ -153,7 +153,7 @@ qemuMigrationParamsCheckTLSCreds(virQEMUDriverPtr driver, { int ret = -1; qemuDomainObjPrivatePtr priv = vm->privateData; - qemuMonitorMigrationParamsPtr migParams = NULL; + qemuMigrationParamsPtr migParams = NULL; if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) return -1; @@ -161,11 +161,11 @@ qemuMigrationParamsCheckTLSCreds(virQEMUDriverPtr driver, if (!(migParams = qemuMigrationParamsNew())) goto cleanup; - if (qemuMonitorGetMigrationParams(priv->mon, migParams) < 0) + if (qemuMonitorGetMigrationParams(priv->mon, &migParams->params) < 0) goto cleanup; /* NB: Could steal NULL pointer too! Let caller decide what to do. */ - VIR_STEAL_PTR(priv->migTLSAlias, migParams->tlsCreds); + VIR_STEAL_PTR(priv->migTLSAlias, migParams->params.tlsCreds); ret = 0; @@ -251,7 +251,7 @@ qemuMigrationParamsAddTLSObjects(virQEMUDriverPtr driver, int asyncJob, char **tlsAlias, char **secAlias, - qemuMonitorMigrationParamsPtr migParams) + qemuMigrationParamsPtr migParams) { qemuDomainObjPrivatePtr priv = vm->privateData; virJSONValuePtr tlsProps = NULL; @@ -274,7 +274,7 @@ qemuMigrationParamsAddTLSObjects(virQEMUDriverPtr driver, *tlsAlias, &tlsProps) < 0) goto error; - if (VIR_STRDUP(migParams->tlsCreds, *tlsAlias) < 0) + if (VIR_STRDUP(migParams->params.tlsCreds, *tlsAlias) < 0) goto error; return 0; @@ -302,7 +302,7 @@ int qemuMigrationParamsSetEmptyTLS(virQEMUDriverPtr driver, virDomainObjPtr vm, int asyncJob, - qemuMonitorMigrationParamsPtr migParams) + qemuMigrationParamsPtr migParams) { qemuDomainObjPrivatePtr priv = vm->privateData; @@ -312,8 +312,8 @@ qemuMigrationParamsSetEmptyTLS(virQEMUDriverPtr driver, if (!priv->migTLSAlias) return 0; - if (VIR_STRDUP(migParams->tlsCreds, "") < 0 || - VIR_STRDUP(migParams->tlsHostname, "") < 0) + if (VIR_STRDUP(migParams->params.tlsCreds, "") < 0 || + VIR_STRDUP(migParams->params.tlsHostname, "") < 0) return -1; return 0; @@ -325,7 +325,7 @@ qemuMigrationParamsSetCompression(virQEMUDriverPtr driver, virDomainObjPtr vm, int asyncJob, qemuMigrationCompressionPtr compression, - qemuMonitorMigrationParamsPtr migParams) + qemuMigrationParamsPtr migParams) { int ret = -1; qemuDomainObjPrivatePtr priv = vm->privateData; @@ -347,14 +347,14 @@ qemuMigrationParamsSetCompression(virQEMUDriverPtr driver, if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) return -1; - migParams->compressLevel_set = compression->level_set; - migParams->compressLevel = compression->level; + migParams->params.compressLevel_set = compression->level_set; + migParams->params.compressLevel = compression->level; - migParams->compressThreads_set = compression->threads_set; - migParams->compressThreads = compression->threads; + migParams->params.compressThreads_set = compression->threads_set; + migParams->params.compressThreads = compression->threads; - migParams->decompressThreads_set = compression->dthreads_set; - migParams->decompressThreads = compression->dthreads; + migParams->params.decompressThreads_set = compression->dthreads_set; + migParams->params.decompressThreads = compression->dthreads; if (compression->xbzrle_cache_set && qemuMonitorSetMigrationCacheSize(priv->mon, @@ -389,7 +389,7 @@ qemuMigrationParamsResetTLS(virQEMUDriverPtr driver, qemuDomainObjPrivatePtr priv = vm->privateData; char *tlsAlias = NULL; char *secAlias = NULL; - qemuMonitorMigrationParamsPtr migParams = NULL; + qemuMigrationParamsPtr migParams = NULL; int ret = -1; if (qemuMigrationParamsCheckTLSCreds(driver, vm, asyncJob) < 0) @@ -412,8 +412,8 @@ qemuMigrationParamsResetTLS(virQEMUDriverPtr driver, qemuDomainDelTLSObjects(driver, vm, asyncJob, secAlias, tlsAlias); qemuDomainSecretInfoFree(&priv->migSecinfo); - if (VIR_STRDUP(migParams->tlsCreds, "") < 0 || - VIR_STRDUP(migParams->tlsHostname, "") < 0 || + if (VIR_STRDUP(migParams->params.tlsCreds, "") < 0 || + VIR_STRDUP(migParams->params.tlsHostname, "") < 0 || qemuMigrationParamsSet(driver, vm, asyncJob, migParams) < 0) goto cleanup; diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index bb38d34cd6..57b7dd6666 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -47,22 +47,29 @@ struct _qemuMigrationCompression { }; -qemuMonitorMigrationParamsPtr +typedef struct _qemuMigrationParams qemuMigrationParams; +typedef qemuMigrationParams *qemuMigrationParamsPtr; +struct _qemuMigrationParams { + qemuMonitorMigrationParams params; +}; + + +qemuMigrationParamsPtr qemuMigrationParamsNew(void); -qemuMonitorMigrationParamsPtr +qemuMigrationParamsPtr qemuMigrationParamsFromFlags(virTypedParameterPtr params, int nparams, unsigned long flags); void -qemuMigrationParamsFree(qemuMonitorMigrationParamsPtr migParams); +qemuMigrationParamsFree(qemuMigrationParamsPtr migParams); int qemuMigrationParamsSet(virQEMUDriverPtr driver, virDomainObjPtr vm, int asyncJob, - qemuMonitorMigrationParamsPtr migParams); + qemuMigrationParamsPtr migParams); int qemuMigrationParamsCheckSetupTLS(virQEMUDriverPtr driver, @@ -78,20 +85,20 @@ qemuMigrationParamsAddTLSObjects(virQEMUDriverPtr driver, int asyncJob, char **tlsAlias, char **secAlias, - qemuMonitorMigrationParamsPtr migParams); + qemuMigrationParamsPtr migParams); int qemuMigrationParamsSetEmptyTLS(virQEMUDriverPtr driver, virDomainObjPtr vm, int asyncJob, - qemuMonitorMigrationParamsPtr migParams); + qemuMigrationParamsPtr migParams); int qemuMigrationParamsSetCompression(virQEMUDriverPtr driver, virDomainObjPtr vm, int asyncJob, qemuMigrationCompressionPtr compression, - qemuMonitorMigrationParamsPtr migParams); + qemuMigrationParamsPtr migParams); void qemuMigrationParamsReset(virQEMUDriverPtr driver, -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:01PM +0200, Jiri Denemark wrote:
Currently migration parameters are stored in a structure which mimics the QEMU migration parameters handled by query-migrate-parameters and migrate-set-parameters. The new structure will become a libvirt's abstraction on top of QEMU migration parameters, capabilities, and related stuff.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_driver.c | 6 ++-- src/qemu/qemu_migration.c | 26 +++++++------- src/qemu/qemu_migration.h | 2 +- src/qemu/qemu_migration_params.c | 62 ++++++++++++++++---------------- src/qemu/qemu_migration_params.h | 21 +++++++---- 5 files changed, 62 insertions(+), 55 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

When connection to the client which controls a non-p2p migration gets closed between Perform and Confirm phase, we don't know whether the domain was successfully migrated or not. Thus, we have to leave the domain paused and just cleanup the migration job and reset migration parameters. Previously we didn't reset the parameters and future save or snapshot operations would see wrong environment (and could fail because of it) in case the domain stayed running on the source host. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 055d8a674a..b7ef535b5d 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -1834,6 +1834,7 @@ qemuMigrationSrcCleanup(virDomainObjPtr vm, VIR_WARN("Migration of domain %s finished but we don't know if the" " domain was successfully started on destination or not", vm->def->name); + qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT); /* clear the job and let higher levels decide what to do */ qemuDomainObjDiscardAsyncJob(driver, vm); break; -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:02PM +0200, Jiri Denemark wrote:
When connection to the client which controls a non-p2p migration gets closed between Perform and Confirm phase, we don't know whether the domain was successfully migrated or not. Thus, we have to leave the domain paused and just cleanup the migration job and reset migration parameters.
Previously we didn't reset the parameters and future save or snapshot operations would see wrong environment (and could fail because of it) in case the domain stayed running on the source host.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 1 + 1 file changed, 1 insertion(+)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Any job which touches migration parameters will first store their original values (i.e., QEMU defaults) to qemuDomainJobObj to make it easier to reset them back once the job finishes. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_domain.c | 3 +++ src/qemu/qemu_domain.h | 3 +++ src/qemu/qemu_migration.c | 9 ++++++++ src/qemu/qemu_migration_params.c | 38 ++++++++++++++++++++++++++++++++ src/qemu/qemu_migration_params.h | 5 +++++ 5 files changed, 58 insertions(+) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 84476de11b..78f5dc360c 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -336,6 +336,8 @@ qemuDomainObjResetAsyncJob(qemuDomainObjPrivatePtr priv) job->dumpCompleted = false; VIR_FREE(job->error); VIR_FREE(job->current); + qemuMigrationParamsFree(job->migParams); + job->migParams = NULL; } void @@ -350,6 +352,7 @@ qemuDomainObjRestoreJob(virDomainObjPtr obj, job->asyncJob = priv->job.asyncJob; job->asyncOwner = priv->job.asyncOwner; job->phase = priv->job.phase; + VIR_STEAL_PTR(job->migParams, priv->job.migParams); qemuDomainObjResetJob(priv); qemuDomainObjResetAsyncJob(priv); diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 415b2ca093..1828b64284 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -34,6 +34,7 @@ # include "qemu_agent.h" # include "qemu_conf.h" # include "qemu_capabilities.h" +# include "qemu_migration_params.h" # include "virmdev.h" # include "virchrdev.h" # include "virobject.h" @@ -177,6 +178,8 @@ struct qemuDomainJobObj { bool postcopyEnabled; /* post-copy migration was enabled */ char *error; /* job event completion error */ bool dumpCompleted; /* dump completed */ + + qemuMigrationParamsPtr migParams; }; typedef void (*qemuDomainCleanupCallback)(virQEMUDriverPtr driver, diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index b7ef535b5d..96ca5593cf 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2448,6 +2448,9 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, dataFD[1] = -1; /* 'st' owns the FD now & will close it */ } + if (qemuMigrationParamsCheck(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN) < 0) + goto stopjob; + if (qemuMigrationParamsSetCompression(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN, compression, migParams) < 0) goto stopjob; @@ -4597,6 +4600,9 @@ qemuMigrationSrcPerformJob(virQEMUDriverPtr driver, qemuMigrationSrcStoreDomainState(vm); + if (qemuMigrationParamsCheck(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) + goto endjob; + if ((flags & (VIR_MIGRATE_TUNNELLED | VIR_MIGRATE_PEER2PEER))) { ret = qemuMigrationSrcPerformPeer2Peer(driver, conn, vm, xmlin, persist_xml, dconnuri, uri, graphicsuri, listenAddress, @@ -4700,6 +4706,9 @@ qemuMigrationSrcPerformPhase(virQEMUDriverPtr driver, virCloseCallbacksUnset(driver->closeCallbacks, vm, qemuMigrationSrcCleanup); + if (qemuMigrationParamsCheck(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) + goto endjob; + ret = qemuMigrationSrcPerformNative(driver, vm, persist_xml, uri, cookiein, cookieinlen, cookieout, cookieoutlen, flags, resource, NULL, graphicsuri, diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 3a1816c2b9..465132fd9c 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -428,6 +428,44 @@ qemuMigrationParamsResetTLS(virQEMUDriverPtr driver, } +/** + * qemuMigrationParamsCheck: + * + * Check supported migration parameters and keep their original values in + * qemuDomainJobObj so that we can properly reset them at the end of migration. + */ +int +qemuMigrationParamsCheck(virQEMUDriverPtr driver, + virDomainObjPtr vm, + int asyncJob) +{ + qemuDomainObjPrivatePtr priv = vm->privateData; + qemuMigrationParamsPtr origParams = NULL; + int ret = -1; + + if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) + return -1; + + if (!(origParams = qemuMigrationParamsNew())) + goto cleanup; + + if (qemuMonitorGetMigrationParams(priv->mon, &origParams->params) < 0) + goto cleanup; + + ret = 0; + + cleanup: + if (qemuDomainObjExitMonitor(driver, vm) < 0) + ret = -1; + + if (ret == 0) + VIR_STEAL_PTR(priv->job.migParams, origParams); + qemuMigrationParamsFree(origParams); + + return ret; +} + + /* * qemuMigrationParamsReset: * diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index 57b7dd6666..c283a81b51 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -100,6 +100,11 @@ qemuMigrationParamsSetCompression(virQEMUDriverPtr driver, qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams); +int +qemuMigrationParamsCheck(virQEMUDriverPtr driver, + virDomainObjPtr vm, + int asyncJob); + void qemuMigrationParamsReset(virQEMUDriverPtr driver, virDomainObjPtr vm, -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:03PM +0200, Jiri Denemark wrote:
Any job which touches migration parameters will first store their original values (i.e., QEMU defaults) to qemuDomainJobObj to make it easier to reset them back once the job finishes.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_domain.c | 3 +++ src/qemu/qemu_domain.h | 3 +++ src/qemu/qemu_migration.c | 9 ++++++++ src/qemu/qemu_migration_params.c | 38 ++++++++++++++++++++++++++++++++ src/qemu/qemu_migration_params.h | 5 +++++ 5 files changed, 58 insertions(+)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_domain.c | 6 +++--- src/qemu/qemu_domain.h | 8 +++++--- src/qemu/qemu_process.c | 4 ++-- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 78f5dc360c..e997c14aad 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -309,7 +309,7 @@ qemuDomainObjInitJob(qemuDomainObjPrivatePtr priv) static void qemuDomainObjResetJob(qemuDomainObjPrivatePtr priv) { - struct qemuDomainJobObj *job = &priv->job; + qemuDomainJobObjPtr job = &priv->job; job->active = QEMU_JOB_NONE; job->owner = 0; @@ -320,7 +320,7 @@ qemuDomainObjResetJob(qemuDomainObjPrivatePtr priv) static void qemuDomainObjResetAsyncJob(qemuDomainObjPrivatePtr priv) { - struct qemuDomainJobObj *job = &priv->job; + qemuDomainJobObjPtr job = &priv->job; job->asyncJob = QEMU_ASYNC_JOB_NONE; job->asyncOwner = 0; @@ -342,7 +342,7 @@ qemuDomainObjResetAsyncJob(qemuDomainObjPrivatePtr priv) void qemuDomainObjRestoreJob(virDomainObjPtr obj, - struct qemuDomainJobObj *job) + qemuDomainJobObjPtr job) { qemuDomainObjPrivatePtr priv = obj->privateData; diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 1828b64284..2c474ae4a4 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -154,7 +154,9 @@ struct _qemuDomainJobInfo { qemuDomainMirrorStats mirrorStats; }; -struct qemuDomainJobObj { +typedef struct _qemuDomainJobObj qemuDomainJobObj; +typedef qemuDomainJobObj *qemuDomainJobObjPtr; +struct _qemuDomainJobObj { virCond cond; /* Use to coordinate jobs */ qemuDomainJob active; /* Currently running job */ unsigned long long owner; /* Thread id which set current job */ @@ -254,7 +256,7 @@ typedef qemuDomainObjPrivate *qemuDomainObjPrivatePtr; struct _qemuDomainObjPrivate { virQEMUDriverPtr driver; - struct qemuDomainJobObj job; + qemuDomainJobObj job; virBitmapPtr namespaces; @@ -513,7 +515,7 @@ void qemuDomainObjSetJobPhase(virQEMUDriverPtr driver, void qemuDomainObjSetAsyncJobMask(virDomainObjPtr obj, unsigned long long allowedJobs); void qemuDomainObjRestoreJob(virDomainObjPtr obj, - struct qemuDomainJobObj *job); + qemuDomainJobObjPtr job); void qemuDomainObjDiscardAsyncJob(virQEMUDriverPtr driver, virDomainObjPtr obj); void qemuDomainObjReleaseAsyncJob(virDomainObjPtr obj); diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 11276dace9..dd97cd7e7d 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3186,7 +3186,7 @@ qemuProcessRecoverMigrationOut(virQEMUDriverPtr driver, static int qemuProcessRecoverJob(virQEMUDriverPtr driver, virDomainObjPtr vm, - const struct qemuDomainJobObj *job, + const qemuDomainJobObj *job, unsigned int *stopFlags) { qemuDomainObjPrivatePtr priv = vm->privateData; @@ -7262,7 +7262,7 @@ qemuProcessReconnect(void *opaque) virQEMUDriverPtr driver = data->driver; virDomainObjPtr obj = data->obj; qemuDomainObjPrivatePtr priv; - struct qemuDomainJobObj oldjob; + qemuDomainJobObj oldjob; int state; int reason; virQEMUDriverConfigPtr cfg; -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:04PM +0200, Jiri Denemark wrote:
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_domain.c | 6 +++--- src/qemu/qemu_domain.h | 8 +++++--- src/qemu/qemu_process.c | 4 ++-- 3 files changed, 10 insertions(+), 8 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Currently, only job->phase is passed and both APIs will need to look at more details about the job. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_process.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index dd97cd7e7d..fd81933f2e 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3034,7 +3034,7 @@ qemuProcessUpdateState(virQEMUDriverPtr driver, virDomainObjPtr vm) static int qemuProcessRecoverMigrationIn(virQEMUDriverPtr driver, virDomainObjPtr vm, - qemuMigrationJobPhase phase, + const qemuDomainJobObj *job, virDomainState state, int reason) { @@ -3043,7 +3043,7 @@ qemuProcessRecoverMigrationIn(virQEMUDriverPtr driver, (state == VIR_DOMAIN_RUNNING && reason == VIR_DOMAIN_RUNNING_POSTCOPY); - switch (phase) { + switch ((qemuMigrationJobPhase) job->phase) { case QEMU_MIGRATION_PHASE_NONE: case QEMU_MIGRATION_PHASE_PERFORM2: case QEMU_MIGRATION_PHASE_BEGIN3: @@ -3092,7 +3092,7 @@ qemuProcessRecoverMigrationIn(virQEMUDriverPtr driver, static int qemuProcessRecoverMigrationOut(virQEMUDriverPtr driver, virDomainObjPtr vm, - qemuMigrationJobPhase phase, + const qemuDomainJobObj *job, virDomainState state, int reason, unsigned int *stopFlags) @@ -3102,7 +3102,7 @@ qemuProcessRecoverMigrationOut(virQEMUDriverPtr driver, reason == VIR_DOMAIN_PAUSED_POSTCOPY_FAILED); bool resume = false; - switch (phase) { + switch ((qemuMigrationJobPhase) job->phase) { case QEMU_MIGRATION_PHASE_NONE: case QEMU_MIGRATION_PHASE_PREPARE: case QEMU_MIGRATION_PHASE_FINISH2: @@ -3197,13 +3197,13 @@ qemuProcessRecoverJob(virQEMUDriverPtr driver, switch (job->asyncJob) { case QEMU_ASYNC_JOB_MIGRATION_OUT: - if (qemuProcessRecoverMigrationOut(driver, vm, job->phase, + if (qemuProcessRecoverMigrationOut(driver, vm, job, state, reason, stopFlags) < 0) return -1; break; case QEMU_ASYNC_JOB_MIGRATION_IN: - if (qemuProcessRecoverMigrationIn(driver, vm, job->phase, + if (qemuProcessRecoverMigrationIn(driver, vm, job, state, reason) < 0) return -1; break; -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:05PM +0200, Jiri Denemark wrote:
Currently, only job->phase is passed and both APIs will need to look at more details about the job.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_process.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Restore the original values of all migration parameters we store in qemuDomainJobObj instead of explicitly resting only a limited set of them. The result is not strictly equivalent to the previous code wrt reseting TLS state because the previous code would only reset it if we changed it before while the new code will reset it always if QEMU supports TLS migration. This is not a problem for the parameters themselves, but it can cause spurious errors about missing TLS objects being logged at the end of non-TLS migration. This issue will be fixed ~50 patches later. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 20 +++++++++---- src/qemu/qemu_migration_params.c | 48 +++++++++++--------------------- src/qemu/qemu_migration_params.h | 3 +- src/qemu/qemu_process.c | 4 +-- 4 files changed, 34 insertions(+), 41 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 96ca5593cf..72fcae77f4 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -1834,7 +1834,8 @@ qemuMigrationSrcCleanup(virDomainObjPtr vm, VIR_WARN("Migration of domain %s finished but we don't know if the" " domain was successfully started on destination or not", vm->def->name); - qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT); + qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, + priv->job.migParams); /* clear the job and let higher levels decide what to do */ qemuDomainObjDiscardAsyncJob(driver, vm); break; @@ -2593,7 +2594,8 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, return ret; stopjob: - qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN); + qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN, + priv->job.migParams); if (stopProcess) { unsigned int stopFlags = VIR_QEMU_PROCESS_STOP_MIGRATED; @@ -2969,7 +2971,8 @@ qemuMigrationSrcConfirmPhase(virQEMUDriverPtr driver, qemuDomainEventQueue(driver, event); } - qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT); + qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, + priv->job.migParams); if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0) VIR_WARN("Failed to save status on vm %s", vm->def->name); @@ -4581,6 +4584,7 @@ qemuMigrationSrcPerformJob(virQEMUDriverPtr driver, int ret = -1; virErrorPtr orig_err = NULL; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + qemuDomainObjPrivatePtr priv = vm->privateData; if (qemuMigrationJobStart(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) goto cleanup; @@ -4641,7 +4645,8 @@ qemuMigrationSrcPerformJob(virQEMUDriverPtr driver, * here */ if (!v3proto && ret < 0) - qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT); + qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, + priv->job.migParams); if (qemuMigrationSrcRestoreDomainState(driver, vm)) { event = virDomainEventLifecycleNewFromObj(vm, @@ -4691,6 +4696,7 @@ qemuMigrationSrcPerformPhase(virQEMUDriverPtr driver, unsigned long flags, unsigned long resource) { + qemuDomainObjPrivatePtr priv = vm->privateData; virObjectEventPtr event = NULL; int ret = -1; @@ -4731,7 +4737,8 @@ qemuMigrationSrcPerformPhase(virQEMUDriverPtr driver, endjob: if (ret < 0) { - qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT); + qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, + priv->job.migParams); qemuMigrationJobFinish(driver, vm); } else { qemuMigrationJobContinue(vm); @@ -5187,7 +5194,8 @@ qemuMigrationDstFinish(virQEMUDriverPtr driver, VIR_FREE(priv->job.completed); } - qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN); + qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN, + priv->job.migParams); qemuMigrationJobFinish(driver, vm); if (!virDomainObjIsActive(vm)) diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 465132fd9c..72836ba9fa 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -378,30 +378,19 @@ qemuMigrationParamsSetCompression(virQEMUDriverPtr driver, * * Deconstruct all the setup possibly done for TLS - delete the TLS and * security objects, free the secinfo, and reset the migration params to "". - * - * Returns 0 on success, -1 on failure */ -static int +static void qemuMigrationParamsResetTLS(virQEMUDriverPtr driver, virDomainObjPtr vm, - int asyncJob) + int asyncJob, + qemuMigrationParamsPtr origParams) { - qemuDomainObjPrivatePtr priv = vm->privateData; char *tlsAlias = NULL; char *secAlias = NULL; - qemuMigrationParamsPtr migParams = NULL; - int ret = -1; - if (qemuMigrationParamsCheckTLSCreds(driver, vm, asyncJob) < 0) - return -1; - - /* If the tls-creds doesn't exist or if they're set to "" then there's - * nothing to do since we never set anything up */ - if (!priv->migTLSAlias || !*priv->migTLSAlias) - return 0; - - if (!(migParams = qemuMigrationParamsNew())) - goto cleanup; + /* If QEMU does not support TLS migration we didn't set the aliases. */ + if (!origParams->params.tlsCreds) + return; /* NB: If either or both fail to allocate memory we can still proceed * since the next time we migrate another deletion attempt will be @@ -410,21 +399,10 @@ qemuMigrationParamsResetTLS(virQEMUDriverPtr driver, secAlias = qemuDomainGetSecretAESAlias(QEMU_MIGRATION_TLS_ALIAS_BASE, false); qemuDomainDelTLSObjects(driver, vm, asyncJob, secAlias, tlsAlias); - qemuDomainSecretInfoFree(&priv->migSecinfo); + qemuDomainSecretInfoFree(&QEMU_DOMAIN_PRIVATE(vm)->migSecinfo); - if (VIR_STRDUP(migParams->params.tlsCreds, "") < 0 || - VIR_STRDUP(migParams->params.tlsHostname, "") < 0 || - qemuMigrationParamsSet(driver, vm, asyncJob, migParams) < 0) - goto cleanup; - - ret = 0; - - cleanup: VIR_FREE(tlsAlias); VIR_FREE(secAlias); - qemuMigrationParamsFree(migParams); - - return ret; } @@ -475,16 +453,22 @@ qemuMigrationParamsCheck(virQEMUDriverPtr driver, void qemuMigrationParamsReset(virQEMUDriverPtr driver, virDomainObjPtr vm, - int asyncJob) + int asyncJob, + qemuMigrationParamsPtr origParams) { qemuMonitorMigrationCaps cap; virErrorPtr err = virSaveLastError(); + VIR_DEBUG("Resetting migration parameters %p", origParams); + if (!virDomainObjIsActive(vm)) goto cleanup; - if (qemuMigrationParamsResetTLS(driver, vm, asyncJob) < 0) - goto cleanup; + if (origParams) { + if (qemuMigrationParamsSet(driver, vm, asyncJob, origParams) < 0) + goto cleanup; + qemuMigrationParamsResetTLS(driver, vm, asyncJob, origParams); + } for (cap = 0; cap < QEMU_MONITOR_MIGRATION_CAPS_LAST; cap++) { if (qemuMigrationCapsGet(vm, cap) && diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index c283a81b51..b7649128f8 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -108,7 +108,8 @@ qemuMigrationParamsCheck(virQEMUDriverPtr driver, void qemuMigrationParamsReset(virQEMUDriverPtr driver, virDomainObjPtr vm, - int asyncJob); + int asyncJob, + qemuMigrationParamsPtr origParams); int qemuMigrationCapsCheck(virQEMUDriverPtr driver, diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index fd81933f2e..6aa4f4ed71 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3085,7 +3085,7 @@ qemuProcessRecoverMigrationIn(virQEMUDriverPtr driver, break; } - qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_NONE); + qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_NONE, job->migParams); return 0; } @@ -3179,7 +3179,7 @@ qemuProcessRecoverMigrationOut(virQEMUDriverPtr driver, } } - qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_NONE); + qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_NONE, job->migParams); return 0; } -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:06PM +0200, Jiri Denemark wrote:
Restore the original values of all migration parameters we store in qemuDomainJobObj instead of explicitly resting only a limited set of them.
The result is not strictly equivalent to the previous code wrt reseting TLS state because the previous code would only reset it if we changed it before while the new code will reset it always if QEMU supports TLS migration. This is not a problem for the parameters themselves, but it can cause spurious errors about missing TLS objects being logged at the end of non-TLS migration. This issue will be fixed ~50 patches later.
It better be.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 20 +++++++++---- src/qemu/qemu_migration_params.c | 48 +++++++++++--------------------- src/qemu/qemu_migration_params.h | 3 +- src/qemu/qemu_process.c | 4 +-- 4 files changed, 34 insertions(+), 41 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

The code can be merged directly in qemuMigrationParamsAddTLSObjects. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 15 ------- src/qemu/qemu_migration_params.c | 73 ++++++++++---------------------- src/qemu/qemu_migration_params.h | 6 --- 3 files changed, 23 insertions(+), 71 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 72fcae77f4..633f0120bb 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2042,7 +2042,6 @@ qemuMigrationSrcBegin(virConnectPtr conn, unsigned long flags) { virQEMUDriverPtr driver = conn->privateData; - virQEMUDriverConfigPtr cfg = NULL; char *xml = NULL; qemuDomainAsyncJob asyncJob; @@ -2076,12 +2075,6 @@ qemuMigrationSrcBegin(virConnectPtr conn, nmigrate_disks, migrate_disks, flags))) goto endjob; - if (flags & VIR_MIGRATE_TLS) { - cfg = virQEMUDriverGetConfig(driver); - if (qemuMigrationParamsCheckSetupTLS(driver, cfg, vm, asyncJob) < 0) - goto endjob; - } - if ((flags & VIR_MIGRATE_CHANGE_PROTECTION)) { /* We keep the job active across API calls until the confirm() call. * This prevents any other APIs being invoked while migration is taking @@ -2098,7 +2091,6 @@ qemuMigrationSrcBegin(virConnectPtr conn, } cleanup: - virObjectUnref(cfg); virDomainObjEndAPI(&vm); return xml; @@ -2460,10 +2452,6 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, * set the migration TLS parameters */ if (flags & VIR_MIGRATE_TLS) { cfg = virQEMUDriverGetConfig(driver); - if (qemuMigrationParamsCheckSetupTLS(driver, cfg, vm, - QEMU_ASYNC_JOB_MIGRATION_IN) < 0) - goto stopjob; - if (qemuMigrationParamsAddTLSObjects(driver, vm, cfg, true, QEMU_ASYNC_JOB_MIGRATION_IN, &tlsAlias, &secAlias, migParams) < 0) @@ -3421,9 +3409,6 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, if (flags & VIR_MIGRATE_TLS) { cfg = virQEMUDriverGetConfig(driver); - - /* Begin/CheckSetupTLS already set up migTLSAlias, the following - * assumes that and adds the TLS objects to the domain. */ if (qemuMigrationParamsAddTLSObjects(driver, vm, cfg, false, QEMU_ASYNC_JOB_MIGRATION_OUT, &tlsAlias, &secAlias, migParams) < 0) diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 72836ba9fa..d3a4a6d896 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -179,56 +179,6 @@ qemuMigrationParamsCheckTLSCreds(virQEMUDriverPtr driver, } -/* qemuMigrationParamsCheckSetupTLS - * @driver: pointer to qemu driver - * @vm: domain object - * @cfg: configuration pointer - * @asyncJob: migration job to join - * - * Check if TLS is possible and set up the environment. Assumes the caller - * desires to use TLS (e.g. caller found VIR_MIGRATE_TLS flag). - * - * Ensure the qemu.conf has been properly configured to add an entry for - * "migrate_tls_x509_cert_dir". Also check if the "tls-creds" parameter - * was present from a query of migration parameters - * - * Returns 0 on success, -1 on error/failure - */ -int -qemuMigrationParamsCheckSetupTLS(virQEMUDriverPtr driver, - virQEMUDriverConfigPtr cfg, - virDomainObjPtr vm, - int asyncJob) -{ - qemuDomainObjPrivatePtr priv = vm->privateData; - - if (!cfg->migrateTLSx509certdir) { - virReportError(VIR_ERR_OPERATION_INVALID, "%s", - _("host migration TLS directory not configured")); - return -1; - } - - if (qemuMigrationParamsCheckTLSCreds(driver, vm, asyncJob) < 0) - return -1; - - if (!priv->migTLSAlias) { - virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", - _("TLS migration is not supported with this " - "QEMU binary")); - return -1; - } - - /* If there's a secret, then grab/store it now using the connection */ - if (cfg->migrateTLSx509secretUUID && - !(priv->migSecinfo = - qemuDomainSecretInfoTLSNew(priv, QEMU_MIGRATION_TLS_ALIAS_BASE, - cfg->migrateTLSx509secretUUID))) - return -1; - - return 0; -} - - /* qemuMigrationParamsAddTLSObjects * @driver: pointer to qemu driver * @vm: domain object @@ -257,6 +207,29 @@ qemuMigrationParamsAddTLSObjects(virQEMUDriverPtr driver, virJSONValuePtr tlsProps = NULL; virJSONValuePtr secProps = NULL; + if (!cfg->migrateTLSx509certdir) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("host migration TLS directory not configured")); + goto error; + } + + if (qemuMigrationParamsCheckTLSCreds(driver, vm, asyncJob) < 0) + goto error; + + if (!priv->migTLSAlias) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("TLS migration is not supported with this " + "QEMU binary")); + goto error; + } + + /* If there's a secret, then grab/store it now using the connection */ + if (cfg->migrateTLSx509secretUUID && + !(priv->migSecinfo = + qemuDomainSecretInfoTLSNew(priv, QEMU_MIGRATION_TLS_ALIAS_BASE, + cfg->migrateTLSx509secretUUID))) + goto error; + if (qemuDomainGetTLSObjects(priv->qemuCaps, priv->migSecinfo, cfg->migrateTLSx509certdir, tlsListen, cfg->migrateTLSx509verify, diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index b7649128f8..a65a2fde2a 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -71,12 +71,6 @@ qemuMigrationParamsSet(virQEMUDriverPtr driver, int asyncJob, qemuMigrationParamsPtr migParams); -int -qemuMigrationParamsCheckSetupTLS(virQEMUDriverPtr driver, - virQEMUDriverConfigPtr cfg, - virDomainObjPtr vm, - int asyncJob); - int qemuMigrationParamsAddTLSObjects(virQEMUDriverPtr driver, virDomainObjPtr vm, -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:07PM +0200, Jiri Denemark wrote:
The code can be merged directly in qemuMigrationParamsAddTLSObjects.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 15 ------- src/qemu/qemu_migration_params.c | 73 ++++++++++---------------------- src/qemu/qemu_migration_params.h | 6 --- 3 files changed, 23 insertions(+), 71 deletions(-)
So we trade not catching some errors in the Begin phase for more readable code. Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

The function checks whether QEMU supports TLS migration and stores the original value of tls-creds parameter to priv->migTLSAlias. This is no longer needed because we already have the original value stored in priv->migParams. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_domain.c | 2 -- src/qemu/qemu_domain.h | 4 --- src/qemu/qemu_migration.c | 8 ++--- src/qemu/qemu_migration_params.c | 62 ++------------------------------ src/qemu/qemu_migration_params.h | 4 +-- 5 files changed, 6 insertions(+), 74 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index e997c14aad..03ad8d35c0 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1905,8 +1905,6 @@ qemuDomainObjPrivateDataClear(qemuDomainObjPrivatePtr priv) virDomainUSBAddressSetFree(priv->usbaddrs); priv->usbaddrs = NULL; - /* clean up migration data */ - VIR_FREE(priv->migTLSAlias); virCPUDefFree(priv->origCPU); priv->origCPU = NULL; diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 2c474ae4a4..2bb3e0a788 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -330,10 +330,6 @@ struct _qemuDomainObjPrivate { /* private XML). */ qemuDomainSecretInfoPtr migSecinfo; - /* Used when fetching/storing the current 'tls-creds' migration setting */ - /* (not to be saved in our private XML). */ - char *migTLSAlias; - /* CPU def used to start the domain when it differs from the one actually * provided by QEMU. */ virCPUDefPtr origCPU; diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 633f0120bb..e6239576ef 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2462,9 +2462,7 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, goto stopjob; } else { - if (qemuMigrationParamsSetEmptyTLS(driver, vm, - QEMU_ASYNC_JOB_MIGRATION_IN, - migParams) < 0) + if (qemuMigrationParamsSetEmptyTLS(vm, migParams) < 0) goto stopjob; } @@ -3426,9 +3424,7 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, goto error; } } else { - if (qemuMigrationParamsSetEmptyTLS(driver, vm, - QEMU_ASYNC_JOB_MIGRATION_OUT, - migParams) < 0) + if (qemuMigrationParamsSetEmptyTLS(vm, migParams) < 0) goto error; } diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index d3a4a6d896..451d799efb 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -133,52 +133,6 @@ qemuMigrationParamsSet(virQEMUDriverPtr driver, } -/* qemuMigrationParamsCheckTLSCreds - * @driver: pointer to qemu driver - * @vm: domain object - * @asyncJob: migration job to join - * - * Query the migration parameters looking for the 'tls-creds' parameter. - * If found, then we can support setting or clearing the parameters and thus - * can support TLS for migration. - * - * Returns 0 if we were able to successfully fetch the params and - * additionally if the tls-creds parameter exists, saves it in the - * private domain structure. Returns -1 on failure. - */ -static int -qemuMigrationParamsCheckTLSCreds(virQEMUDriverPtr driver, - virDomainObjPtr vm, - int asyncJob) -{ - int ret = -1; - qemuDomainObjPrivatePtr priv = vm->privateData; - qemuMigrationParamsPtr migParams = NULL; - - if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) - return -1; - - if (!(migParams = qemuMigrationParamsNew())) - goto cleanup; - - if (qemuMonitorGetMigrationParams(priv->mon, &migParams->params) < 0) - goto cleanup; - - /* NB: Could steal NULL pointer too! Let caller decide what to do. */ - VIR_STEAL_PTR(priv->migTLSAlias, migParams->params.tlsCreds); - - ret = 0; - - cleanup: - if (qemuDomainObjExitMonitor(driver, vm) < 0) - ret = -1; - - qemuMigrationParamsFree(migParams); - - return ret; -} - - /* qemuMigrationParamsAddTLSObjects * @driver: pointer to qemu driver * @vm: domain object @@ -213,10 +167,7 @@ qemuMigrationParamsAddTLSObjects(virQEMUDriverPtr driver, goto error; } - if (qemuMigrationParamsCheckTLSCreds(driver, vm, asyncJob) < 0) - goto error; - - if (!priv->migTLSAlias) { + if ((!priv->job.migParams->params.tlsCreds)) { virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", _("TLS migration is not supported with this " "QEMU binary")); @@ -260,9 +211,7 @@ qemuMigrationParamsAddTLSObjects(virQEMUDriverPtr driver, /* qemuMigrationParamsSetEmptyTLS - * @driver: pointer to qemu driver * @vm: domain object - * @asyncJob: migration job to join * @migParams: Pointer to a migration parameters block * * If we support setting the tls-creds, then set both tls-creds and @@ -272,17 +221,12 @@ qemuMigrationParamsAddTLSObjects(virQEMUDriverPtr driver, * Returns 0 on success, -1 on failure */ int -qemuMigrationParamsSetEmptyTLS(virQEMUDriverPtr driver, - virDomainObjPtr vm, - int asyncJob, +qemuMigrationParamsSetEmptyTLS(virDomainObjPtr vm, qemuMigrationParamsPtr migParams) { qemuDomainObjPrivatePtr priv = vm->privateData; - if (qemuMigrationParamsCheckTLSCreds(driver, vm, asyncJob) < 0) - return -1; - - if (!priv->migTLSAlias) + if (!priv->job.migParams->params.tlsCreds) return 0; if (VIR_STRDUP(migParams->params.tlsCreds, "") < 0 || diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index a65a2fde2a..c6cc2aaff6 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -82,9 +82,7 @@ qemuMigrationParamsAddTLSObjects(virQEMUDriverPtr driver, qemuMigrationParamsPtr migParams); int -qemuMigrationParamsSetEmptyTLS(virQEMUDriverPtr driver, - virDomainObjPtr vm, - int asyncJob, +qemuMigrationParamsSetEmptyTLS(virDomainObjPtr vm, qemuMigrationParamsPtr migParams); int -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:08PM +0200, Jiri Denemark wrote:
The function checks whether QEMU supports TLS migration and stores the original value of tls-creds parameter to priv->migTLSAlias. This is no longer needed because we already have the original value stored in priv->migParams.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_domain.c | 2 -- src/qemu/qemu_domain.h | 4 --- src/qemu/qemu_migration.c | 8 ++--- src/qemu/qemu_migration_params.c | 62 ++------------------------------ src/qemu/qemu_migration_params.h | 4 +-- 5 files changed, 6 insertions(+), 74 deletions(-)
Worth it. Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

The new name is qemuMigrationParamsDisableTLS. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 4 ++-- src/qemu/qemu_migration_params.c | 6 +++--- src/qemu/qemu_migration_params.h | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index e6239576ef..efc5734b1a 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2462,7 +2462,7 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, goto stopjob; } else { - if (qemuMigrationParamsSetEmptyTLS(vm, migParams) < 0) + if (qemuMigrationParamsDisableTLS(vm, migParams) < 0) goto stopjob; } @@ -3424,7 +3424,7 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, goto error; } } else { - if (qemuMigrationParamsSetEmptyTLS(vm, migParams) < 0) + if (qemuMigrationParamsDisableTLS(vm, migParams) < 0) goto error; } diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 451d799efb..1f3549a7b4 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -210,7 +210,7 @@ qemuMigrationParamsAddTLSObjects(virQEMUDriverPtr driver, } -/* qemuMigrationParamsSetEmptyTLS +/* qemuMigrationParamsDisableTLS * @vm: domain object * @migParams: Pointer to a migration parameters block * @@ -221,8 +221,8 @@ qemuMigrationParamsAddTLSObjects(virQEMUDriverPtr driver, * Returns 0 on success, -1 on failure */ int -qemuMigrationParamsSetEmptyTLS(virDomainObjPtr vm, - qemuMigrationParamsPtr migParams) +qemuMigrationParamsDisableTLS(virDomainObjPtr vm, + qemuMigrationParamsPtr migParams) { qemuDomainObjPrivatePtr priv = vm->privateData; diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index c6cc2aaff6..4eefe409df 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -82,8 +82,8 @@ qemuMigrationParamsAddTLSObjects(virQEMUDriverPtr driver, qemuMigrationParamsPtr migParams); int -qemuMigrationParamsSetEmptyTLS(virDomainObjPtr vm, - qemuMigrationParamsPtr migParams); +qemuMigrationParamsDisableTLS(virDomainObjPtr vm, + qemuMigrationParamsPtr migParams); int qemuMigrationParamsSetCompression(virQEMUDriverPtr driver, -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:09PM +0200, Jiri Denemark wrote:
The new name is qemuMigrationParamsDisableTLS.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 4 ++-- src/qemu/qemu_migration_params.c | 6 +++--- src/qemu/qemu_migration_params.h | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

The new name is qemuMigrationParamsEnableTLS. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 12 ++++++------ src/qemu/qemu_migration_params.c | 18 +++++++++--------- src/qemu/qemu_migration_params.h | 16 ++++++++-------- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index efc5734b1a..9a9a881f9b 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2452,9 +2452,9 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, * set the migration TLS parameters */ if (flags & VIR_MIGRATE_TLS) { cfg = virQEMUDriverGetConfig(driver); - if (qemuMigrationParamsAddTLSObjects(driver, vm, cfg, true, - QEMU_ASYNC_JOB_MIGRATION_IN, - &tlsAlias, &secAlias, migParams) < 0) + if (qemuMigrationParamsEnableTLS(driver, vm, cfg, true, + QEMU_ASYNC_JOB_MIGRATION_IN, + &tlsAlias, &secAlias, migParams) < 0) goto stopjob; /* Force reset of 'tls-hostname', it's a source only parameter */ @@ -3407,9 +3407,9 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, if (flags & VIR_MIGRATE_TLS) { cfg = virQEMUDriverGetConfig(driver); - if (qemuMigrationParamsAddTLSObjects(driver, vm, cfg, false, - QEMU_ASYNC_JOB_MIGRATION_OUT, - &tlsAlias, &secAlias, migParams) < 0) + if (qemuMigrationParamsEnableTLS(driver, vm, cfg, false, + QEMU_ASYNC_JOB_MIGRATION_OUT, + &tlsAlias, &secAlias, migParams) < 0) goto error; /* We need to add tls-hostname whenever QEMU itself does not diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 1f3549a7b4..bb3bbc30f3 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -133,7 +133,7 @@ qemuMigrationParamsSet(virQEMUDriverPtr driver, } -/* qemuMigrationParamsAddTLSObjects +/* qemuMigrationParamsEnableTLS * @driver: pointer to qemu driver * @vm: domain object * @cfg: configuration pointer @@ -148,14 +148,14 @@ qemuMigrationParamsSet(virQEMUDriverPtr driver, * Returns 0 on success, -1 on failure */ int -qemuMigrationParamsAddTLSObjects(virQEMUDriverPtr driver, - virDomainObjPtr vm, - virQEMUDriverConfigPtr cfg, - bool tlsListen, - int asyncJob, - char **tlsAlias, - char **secAlias, - qemuMigrationParamsPtr migParams) +qemuMigrationParamsEnableTLS(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virQEMUDriverConfigPtr cfg, + bool tlsListen, + int asyncJob, + char **tlsAlias, + char **secAlias, + qemuMigrationParamsPtr migParams) { qemuDomainObjPrivatePtr priv = vm->privateData; virJSONValuePtr tlsProps = NULL; diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index 4eefe409df..6f3fb67949 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -72,14 +72,14 @@ qemuMigrationParamsSet(virQEMUDriverPtr driver, qemuMigrationParamsPtr migParams); int -qemuMigrationParamsAddTLSObjects(virQEMUDriverPtr driver, - virDomainObjPtr vm, - virQEMUDriverConfigPtr cfg, - bool tlsListen, - int asyncJob, - char **tlsAlias, - char **secAlias, - qemuMigrationParamsPtr migParams); +qemuMigrationParamsEnableTLS(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virQEMUDriverConfigPtr cfg, + bool tlsListen, + int asyncJob, + char **tlsAlias, + char **secAlias, + qemuMigrationParamsPtr migParams); int qemuMigrationParamsDisableTLS(virDomainObjPtr vm, -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:10PM +0200, Jiri Denemark wrote:
The new name is qemuMigrationParamsEnableTLS.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 12 ++++++------ src/qemu/qemu_migration_params.c | 18 +++++++++--------- src/qemu/qemu_migration_params.h | 16 ++++++++-------- 3 files changed, 23 insertions(+), 23 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 31 ++++++++++++------------------- src/qemu/qemu_migration_params.c | 9 +++++++-- src/qemu/qemu_migration_params.h | 1 + 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 9a9a881f9b..c2cd937743 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2454,13 +2454,9 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, cfg = virQEMUDriverGetConfig(driver); if (qemuMigrationParamsEnableTLS(driver, vm, cfg, true, QEMU_ASYNC_JOB_MIGRATION_IN, - &tlsAlias, &secAlias, migParams) < 0) + &tlsAlias, &secAlias, NULL, + migParams) < 0) goto stopjob; - - /* Force reset of 'tls-hostname', it's a source only parameter */ - if (VIR_STRDUP(migParams->params.tlsHostname, "") < 0) - goto stopjob; - } else { if (qemuMigrationParamsDisableTLS(vm, migParams) < 0) goto stopjob; @@ -3406,23 +3402,20 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, VIR_WARN("unable to provide data for graphics client relocation"); if (flags & VIR_MIGRATE_TLS) { - cfg = virQEMUDriverGetConfig(driver); - if (qemuMigrationParamsEnableTLS(driver, vm, cfg, false, - QEMU_ASYNC_JOB_MIGRATION_OUT, - &tlsAlias, &secAlias, migParams) < 0) - goto error; + const char *hostname = NULL; /* We need to add tls-hostname whenever QEMU itself does not * connect directly to the destination. */ if (spec->destType == MIGRATION_DEST_CONNECT_HOST || - spec->destType == MIGRATION_DEST_FD) { - if (VIR_STRDUP(migParams->params.tlsHostname, spec->dest.host.name) < 0) - goto error; - } else { - /* Be sure there's nothing from a previous migration */ - if (VIR_STRDUP(migParams->params.tlsHostname, "") < 0) - goto error; - } + spec->destType == MIGRATION_DEST_FD) + hostname = spec->dest.host.name; + + cfg = virQEMUDriverGetConfig(driver); + if (qemuMigrationParamsEnableTLS(driver, vm, cfg, false, + QEMU_ASYNC_JOB_MIGRATION_OUT, + &tlsAlias, &secAlias, hostname, + migParams) < 0) + goto error; } else { if (qemuMigrationParamsDisableTLS(vm, migParams) < 0) goto error; diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index bb3bbc30f3..476687aae2 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -141,9 +141,12 @@ qemuMigrationParamsSet(virQEMUDriverPtr driver, * @asyncJob: Migration job to join * @tlsAlias: alias to be generated for TLS object * @secAlias: alias to be generated for a secinfo object + * @hostname: hostname of the migration destination * @migParams: migration parameters to set * - * Create the TLS objects for the migration and set the migParams value + * Create the TLS objects for the migration and set the migParams value. + * If QEMU itself does not connect to the destination @hostname must be + * provided for certificate verification. * * Returns 0 on success, -1 on failure */ @@ -155,6 +158,7 @@ qemuMigrationParamsEnableTLS(virQEMUDriverPtr driver, int asyncJob, char **tlsAlias, char **secAlias, + const char *hostname, qemuMigrationParamsPtr migParams) { qemuDomainObjPrivatePtr priv = vm->privateData; @@ -198,7 +202,8 @@ qemuMigrationParamsEnableTLS(virQEMUDriverPtr driver, *tlsAlias, &tlsProps) < 0) goto error; - if (VIR_STRDUP(migParams->params.tlsCreds, *tlsAlias) < 0) + if (VIR_STRDUP(migParams->params.tlsCreds, *tlsAlias) < 0 || + VIR_STRDUP(migParams->params.tlsHostname, hostname ? hostname : "") < 0) goto error; return 0; diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index 6f3fb67949..6535c3af47 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -79,6 +79,7 @@ qemuMigrationParamsEnableTLS(virQEMUDriverPtr driver, int asyncJob, char **tlsAlias, char **secAlias, + const char *hostname, qemuMigrationParamsPtr migParams); int -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:11PM +0200, Jiri Denemark wrote:
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 31 ++++++++++++------------------- src/qemu/qemu_migration_params.c | 9 +++++++-- src/qemu/qemu_migration_params.h | 1 + 3 files changed, 20 insertions(+), 21 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

There's no real reason for qemuMigrationParamsEnableTLS to require the callers to pass a valid virQEMUDriverConfigPtr, it can just call virQEMUDriverGetConfig. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 10 ++-------- src/qemu/qemu_migration_params.c | 12 ++++++++---- src/qemu/qemu_migration_params.h | 1 - 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index c2cd937743..54d9dfa025 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2228,7 +2228,6 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, { virDomainObjPtr vm = NULL; virObjectEventPtr event = NULL; - virQEMUDriverConfigPtr cfg = NULL; int ret = -1; int dataFD[2] = { -1, -1 }; qemuDomainObjPrivatePtr priv = NULL; @@ -2451,8 +2450,7 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, /* Migrations using TLS need to add the "tls-creds-x509" object and * set the migration TLS parameters */ if (flags & VIR_MIGRATE_TLS) { - cfg = virQEMUDriverGetConfig(driver); - if (qemuMigrationParamsEnableTLS(driver, vm, cfg, true, + if (qemuMigrationParamsEnableTLS(driver, vm, true, QEMU_ASYNC_JOB_MIGRATION_IN, &tlsAlias, &secAlias, NULL, migParams) < 0) @@ -2549,7 +2547,6 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, cleanup: VIR_FREE(tlsAlias); VIR_FREE(secAlias); - virObjectUnref(cfg); qemuProcessIncomingDefFree(incoming); VIR_FREE(xmlout); VIR_FORCE_CLOSE(dataFD[0]); @@ -3330,7 +3327,6 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, { int ret = -1; unsigned int migrate_flags = QEMU_MONITOR_MIGRATE_BACKGROUND; - virQEMUDriverConfigPtr cfg = NULL; qemuDomainObjPrivatePtr priv = vm->privateData; qemuMigrationCookiePtr mig = NULL; char *tlsAlias = NULL; @@ -3410,8 +3406,7 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, spec->destType == MIGRATION_DEST_FD) hostname = spec->dest.host.name; - cfg = virQEMUDriverGetConfig(driver); - if (qemuMigrationParamsEnableTLS(driver, vm, cfg, false, + if (qemuMigrationParamsEnableTLS(driver, vm, false, QEMU_ASYNC_JOB_MIGRATION_OUT, &tlsAlias, &secAlias, hostname, migParams) < 0) @@ -3649,7 +3644,6 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, cleanup: VIR_FREE(tlsAlias); VIR_FREE(secAlias); - virObjectUnref(cfg); VIR_FORCE_CLOSE(fd); virDomainDefFree(persistDef); qemuMigrationCookieFree(mig); diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 476687aae2..dd8cf68842 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -136,7 +136,6 @@ qemuMigrationParamsSet(virQEMUDriverPtr driver, /* qemuMigrationParamsEnableTLS * @driver: pointer to qemu driver * @vm: domain object - * @cfg: configuration pointer * @tlsListen: server or client * @asyncJob: Migration job to join * @tlsAlias: alias to be generated for TLS object @@ -153,7 +152,6 @@ qemuMigrationParamsSet(virQEMUDriverPtr driver, int qemuMigrationParamsEnableTLS(virQEMUDriverPtr driver, virDomainObjPtr vm, - virQEMUDriverConfigPtr cfg, bool tlsListen, int asyncJob, char **tlsAlias, @@ -164,6 +162,8 @@ qemuMigrationParamsEnableTLS(virQEMUDriverPtr driver, qemuDomainObjPrivatePtr priv = vm->privateData; virJSONValuePtr tlsProps = NULL; virJSONValuePtr secProps = NULL; + virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + int ret = -1; if (!cfg->migrateTLSx509certdir) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", @@ -206,12 +206,16 @@ qemuMigrationParamsEnableTLS(virQEMUDriverPtr driver, VIR_STRDUP(migParams->params.tlsHostname, hostname ? hostname : "") < 0) goto error; - return 0; + ret = 0; + + cleanup: + virObjectUnref(cfg); + return ret; error: virJSONValueFree(tlsProps); virJSONValueFree(secProps); - return -1; + goto cleanup; } diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index 6535c3af47..e8323dc9bb 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -74,7 +74,6 @@ qemuMigrationParamsSet(virQEMUDriverPtr driver, int qemuMigrationParamsEnableTLS(virQEMUDriverPtr driver, virDomainObjPtr vm, - virQEMUDriverConfigPtr cfg, bool tlsListen, int asyncJob, char **tlsAlias, -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:12PM +0200, Jiri Denemark wrote:
There's no real reason for qemuMigrationParamsEnableTLS to require the callers to pass a valid virQEMUDriverConfigPtr, it can just call virQEMUDriverGetConfig.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 10 ++-------- src/qemu/qemu_migration_params.c | 12 ++++++++---- src/qemu/qemu_migration_params.h | 1 - 3 files changed, 10 insertions(+), 13 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

The new name is qemuMigrationParamsApply and it will soon become the only API which will send all requested migration parameters and capabilities to QEMU. All other qemuMigrationParams* APIs will just operate on the qemuMigrationParams structure. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 8 ++++---- src/qemu/qemu_migration_params.c | 21 ++++++++++++++++----- src/qemu/qemu_migration_params.h | 8 ++++---- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 54d9dfa025..602ccdfdd5 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2476,8 +2476,8 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, QEMU_ASYNC_JOB_MIGRATION_IN) < 0) goto stopjob; - if (qemuMigrationParamsSet(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN, - migParams) < 0) + if (qemuMigrationParamsApply(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN, + migParams) < 0) goto stopjob; if (mig->nbd && @@ -3471,8 +3471,8 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, true, QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) goto error; - if (qemuMigrationParamsSet(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, - migParams) < 0) + if (qemuMigrationParamsApply(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, + migParams) < 0) goto error; if (qemuDomainObjEnterMonitorAsync(driver, vm, diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index dd8cf68842..92fe84d324 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -108,11 +108,22 @@ qemuMigrationParamsFromFlags(virTypedParameterPtr params, } +/** + * qemuMigrationParamsApply + * @driver: qemu driver + * @vm: domain object + * @asyncJob: migration job + * @migParams: migration parameters to send to QEMU + * + * Send all parameters stored in @migParams to QEMU. + * + * Returns 0 on success, -1 on failure. + */ int -qemuMigrationParamsSet(virQEMUDriverPtr driver, - virDomainObjPtr vm, - int asyncJob, - qemuMigrationParamsPtr migParams) +qemuMigrationParamsApply(virQEMUDriverPtr driver, + virDomainObjPtr vm, + int asyncJob, + qemuMigrationParamsPtr migParams) { qemuDomainObjPrivatePtr priv = vm->privateData; int ret = -1; @@ -391,7 +402,7 @@ qemuMigrationParamsReset(virQEMUDriverPtr driver, goto cleanup; if (origParams) { - if (qemuMigrationParamsSet(driver, vm, asyncJob, origParams) < 0) + if (qemuMigrationParamsApply(driver, vm, asyncJob, origParams) < 0) goto cleanup; qemuMigrationParamsResetTLS(driver, vm, asyncJob, origParams); } diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index e8323dc9bb..ce7f84fd66 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -66,10 +66,10 @@ void qemuMigrationParamsFree(qemuMigrationParamsPtr migParams); int -qemuMigrationParamsSet(virQEMUDriverPtr driver, - virDomainObjPtr vm, - int asyncJob, - qemuMigrationParamsPtr migParams); +qemuMigrationParamsApply(virQEMUDriverPtr driver, + virDomainObjPtr vm, + int asyncJob, + qemuMigrationParamsPtr migParams); int qemuMigrationParamsEnableTLS(virQEMUDriverPtr driver, -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:13PM +0200, Jiri Denemark wrote:
The new name is qemuMigrationParamsApply and it will soon become the only API which will send all requested migration parameters and capabilities to QEMU. All other qemuMigrationParams* APIs will just operate on the qemuMigrationParams structure.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 8 ++++---- src/qemu/qemu_migration_params.c | 21 ++++++++++++++++----- src/qemu/qemu_migration_params.h | 8 ++++---- 3 files changed, 24 insertions(+), 13 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

All users of migration parameters are supposed to use APIs provided by qemu_migration_params.c without having to worry about the internals. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 5 +++++ src/qemu/qemu_migration_params.h | 3 --- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 92fe84d324..4ca49d942e 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -30,6 +30,7 @@ #include "qemu_hotplug.h" #include "qemu_migration.h" #include "qemu_migration_params.h" +#include "qemu_monitor.h" #define VIR_FROM_THIS VIR_FROM_QEMU @@ -37,6 +38,10 @@ VIR_LOG_INIT("qemu.qemu_migration_params"); #define QEMU_MIGRATION_TLS_ALIAS_BASE "libvirt_migrate" +struct _qemuMigrationParams { + qemuMonitorMigrationParams params; +}; + qemuMigrationParamsPtr qemuMigrationParamsNew(void) diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index ce7f84fd66..37e528f36c 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -49,9 +49,6 @@ struct _qemuMigrationCompression { typedef struct _qemuMigrationParams qemuMigrationParams; typedef qemuMigrationParams *qemuMigrationParamsPtr; -struct _qemuMigrationParams { - qemuMonitorMigrationParams params; -}; qemuMigrationParamsPtr -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:14PM +0200, Jiri Denemark wrote:
All users of migration parameters are supposed to use APIs provided by qemu_migration_params.c without having to worry about the internals.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 5 +++++ src/qemu/qemu_migration_params.h | 3 --- 2 files changed, 5 insertions(+), 3 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Our current monitor API forces the caller to call migrate-set-capabilities QMP command for each capability separately, which is quite suboptimal. Let's add a new API for setting all capabilities at once. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_monitor.c | 19 +++++++++++ src/qemu/qemu_monitor.h | 3 ++ src/qemu/qemu_monitor_json.c | 63 ++++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 3 ++ 4 files changed, 88 insertions(+) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 7b647525b3..7ea72af788 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -3991,6 +3991,25 @@ qemuMonitorSetMigrationCapability(qemuMonitorPtr mon, } +int +qemuMonitorSetMigrationCapabilities(qemuMonitorPtr mon, + virBitmapPtr caps, + virBitmapPtr states) +{ + char *capsStr = virBitmapFormat(caps); + char *statesStr = virBitmapFormat(states); + + VIR_DEBUG("caps=%s, states=%s", NULLSTR(capsStr), NULLSTR(statesStr)); + + VIR_FREE(capsStr); + VIR_FREE(statesStr); + + QEMU_CHECK_MONITOR_JSON(mon); + + return qemuMonitorJSONSetMigrationCapabilities(mon, caps, states); +} + + /** * qemuMonitorGetGICCapabilities: * @mon: QEMU monitor diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index d04148e568..870aae5cbd 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -763,6 +763,9 @@ int qemuMonitorGetMigrationCapabilities(qemuMonitorPtr mon, int qemuMonitorSetMigrationCapability(qemuMonitorPtr mon, qemuMonitorMigrationCaps capability, bool state); +int qemuMonitorSetMigrationCapabilities(qemuMonitorPtr mon, + virBitmapPtr caps, + virBitmapPtr states); int qemuMonitorGetGICCapabilities(qemuMonitorPtr mon, virGICCapability **capabilities); diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 57c2c4de0f..7ab73657a0 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -6251,6 +6251,69 @@ qemuMonitorJSONSetMigrationCapability(qemuMonitorPtr mon, } +int +qemuMonitorJSONSetMigrationCapabilities(qemuMonitorPtr mon, + virBitmapPtr caps, + virBitmapPtr states) +{ + int ret = -1; + qemuMonitorMigrationCaps bit; + virJSONValuePtr cmd = NULL; + virJSONValuePtr reply = NULL; + virJSONValuePtr cap = NULL; + virJSONValuePtr array; + + if (!(array = virJSONValueNewArray())) + goto cleanup; + + for (bit = 0; bit < QEMU_MONITOR_MIGRATION_CAPS_LAST; bit++) { + bool supported = false; + bool state = false; + + ignore_value(virBitmapGetBit(caps, bit, &supported)); + if (!supported) + continue; + + ignore_value(virBitmapGetBit(states, bit, &state)); + + if (!(cap = virJSONValueNewObject())) + goto cleanup; + + if (virJSONValueObjectAppendString(cap, "capability", + qemuMonitorMigrationCapsTypeToString(bit)) < 0) + goto cleanup; + + if (virJSONValueObjectAppendBoolean(cap, "state", state) < 0) + goto cleanup; + + if (virJSONValueArrayAppend(array, cap) < 0) + goto cleanup; + + cap = NULL; + } + + cmd = qemuMonitorJSONMakeCommand("migrate-set-capabilities", + "a:capabilities", &array, + NULL); + if (!cmd) + goto cleanup; + + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) + goto cleanup; + + if (qemuMonitorJSONCheckError(cmd, reply) < 0) + goto cleanup; + + ret = 0; + cleanup: + virJSONValueFree(array); + virJSONValueFree(cap); + virJSONValueFree(cmd); + virJSONValueFree(reply); + return ret; +} + + /** * qemuMonitorJSONGetGICCapabilities: * @mon: QEMU JSON monitor diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 045df4919f..76e6738f44 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -148,6 +148,9 @@ int qemuMonitorJSONGetMigrationCapabilities(qemuMonitorPtr mon, int qemuMonitorJSONSetMigrationCapability(qemuMonitorPtr mon, qemuMonitorMigrationCaps capability, bool state); +int qemuMonitorJSONSetMigrationCapabilities(qemuMonitorPtr mon, + virBitmapPtr caps, + virBitmapPtr states); int qemuMonitorJSONGetGICCapabilities(qemuMonitorPtr mon, virGICCapability **capabilities); -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:15PM +0200, Jiri Denemark wrote:
Our current monitor API forces the caller to call migrate-set-capabilities QMP command for each capability separately, which is quite suboptimal. Let's add a new API for setting all capabilities at once.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_monitor.c | 19 +++++++++++ src/qemu/qemu_monitor.h | 3 ++ src/qemu/qemu_monitor_json.c | 63 ++++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 3 ++ 4 files changed, 88 insertions(+)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Migration capabilities are closely related to migration parameters and it makes sense to keep them in a single data structure. Similarly to migration parameters the capabilities are all send to QEMU at once in qemuMigrationParamsApply, all other APIs operate on the qemuMigrationParams structure. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 100 ++++++------------------------- src/qemu/qemu_migration.h | 7 --- src/qemu/qemu_migration_params.c | 99 +++++++++++++++++++++++------- src/qemu/qemu_migration_params.h | 11 ++++ 4 files changed, 107 insertions(+), 110 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 602ccdfdd5..e01c2a209d 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -1174,66 +1174,6 @@ qemuMigrationAnyPostcopyFailed(virQEMUDriverPtr driver, } -int -qemuMigrationOptionSet(virQEMUDriverPtr driver, - virDomainObjPtr vm, - qemuMonitorMigrationCaps capability, - bool state, - qemuDomainAsyncJob job) -{ - qemuDomainObjPrivatePtr priv = vm->privateData; - int ret; - - if (!qemuMigrationCapsGet(vm, capability)) { - if (!state) { - /* Unsupported but we want it off anyway */ - return 0; - } - - if (job == QEMU_ASYNC_JOB_MIGRATION_IN) { - virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, - _("Migration option '%s' is not supported by " - "target QEMU binary"), - qemuMonitorMigrationCapsTypeToString(capability)); - } else { - virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, - _("Migration option '%s' is not supported by " - "source QEMU binary"), - qemuMonitorMigrationCapsTypeToString(capability)); - } - return -1; - } - - if (qemuDomainObjEnterMonitorAsync(driver, vm, job) < 0) - return -1; - - ret = qemuMonitorSetMigrationCapability(priv->mon, capability, state); - - if (qemuDomainObjExitMonitor(driver, vm) < 0) - ret = -1; - - return ret; -} - - -static int -qemuMigrationOptionSetPostCopy(virQEMUDriverPtr driver, - virDomainObjPtr vm, - bool state, - qemuDomainAsyncJob job) -{ - qemuDomainObjPrivatePtr priv = vm->privateData; - - if (qemuMigrationOptionSet(driver, vm, - QEMU_MONITOR_MIGRATION_CAPS_POSTCOPY, - state, job) < 0) - return -1; - - priv->job.postcopyEnabled = state; - return 0; -} - - static int qemuMigrationSrcWaitForSpice(virDomainObjPtr vm) { @@ -2465,15 +2405,14 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, goto stopjob; } - if (qemuMigrationOptionSet(driver, vm, - QEMU_MONITOR_MIGRATION_CAPS_RDMA_PIN_ALL, - flags & VIR_MIGRATE_RDMA_PIN_ALL, - QEMU_ASYNC_JOB_MIGRATION_IN) < 0) + if (qemuMigrationParamsSetCapability(vm, + QEMU_MONITOR_MIGRATION_CAPS_RDMA_PIN_ALL, + flags & VIR_MIGRATE_RDMA_PIN_ALL, + migParams) < 0) goto stopjob; - if (qemuMigrationOptionSetPostCopy(driver, vm, - flags & VIR_MIGRATE_POSTCOPY, - QEMU_ASYNC_JOB_MIGRATION_IN) < 0) + if (qemuMigrationParamsSetPostCopy(vm, flags & VIR_MIGRATE_POSTCOPY, + migParams) < 0) goto stopjob; if (qemuMigrationParamsApply(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN, @@ -3448,27 +3387,26 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, compression, migParams) < 0) goto error; - if (qemuMigrationOptionSet(driver, vm, - QEMU_MONITOR_MIGRATION_CAPS_AUTO_CONVERGE, - flags & VIR_MIGRATE_AUTO_CONVERGE, - QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) + if (qemuMigrationParamsSetCapability(vm, + QEMU_MONITOR_MIGRATION_CAPS_AUTO_CONVERGE, + flags & VIR_MIGRATE_AUTO_CONVERGE, + migParams) < 0) goto error; - if (qemuMigrationOptionSet(driver, vm, - QEMU_MONITOR_MIGRATION_CAPS_RDMA_PIN_ALL, - flags & VIR_MIGRATE_RDMA_PIN_ALL, - QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) + if (qemuMigrationParamsSetCapability(vm, + QEMU_MONITOR_MIGRATION_CAPS_RDMA_PIN_ALL, + flags & VIR_MIGRATE_RDMA_PIN_ALL, + migParams) < 0) goto error; - if (qemuMigrationOptionSetPostCopy(driver, vm, - flags & VIR_MIGRATE_POSTCOPY, - QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) + if (qemuMigrationParamsSetPostCopy(vm, flags & VIR_MIGRATE_POSTCOPY, + migParams) < 0) goto error; if (qemuMigrationCapsGet(vm, QEMU_MONITOR_MIGRATION_CAPS_PAUSE_BEFORE_SWITCHOVER) && - qemuMigrationOptionSet(driver, vm, - QEMU_MONITOR_MIGRATION_CAPS_PAUSE_BEFORE_SWITCHOVER, - true, QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) + qemuMigrationParamsSetCapability(vm, + QEMU_MONITOR_MIGRATION_CAPS_PAUSE_BEFORE_SWITCHOVER, + true, migParams) < 0) goto error; if (qemuMigrationParamsApply(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h index e59296fd63..fc81eb5016 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -273,11 +273,4 @@ qemuMigrationSrcFetchMirrorStats(virQEMUDriverPtr driver, qemuDomainAsyncJob asyncJob, qemuDomainJobInfoPtr jobInfo); -int -qemuMigrationOptionSet(virQEMUDriverPtr driver, - virDomainObjPtr vm, - qemuMonitorMigrationCaps capability, - bool state, - qemuDomainAsyncJob job); - #endif /* __QEMU_MIGRATION_H__ */ diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 4ca49d942e..d934a93086 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -39,6 +39,7 @@ VIR_LOG_INIT("qemu.qemu_migration_params"); #define QEMU_MIGRATION_TLS_ALIAS_BASE "libvirt_migrate" struct _qemuMigrationParams { + virBitmapPtr caps; qemuMonitorMigrationParams params; }; @@ -51,7 +52,15 @@ qemuMigrationParamsNew(void) if (VIR_ALLOC(params) < 0) return NULL; + params->caps = virBitmapNew(QEMU_MONITOR_MIGRATION_CAPS_LAST); + if (!params->caps) + goto error; + return params; + + error: + qemuMigrationParamsFree(params); + return NULL; } @@ -61,6 +70,7 @@ qemuMigrationParamsFree(qemuMigrationParamsPtr migParams) if (!migParams) return; + virBitmapFree(migParams->caps); VIR_FREE(migParams->params.tlsCreds); VIR_FREE(migParams->params.tlsHostname); VIR_FREE(migParams); @@ -136,6 +146,10 @@ qemuMigrationParamsApply(virQEMUDriverPtr driver, if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) return -1; + if (qemuMonitorSetMigrationCapabilities(priv->mon, priv->migrationCaps, + migParams->caps) < 0) + goto cleanup; + if (qemuMonitorSetMigrationParams(priv->mon, &migParams->params) < 0) goto cleanup; @@ -149,6 +163,50 @@ qemuMigrationParamsApply(virQEMUDriverPtr driver, } +int +qemuMigrationParamsSetCapability(virDomainObjPtr vm, + qemuMonitorMigrationCaps capability, + bool state, + qemuMigrationParamsPtr migParams) +{ + if (!qemuMigrationCapsGet(vm, capability)) { + if (!state) { + /* Unsupported but we want it off anyway */ + return 0; + } + + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, + _("Migration option '%s' is not supported by QEMU binary"), + qemuMonitorMigrationCapsTypeToString(capability)); + return -1; + } + + if (state) + ignore_value(virBitmapSetBit(migParams->caps, capability)); + else + ignore_value(virBitmapClearBit(migParams->caps, capability)); + + return 0; +} + + +int +qemuMigrationParamsSetPostCopy(virDomainObjPtr vm, + bool state, + qemuMigrationParamsPtr migParams) +{ + qemuDomainObjPrivatePtr priv = vm->privateData; + + if (qemuMigrationParamsSetCapability(vm, + QEMU_MONITOR_MIGRATION_CAPS_POSTCOPY, + state, migParams) < 0) + return -1; + + priv->job.postcopyEnabled = state; + return 0; +} + + /* qemuMigrationParamsEnableTLS * @driver: pointer to qemu driver * @vm: domain object @@ -272,18 +330,18 @@ qemuMigrationParamsSetCompression(virQEMUDriverPtr driver, int ret = -1; qemuDomainObjPrivatePtr priv = vm->privateData; - if (qemuMigrationOptionSet(driver, vm, - QEMU_MONITOR_MIGRATION_CAPS_XBZRLE, - compression->methods & - (1ULL << QEMU_MIGRATION_COMPRESS_XBZRLE), - asyncJob) < 0) + if (qemuMigrationParamsSetCapability(vm, + QEMU_MONITOR_MIGRATION_CAPS_XBZRLE, + compression->methods & + (1ULL << QEMU_MIGRATION_COMPRESS_XBZRLE), + migParams) < 0) return -1; - if (qemuMigrationOptionSet(driver, vm, - QEMU_MONITOR_MIGRATION_CAPS_COMPRESS, - compression->methods & - (1ULL << QEMU_MIGRATION_COMPRESS_MT), - asyncJob) < 0) + if (qemuMigrationParamsSetCapability(vm, + QEMU_MONITOR_MIGRATION_CAPS_COMPRESS, + compression->methods & + (1ULL << QEMU_MIGRATION_COMPRESS_MT), + migParams) < 0) return -1; if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) @@ -369,6 +427,11 @@ qemuMigrationParamsCheck(virQEMUDriverPtr driver, if (!(origParams = qemuMigrationParamsNew())) goto cleanup; + /* + * We want to disable all migration capabilities after migration, no need + * to ask QEMU for their current settings. + */ + if (qemuMonitorGetMigrationParams(priv->mon, &origParams->params) < 0) goto cleanup; @@ -398,25 +461,17 @@ qemuMigrationParamsReset(virQEMUDriverPtr driver, int asyncJob, qemuMigrationParamsPtr origParams) { - qemuMonitorMigrationCaps cap; virErrorPtr err = virSaveLastError(); VIR_DEBUG("Resetting migration parameters %p", origParams); - if (!virDomainObjIsActive(vm)) + if (!virDomainObjIsActive(vm) || !origParams) goto cleanup; - if (origParams) { - if (qemuMigrationParamsApply(driver, vm, asyncJob, origParams) < 0) - goto cleanup; - qemuMigrationParamsResetTLS(driver, vm, asyncJob, origParams); - } + if (qemuMigrationParamsApply(driver, vm, asyncJob, origParams) < 0) + goto cleanup; - for (cap = 0; cap < QEMU_MONITOR_MIGRATION_CAPS_LAST; cap++) { - if (qemuMigrationCapsGet(vm, cap) && - qemuMigrationOptionSet(driver, vm, cap, false, asyncJob) < 0) - goto cleanup; - } + qemuMigrationParamsResetTLS(driver, vm, asyncJob, origParams); cleanup: if (err) { diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index 37e528f36c..e341f73900 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -68,6 +68,17 @@ qemuMigrationParamsApply(virQEMUDriverPtr driver, int asyncJob, qemuMigrationParamsPtr migParams); +int +qemuMigrationParamsSetCapability(virDomainObjPtr vm, + qemuMonitorMigrationCaps capability, + bool state, + qemuMigrationParamsPtr migParams); + +int +qemuMigrationParamsSetPostCopy(virDomainObjPtr vm, + bool state, + qemuMigrationParamsPtr migParams); + int qemuMigrationParamsEnableTLS(virQEMUDriverPtr driver, virDomainObjPtr vm, -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:16PM +0200, Jiri Denemark wrote:
Migration capabilities are closely related to migration parameters and it makes sense to keep them in a single data structure. Similarly to migration parameters the capabilities are all send to QEMU at once in qemuMigrationParamsApply, all other APIs operate on the qemuMigrationParams structure.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 100 ++++++------------------------- src/qemu/qemu_migration.h | 7 --- src/qemu/qemu_migration_params.c | 99 +++++++++++++++++++++++------- src/qemu/qemu_migration_params.h | 11 ++++ 4 files changed, 107 insertions(+), 110 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Rework all remaining callers of qemuMonitorSetMigrationCapability to use the new qemuMonitorSetMigrationCapabilities API. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 11 ++++++++--- tests/qemumonitorjsontest.c | 16 +++++++++++----- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index d934a93086..53e105bec8 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -487,6 +487,7 @@ qemuMigrationCapsCheck(virQEMUDriverPtr driver, int asyncJob) { qemuDomainObjPrivatePtr priv = vm->privateData; + virBitmapPtr migEvent = NULL; char **caps = NULL; char **capStr; int ret = -1; @@ -521,12 +522,16 @@ qemuMigrationCapsCheck(virQEMUDriverPtr driver, } if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT)) { + migEvent = virBitmapNew(QEMU_MONITOR_MIGRATION_CAPS_LAST); + if (!migEvent) + goto cleanup; + + ignore_value(virBitmapSetBit(migEvent, QEMU_MONITOR_MIGRATION_CAPS_EVENTS)); + if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) goto cleanup; - rc = qemuMonitorSetMigrationCapability(priv->mon, - QEMU_MONITOR_MIGRATION_CAPS_EVENTS, - true); + rc = qemuMonitorSetMigrationCapabilities(priv->mon, migEvent, migEvent); if (qemuDomainObjExitMonitor(driver, vm) < 0) goto cleanup; diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index 0afdc80038..1cad383596 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -2229,13 +2229,14 @@ testQemuMonitorJSONqemuMonitorJSONGetTargetArch(const void *data) } static int -testQemuMonitorJSONqemuMonitorJSONGetMigrationCapability(const void *data) +testQemuMonitorJSONqemuMonitorJSONGetMigrationCapabilities(const void *data) { virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data; qemuMonitorTestPtr test = qemuMonitorTestNewSimple(true, xmlopt); int ret = -1; const char *cap; char **caps = NULL; + virBitmapPtr bitmap = NULL; const char *reply = "{" " \"return\": [" @@ -2266,15 +2267,20 @@ testQemuMonitorJSONqemuMonitorJSONGetMigrationCapability(const void *data) goto cleanup; } - if (qemuMonitorJSONSetMigrationCapability(qemuMonitorTestGetMonitor(test), - QEMU_MONITOR_MIGRATION_CAPS_XBZRLE, - true) < 0) + bitmap = virBitmapNew(QEMU_MONITOR_MIGRATION_CAPS_LAST); + if (!bitmap) + goto cleanup; + + ignore_value(virBitmapSetBit(bitmap, QEMU_MONITOR_MIGRATION_CAPS_XBZRLE)); + if (qemuMonitorJSONSetMigrationCapabilities(qemuMonitorTestGetMonitor(test), + bitmap, bitmap) < 0) goto cleanup; ret = 0; cleanup: qemuMonitorTestFree(test); virStringListFree(caps); + virBitmapFree(bitmap); return ret; } @@ -2999,7 +3005,7 @@ mymain(void) DO_TEST(qemuMonitorJSONGetChardevInfo); DO_TEST(qemuMonitorJSONSetBlockIoThrottle); DO_TEST(qemuMonitorJSONGetTargetArch); - DO_TEST(qemuMonitorJSONGetMigrationCapability); + DO_TEST(qemuMonitorJSONGetMigrationCapabilities); DO_TEST(qemuMonitorJSONQueryCPUs); DO_TEST(qemuMonitorJSONGetVirtType); DO_TEST(qemuMonitorJSONSendKey); -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:17PM +0200, Jiri Denemark wrote:
Rework all remaining callers of qemuMonitorSetMigrationCapability to use the new qemuMonitorSetMigrationCapabilities API.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 11 ++++++++--- tests/qemumonitorjsontest.c | 16 +++++++++++----- 2 files changed, 19 insertions(+), 8 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_monitor.c | 14 ---------- src/qemu/qemu_monitor.h | 3 -- src/qemu/qemu_monitor_json.c | 53 ------------------------------------ src/qemu/qemu_monitor_json.h | 3 -- 4 files changed, 73 deletions(-) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 7ea72af788..09f21ba77d 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -3977,20 +3977,6 @@ qemuMonitorGetMigrationCapabilities(qemuMonitorPtr mon, } -int -qemuMonitorSetMigrationCapability(qemuMonitorPtr mon, - qemuMonitorMigrationCaps capability, - bool state) -{ - VIR_DEBUG("capability=%s, state=%d", - qemuMonitorMigrationCapsTypeToString(capability), state); - - QEMU_CHECK_MONITOR_JSON(mon); - - return qemuMonitorJSONSetMigrationCapability(mon, capability, state); -} - - int qemuMonitorSetMigrationCapabilities(qemuMonitorPtr mon, virBitmapPtr caps, diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 870aae5cbd..c95b3a2ef4 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -760,9 +760,6 @@ VIR_ENUM_DECL(qemuMonitorMigrationCaps); int qemuMonitorGetMigrationCapabilities(qemuMonitorPtr mon, char ***capabilities); -int qemuMonitorSetMigrationCapability(qemuMonitorPtr mon, - qemuMonitorMigrationCaps capability, - bool state); int qemuMonitorSetMigrationCapabilities(qemuMonitorPtr mon, virBitmapPtr caps, virBitmapPtr states); diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 7ab73657a0..c6cb71addf 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -6198,59 +6198,6 @@ qemuMonitorJSONGetMigrationCapabilities(qemuMonitorPtr mon, } -int -qemuMonitorJSONSetMigrationCapability(qemuMonitorPtr mon, - qemuMonitorMigrationCaps capability, - bool state) -{ - int ret = -1; - - virJSONValuePtr cmd = NULL; - virJSONValuePtr reply = NULL; - virJSONValuePtr cap = NULL; - virJSONValuePtr caps; - - if (!(caps = virJSONValueNewArray())) - goto cleanup; - - if (!(cap = virJSONValueNewObject())) - goto cleanup; - - if (virJSONValueObjectAppendString( - cap, "capability", - qemuMonitorMigrationCapsTypeToString(capability)) < 0) - goto cleanup; - - if (virJSONValueObjectAppendBoolean(cap, "state", state) < 0) - goto cleanup; - - if (virJSONValueArrayAppend(caps, cap) < 0) - goto cleanup; - - cap = NULL; - - cmd = qemuMonitorJSONMakeCommand("migrate-set-capabilities", - "a:capabilities", &caps, - NULL); - if (!cmd) - goto cleanup; - - if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) - goto cleanup; - - if (qemuMonitorJSONCheckError(cmd, reply) < 0) - goto cleanup; - - ret = 0; - cleanup: - virJSONValueFree(caps); - virJSONValueFree(cap); - virJSONValueFree(cmd); - virJSONValueFree(reply); - return ret; -} - - int qemuMonitorJSONSetMigrationCapabilities(qemuMonitorPtr mon, virBitmapPtr caps, diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 76e6738f44..a73e98815c 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -145,9 +145,6 @@ int qemuMonitorJSONGetMigrationStats(qemuMonitorPtr mon, int qemuMonitorJSONGetMigrationCapabilities(qemuMonitorPtr mon, char ***capabilities); -int qemuMonitorJSONSetMigrationCapability(qemuMonitorPtr mon, - qemuMonitorMigrationCaps capability, - bool state); int qemuMonitorJSONSetMigrationCapabilities(qemuMonitorPtr mon, virBitmapPtr caps, virBitmapPtr states); -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:18PM +0200, Jiri Denemark wrote:
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_monitor.c | 14 ---------- src/qemu/qemu_monitor.h | 3 -- src/qemu/qemu_monitor_json.c | 53 ------------------------------------ src/qemu/qemu_monitor_json.h | 3 -- 4 files changed, 73 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Originally QEMU provided query-migrate-cache-size and migrate-set-cache-size QMP commands for querying/setting XBZRLE cache size. In version 2.11 QEMU added support for XBZRLE cache size to the general migration paramaters commands. This patch adds support for this parameter to libvirt to make sure it is properly restored to its original value after a failed or aborted migration. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_monitor.c | 5 +++-- src/qemu/qemu_monitor.h | 3 +++ src/qemu/qemu_monitor_json.c | 2 ++ tests/qemumonitorjsontest.c | 4 +++- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 09f21ba77d..18b54e2da8 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -2639,7 +2639,7 @@ qemuMonitorSetMigrationParams(qemuMonitorPtr mon, "decompressThreads=%d:%d cpuThrottleInitial=%d:%d " "cpuThrottleIncrement=%d:%d tlsCreds=%s tlsHostname=%s " "maxBandwidth=%d:%llu downtimeLimit=%d:%llu " - "blockIncremental=%d:%d", + "blockIncremental=%d:%d xbzrleCacheSize=%d:%llu", params->compressLevel_set, params->compressLevel, params->compressThreads_set, params->compressThreads, params->decompressThreads_set, params->decompressThreads, @@ -2648,7 +2648,8 @@ qemuMonitorSetMigrationParams(qemuMonitorPtr mon, NULLSTR(params->tlsCreds), NULLSTR(params->tlsHostname), params->maxBandwidth_set, params->maxBandwidth, params->downtimeLimit_set, params->downtimeLimit, - params->blockIncremental_set, params->blockIncremental); + params->blockIncremental_set, params->blockIncremental, + params->xbzrleCacheSize_set, params->xbzrleCacheSize); QEMU_CHECK_MONITOR_JSON(mon); diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index c95b3a2ef4..2bb4dbc667 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -673,6 +673,9 @@ struct _qemuMonitorMigrationParams { bool blockIncremental_set; bool blockIncremental; + + bool xbzrleCacheSize_set; + unsigned long long xbzrleCacheSize; }; int qemuMonitorGetMigrationParams(qemuMonitorPtr mon, diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index c6cb71addf..acc126629e 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -2833,6 +2833,7 @@ qemuMonitorJSONGetMigrationParams(qemuMonitorPtr mon, PARSE_ULONG(maxBandwidth, "max-bandwidth"); PARSE_ULONG(downtimeLimit, "downtime-limit"); PARSE_BOOL(blockIncremental, "block-incremental"); + PARSE_ULONG(xbzrleCacheSize, "xbzrle-cache-size"); #undef PARSE_SET #undef PARSE_INT @@ -2898,6 +2899,7 @@ qemuMonitorJSONSetMigrationParams(qemuMonitorPtr mon, APPEND_ULONG(maxBandwidth, "max-bandwidth"); APPEND_ULONG(downtimeLimit, "downtime-limit"); APPEND_BOOL(blockIncremental, "block-incremental"); + APPEND_ULONG(xbzrleCacheSize, "xbzrle-cache-size"); #undef APPEND #undef APPEND_INT diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index 1cad383596..8a5b0be64b 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -1810,7 +1810,8 @@ testQemuMonitorJSONqemuMonitorJSONGetMigrationParams(const void *data) " \"tls-hostname\": \"\"," " \"max-bandwidth\": 1234567890," " \"downtime-limit\": 500," - " \"block-incremental\": true" + " \"block-incremental\": true," + " \"xbzrle-cache-size\": 67108864" " }" "}") < 0) { goto cleanup; @@ -1867,6 +1868,7 @@ testQemuMonitorJSONqemuMonitorJSONGetMigrationParams(const void *data) CHECK_ULONG(maxBandwidth, "max-bandwidth", 1234567890ULL); CHECK_ULONG(downtimeLimit, "downtime-limit", 500ULL); CHECK_BOOL(blockIncremental, "block-incremental", true); + CHECK_ULONG(xbzrleCacheSize, "xbzrle-cache-size", 67108864ULL); #undef CHECK_NUM #undef CHECK_INT -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:19PM +0200, Jiri Denemark wrote:
Originally QEMU provided query-migrate-cache-size and migrate-set-cache-size QMP commands for querying/setting XBZRLE cache size. In version 2.11 QEMU added support for XBZRLE cache size to the general migration paramaters commands.
This patch adds support for this parameter to libvirt to make sure it is properly restored to its original value after a failed or aborted migration.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_monitor.c | 5 +++-- src/qemu/qemu_monitor.h | 3 +++ src/qemu/qemu_monitor_json.c | 2 ++ tests/qemumonitorjsontest.c | 4 +++- 4 files changed, 11 insertions(+), 3 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Prefer xbzrle-cache-size migration parameter over the special migrate-set-cache-size QMP command. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 6 ++--- src/qemu/qemu_migration_params.c | 42 +++++++++++++++++--------------- src/qemu/qemu_migration_params.h | 4 +-- 3 files changed, 25 insertions(+), 27 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index e01c2a209d..476417c15d 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2383,8 +2383,7 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, if (qemuMigrationParamsCheck(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN) < 0) goto stopjob; - if (qemuMigrationParamsSetCompression(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN, - compression, migParams) < 0) + if (qemuMigrationParamsSetCompression(vm, compression, migParams) < 0) goto stopjob; /* Migrations using TLS need to add the "tls-creds-x509" object and @@ -3383,8 +3382,7 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, goto error; } - if (qemuMigrationParamsSetCompression(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, - compression, migParams) < 0) + if (qemuMigrationParamsSetCompression(vm, compression, migParams) < 0) goto error; if (qemuMigrationParamsSetCapability(vm, diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 53e105bec8..faaaa29cc9 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -141,6 +141,7 @@ qemuMigrationParamsApply(virQEMUDriverPtr driver, qemuMigrationParamsPtr migParams) { qemuDomainObjPrivatePtr priv = vm->privateData; + bool xbzrleCacheSize_old = false; int ret = -1; if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) @@ -150,6 +151,20 @@ qemuMigrationParamsApply(virQEMUDriverPtr driver, migParams->caps) < 0) goto cleanup; + /* If QEMU is too old to support xbzrle-cache-size migration parameter, + * we need to set it via migrate-set-cache-size and tell + * qemuMonitorSetMigrationParams to ignore this parameter. + */ + if (migParams->params.xbzrleCacheSize_set && + (!priv->job.migParams || + !priv->job.migParams->params.xbzrleCacheSize_set)) { + if (qemuMonitorSetMigrationCacheSize(priv->mon, + migParams->params.xbzrleCacheSize) < 0) + goto cleanup; + xbzrleCacheSize_old = true; + migParams->params.xbzrleCacheSize_set = false; + } + if (qemuMonitorSetMigrationParams(priv->mon, &migParams->params) < 0) goto cleanup; @@ -159,6 +174,9 @@ qemuMigrationParamsApply(virQEMUDriverPtr driver, if (qemuDomainObjExitMonitor(driver, vm) < 0) ret = -1; + if (xbzrleCacheSize_old) + migParams->params.xbzrleCacheSize_set = true; + return ret; } @@ -321,15 +339,10 @@ qemuMigrationParamsDisableTLS(virDomainObjPtr vm, int -qemuMigrationParamsSetCompression(virQEMUDriverPtr driver, - virDomainObjPtr vm, - int asyncJob, +qemuMigrationParamsSetCompression(virDomainObjPtr vm, qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams) { - int ret = -1; - qemuDomainObjPrivatePtr priv = vm->privateData; - if (qemuMigrationParamsSetCapability(vm, QEMU_MONITOR_MIGRATION_CAPS_XBZRLE, compression->methods & @@ -344,9 +357,6 @@ qemuMigrationParamsSetCompression(virQEMUDriverPtr driver, migParams) < 0) return -1; - if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) - return -1; - migParams->params.compressLevel_set = compression->level_set; migParams->params.compressLevel = compression->level; @@ -356,18 +366,10 @@ qemuMigrationParamsSetCompression(virQEMUDriverPtr driver, migParams->params.decompressThreads_set = compression->dthreads_set; migParams->params.decompressThreads = compression->dthreads; - if (compression->xbzrle_cache_set && - qemuMonitorSetMigrationCacheSize(priv->mon, - compression->xbzrle_cache) < 0) - goto cleanup; + migParams->params.xbzrleCacheSize_set = compression->xbzrle_cache_set; + migParams->params.xbzrleCacheSize = compression->xbzrle_cache; - ret = 0; - - cleanup: - if (qemuDomainObjExitMonitor(driver, vm) < 0) - ret = -1; - - return ret; + return 0; } diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index e341f73900..4cb70f62a4 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -94,9 +94,7 @@ qemuMigrationParamsDisableTLS(virDomainObjPtr vm, qemuMigrationParamsPtr migParams); int -qemuMigrationParamsSetCompression(virQEMUDriverPtr driver, - virDomainObjPtr vm, - int asyncJob, +qemuMigrationParamsSetCompression(virDomainObjPtr vm, qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams); -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:20PM +0200, Jiri Denemark wrote:
Prefer xbzrle-cache-size migration parameter over the special migrate-set-cache-size QMP command.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 6 ++--- src/qemu/qemu_migration_params.c | 42 +++++++++++++++++--------------- src/qemu/qemu_migration_params.h | 4 +-- 3 files changed, 25 insertions(+), 27 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

We reached the point when qemuMigrationParamsApply is the only API which sends migration parameters and capabilities to QEMU. Thus all but the TLS parameters can be set before we ask QEMU for the current values of all parameters in qemuMigrationParamsCheck. Supported migration capabilities are queried as soon as libvirt connects to QEMU monitor so we can check them anytime. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 476417c15d..c97911039d 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2380,25 +2380,9 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, dataFD[1] = -1; /* 'st' owns the FD now & will close it */ } - if (qemuMigrationParamsCheck(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN) < 0) - goto stopjob; - if (qemuMigrationParamsSetCompression(vm, compression, migParams) < 0) goto stopjob; - /* Migrations using TLS need to add the "tls-creds-x509" object and - * set the migration TLS parameters */ - if (flags & VIR_MIGRATE_TLS) { - if (qemuMigrationParamsEnableTLS(driver, vm, true, - QEMU_ASYNC_JOB_MIGRATION_IN, - &tlsAlias, &secAlias, NULL, - migParams) < 0) - goto stopjob; - } else { - if (qemuMigrationParamsDisableTLS(vm, migParams) < 0) - goto stopjob; - } - if (STREQ_NULLABLE(protocol, "rdma") && virProcessSetMaxMemLock(vm->pid, vm->def->mem.hard_limit << 10) < 0) { goto stopjob; @@ -2414,6 +2398,22 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, migParams) < 0) goto stopjob; + if (qemuMigrationParamsCheck(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN) < 0) + goto stopjob; + + /* Migrations using TLS need to add the "tls-creds-x509" object and + * set the migration TLS parameters */ + if (flags & VIR_MIGRATE_TLS) { + if (qemuMigrationParamsEnableTLS(driver, vm, true, + QEMU_ASYNC_JOB_MIGRATION_IN, + &tlsAlias, &secAlias, NULL, + migParams) < 0) + goto stopjob; + } else { + if (qemuMigrationParamsDisableTLS(vm, migParams) < 0) + goto stopjob; + } + if (qemuMigrationParamsApply(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN, migParams) < 0) goto stopjob; -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:21PM +0200, Jiri Denemark wrote:
We reached the point when qemuMigrationParamsApply is the only API which sends migration parameters and capabilities to QEMU. Thus all but the TLS parameters can be set before we ask QEMU for the current values of all parameters in qemuMigrationParamsCheck.
Supported migration capabilities are queried as soon as libvirt connects to QEMU monitor so we can check them anytime.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

We reached the point when qemuMigrationParamsApply is the only API which sends migration parameters and capabilities to QEMU. Thus all but the TLS parameters can be set before we ask QEMU for the current values of all parameters in qemuMigrationParamsCheck. Supported migration capabilities are queried as soon as libvirt connects to QEMU monitor so we can check them anytime. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 67 +++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 35 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index c97911039d..3f443a756b 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -3335,6 +3335,34 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, if (qemuMigrationSrcGraphicsRelocate(driver, vm, mig, graphicsuri) < 0) VIR_WARN("unable to provide data for graphics client relocation"); + if (qemuMigrationParamsSetCompression(vm, compression, migParams) < 0) + goto error; + + if (qemuMigrationParamsSetCapability(vm, + QEMU_MONITOR_MIGRATION_CAPS_AUTO_CONVERGE, + flags & VIR_MIGRATE_AUTO_CONVERGE, + migParams) < 0) + goto error; + + if (qemuMigrationParamsSetCapability(vm, + QEMU_MONITOR_MIGRATION_CAPS_RDMA_PIN_ALL, + flags & VIR_MIGRATE_RDMA_PIN_ALL, + migParams) < 0) + goto error; + + if (qemuMigrationParamsSetPostCopy(vm, flags & VIR_MIGRATE_POSTCOPY, + migParams) < 0) + goto error; + + if (qemuMigrationCapsGet(vm, QEMU_MONITOR_MIGRATION_CAPS_PAUSE_BEFORE_SWITCHOVER) && + qemuMigrationParamsSetCapability(vm, + QEMU_MONITOR_MIGRATION_CAPS_PAUSE_BEFORE_SWITCHOVER, + true, migParams) < 0) + goto error; + + if (qemuMigrationParamsCheck(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) + goto error; + if (flags & VIR_MIGRATE_TLS) { const char *hostname = NULL; @@ -3354,6 +3382,10 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, goto error; } + if (qemuMigrationParamsApply(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, + migParams) < 0) + goto error; + if (migrate_flags & (QEMU_MONITOR_MIGRATE_NON_SHARED_DISK | QEMU_MONITOR_MIGRATE_NON_SHARED_INC)) { if (mig->nbd) { @@ -3382,35 +3414,6 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, goto error; } - if (qemuMigrationParamsSetCompression(vm, compression, migParams) < 0) - goto error; - - if (qemuMigrationParamsSetCapability(vm, - QEMU_MONITOR_MIGRATION_CAPS_AUTO_CONVERGE, - flags & VIR_MIGRATE_AUTO_CONVERGE, - migParams) < 0) - goto error; - - if (qemuMigrationParamsSetCapability(vm, - QEMU_MONITOR_MIGRATION_CAPS_RDMA_PIN_ALL, - flags & VIR_MIGRATE_RDMA_PIN_ALL, - migParams) < 0) - goto error; - - if (qemuMigrationParamsSetPostCopy(vm, flags & VIR_MIGRATE_POSTCOPY, - migParams) < 0) - goto error; - - if (qemuMigrationCapsGet(vm, QEMU_MONITOR_MIGRATION_CAPS_PAUSE_BEFORE_SWITCHOVER) && - qemuMigrationParamsSetCapability(vm, - QEMU_MONITOR_MIGRATION_CAPS_PAUSE_BEFORE_SWITCHOVER, - true, migParams) < 0) - goto error; - - if (qemuMigrationParamsApply(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, - migParams) < 0) - goto error; - if (qemuDomainObjEnterMonitorAsync(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) goto error; @@ -4508,9 +4511,6 @@ qemuMigrationSrcPerformJob(virQEMUDriverPtr driver, qemuMigrationSrcStoreDomainState(vm); - if (qemuMigrationParamsCheck(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) - goto endjob; - if ((flags & (VIR_MIGRATE_TUNNELLED | VIR_MIGRATE_PEER2PEER))) { ret = qemuMigrationSrcPerformPeer2Peer(driver, conn, vm, xmlin, persist_xml, dconnuri, uri, graphicsuri, listenAddress, @@ -4616,9 +4616,6 @@ qemuMigrationSrcPerformPhase(virQEMUDriverPtr driver, virCloseCallbacksUnset(driver->closeCallbacks, vm, qemuMigrationSrcCleanup); - if (qemuMigrationParamsCheck(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) - goto endjob; - ret = qemuMigrationSrcPerformNative(driver, vm, persist_xml, uri, cookiein, cookieinlen, cookieout, cookieoutlen, flags, resource, NULL, graphicsuri, -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:22PM +0200, Jiri Denemark wrote:
We reached the point when qemuMigrationParamsApply is the only API which sends migration parameters and capabilities to QEMU. Thus all but the TLS parameters can be set before we ask QEMU for the current values of all parameters in qemuMigrationParamsCheck.
Supported migration capabilities are queried as soon as libvirt connects to QEMU monitor so we can check them anytime.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 67 +++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 35 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Instead of checking each capability at the time we want to set it in qemuMigrationParamsSetCapability we can check all of them at once in qemuMigrationParamsCheck. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 6 ++++-- src/qemu/qemu_migration_params.c | 33 ++++++++++++++++++-------------- src/qemu/qemu_migration_params.h | 3 ++- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 3f443a756b..eb544bbb77 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2398,7 +2398,8 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, migParams) < 0) goto stopjob; - if (qemuMigrationParamsCheck(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN) < 0) + if (qemuMigrationParamsCheck(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN, + migParams) < 0) goto stopjob; /* Migrations using TLS need to add the "tls-creds-x509" object and @@ -3360,7 +3361,8 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, true, migParams) < 0) goto error; - if (qemuMigrationParamsCheck(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) + if (qemuMigrationParamsCheck(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, + migParams) < 0) goto error; if (flags & VIR_MIGRATE_TLS) { diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index faaaa29cc9..a7b5ce385e 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -182,23 +182,11 @@ qemuMigrationParamsApply(virQEMUDriverPtr driver, int -qemuMigrationParamsSetCapability(virDomainObjPtr vm, +qemuMigrationParamsSetCapability(virDomainObjPtr vm ATTRIBUTE_UNUSED, qemuMonitorMigrationCaps capability, bool state, qemuMigrationParamsPtr migParams) { - if (!qemuMigrationCapsGet(vm, capability)) { - if (!state) { - /* Unsupported but we want it off anyway */ - return 0; - } - - virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, - _("Migration option '%s' is not supported by QEMU binary"), - qemuMonitorMigrationCapsTypeToString(capability)); - return -1; - } - if (state) ignore_value(virBitmapSetBit(migParams->caps, capability)); else @@ -413,16 +401,33 @@ qemuMigrationParamsResetTLS(virQEMUDriverPtr driver, * * Check supported migration parameters and keep their original values in * qemuDomainJobObj so that we can properly reset them at the end of migration. + * Reports an error if any of the currently used capabilities in @migParams + * are unsupported by QEMU. */ int qemuMigrationParamsCheck(virQEMUDriverPtr driver, virDomainObjPtr vm, - int asyncJob) + int asyncJob, + qemuMigrationParamsPtr migParams) { qemuDomainObjPrivatePtr priv = vm->privateData; qemuMigrationParamsPtr origParams = NULL; + qemuMonitorMigrationCaps cap; int ret = -1; + for (cap = 0; cap < QEMU_MONITOR_MIGRATION_CAPS_LAST; cap++) { + bool state = false; + + ignore_value(virBitmapGetBit(migParams->caps, cap, &state)); + + if (state && !qemuMigrationCapsGet(vm, cap)) { + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, + _("Migration option '%s' is not supported by QEMU binary"), + qemuMonitorMigrationCapsTypeToString(cap)); + return -1; + } + } + if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) return -1; diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index 4cb70f62a4..7ca667a507 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -101,7 +101,8 @@ qemuMigrationParamsSetCompression(virDomainObjPtr vm, int qemuMigrationParamsCheck(virQEMUDriverPtr driver, virDomainObjPtr vm, - int asyncJob); + int asyncJob, + qemuMigrationParamsPtr migParams); void qemuMigrationParamsReset(virQEMUDriverPtr driver, -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:23PM +0200, Jiri Denemark wrote:
Instead of checking each capability at the time we want to set it in qemuMigrationParamsSetCapability we can check all of them at once in qemuMigrationParamsCheck.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 6 ++++-- src/qemu/qemu_migration_params.c | 33 ++++++++++++++++++-------------- src/qemu/qemu_migration_params.h | 3 ++- 3 files changed, 25 insertions(+), 17 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Some migration parameters and capabilities are supposed to be set on both sides of migration while others should only be set on one side. For example, CPU throttling parameters make no sense on the destination and they can be used even if the destination is too old to support them. To make qemuMigrationParamsFromFlags more general and usable on both sides of migration, we need to tell it what side it's been called on. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_driver.c | 3 ++- src/qemu/qemu_migration_params.c | 9 ++++++--- src/qemu/qemu_migration_params.h | 8 +++++++- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 6e6fc130c5..d8a641f77d 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -12765,7 +12765,8 @@ qemuDomainMigratePerform3Params(virDomainPtr dom, if (nmigrate_disks < 0) goto cleanup; - if (!(migParams = qemuMigrationParamsFromFlags(params, nparams, flags))) + if (!(migParams = qemuMigrationParamsFromFlags(params, nparams, flags, + QEMU_MIGRATION_SOURCE))) goto cleanup; if (!(compression = qemuMigrationAnyCompressionParse(params, nparams, flags))) diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index a7b5ce385e..b55abc2e36 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -80,7 +80,8 @@ qemuMigrationParamsFree(qemuMigrationParamsPtr migParams) qemuMigrationParamsPtr qemuMigrationParamsFromFlags(virTypedParameterPtr params, int nparams, - unsigned long flags) + unsigned long flags, + qemuMigrationParty party) { qemuMigrationParamsPtr migParams; @@ -102,8 +103,10 @@ qemuMigrationParamsFromFlags(virTypedParameterPtr params, migParams->params.VAR ## _set = true; \ } while (0) - GET(AUTO_CONVERGE_INITIAL, cpuThrottleInitial); - GET(AUTO_CONVERGE_INCREMENT, cpuThrottleIncrement); + if (party == QEMU_MIGRATION_SOURCE) { + GET(AUTO_CONVERGE_INITIAL, cpuThrottleInitial); + GET(AUTO_CONVERGE_INCREMENT, cpuThrottleIncrement); + } #undef GET diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index 7ca667a507..d66fdb7cde 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -50,6 +50,11 @@ struct _qemuMigrationCompression { typedef struct _qemuMigrationParams qemuMigrationParams; typedef qemuMigrationParams *qemuMigrationParamsPtr; +typedef enum { + QEMU_MIGRATION_SOURCE = (1 << 0), + QEMU_MIGRATION_DESTINATION = (1 << 1), +} qemuMigrationParty; + qemuMigrationParamsPtr qemuMigrationParamsNew(void); @@ -57,7 +62,8 @@ qemuMigrationParamsNew(void); qemuMigrationParamsPtr qemuMigrationParamsFromFlags(virTypedParameterPtr params, int nparams, - unsigned long flags); + unsigned long flags, + qemuMigrationParty party); void qemuMigrationParamsFree(qemuMigrationParamsPtr migParams); -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:24PM +0200, Jiri Denemark wrote:
Some migration parameters and capabilities are supposed to be set on both sides of migration while others should only be set on one side. For example, CPU throttling parameters make no sense on the destination and they can be used even if the destination is too old to support them.
To make qemuMigrationParamsFromFlags more general and usable on both sides of migration, we need to tell it what side it's been called on.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_driver.c | 3 ++- src/qemu/qemu_migration_params.c | 9 ++++++--- src/qemu/qemu_migration_params.h | 8 +++++++- 3 files changed, 15 insertions(+), 5 deletions(-)
That does sound like a party I could vote for. Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Every migration entry point in qemu_driver is supposed to call qemuMigrationParamsFromFlags to transform flags and parameters into qemuMigrationParams structure and pass the result to qemuMigration* APIs. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_driver.c | 64 +++++++++++++++++++++++++++++++-------- src/qemu/qemu_migration.c | 23 ++++++-------- src/qemu/qemu_migration.h | 2 ++ 3 files changed, 62 insertions(+), 27 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index d8a641f77d..5271e01d92 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -12126,6 +12126,7 @@ qemuDomainMigratePrepareTunnel(virConnectPtr dconn, virQEMUDriverPtr driver = dconn->privateData; virDomainDefPtr def = NULL; char *origname = NULL; + qemuMigrationParamsPtr migParams = NULL; int ret = -1; virCheckFlags(QEMU_MIGRATION_FLAGS, -1); @@ -12136,6 +12137,10 @@ qemuDomainMigratePrepareTunnel(virConnectPtr dconn, goto cleanup; } + if (!(migParams = qemuMigrationParamsFromFlags(NULL, 0, flags, + QEMU_MIGRATION_DESTINATION))) + goto cleanup; + if (virLockManagerPluginUsesState(driver->lockManager)) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Cannot use migrate v2 protocol with lock manager %s"), @@ -12151,9 +12156,10 @@ qemuDomainMigratePrepareTunnel(virConnectPtr dconn, ret = qemuMigrationDstPrepareTunnel(driver, dconn, NULL, 0, NULL, NULL, /* No cookies in v2 */ - st, &def, origname, flags); + st, &def, origname, migParams, flags); cleanup: + qemuMigrationParamsFree(migParams); VIR_FREE(origname); virDomainDefFree(def); return ret; @@ -12178,6 +12184,7 @@ qemuDomainMigratePrepare2(virConnectPtr dconn, virDomainDefPtr def = NULL; char *origname = NULL; qemuMigrationCompressionPtr compression = NULL; + qemuMigrationParamsPtr migParams = NULL; int ret = -1; virCheckFlags(QEMU_MIGRATION_FLAGS, -1); @@ -12195,6 +12202,10 @@ qemuDomainMigratePrepare2(virConnectPtr dconn, if (!(compression = qemuMigrationAnyCompressionParse(NULL, 0, flags))) goto cleanup; + if (!(migParams = qemuMigrationParamsFromFlags(NULL, 0, flags, + QEMU_MIGRATION_DESTINATION))) + goto cleanup; + if (virLockManagerPluginUsesState(driver->lockManager)) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Cannot use migrate v2 protocol with lock manager %s"), @@ -12216,9 +12227,10 @@ qemuDomainMigratePrepare2(virConnectPtr dconn, NULL, 0, NULL, NULL, /* No cookies */ uri_in, uri_out, &def, origname, NULL, 0, NULL, 0, - compression, flags); + compression, migParams, flags); cleanup: + qemuMigrationParamsFree(migParams); VIR_FREE(compression); VIR_FREE(origname); virDomainDefFree(def); @@ -12252,10 +12264,11 @@ qemuDomainMigratePerform(virDomainPtr dom, goto cleanup; } - if (!(migParams = qemuMigrationParamsNew())) + if (!(compression = qemuMigrationAnyCompressionParse(NULL, 0, flags))) goto cleanup; - if (!(compression = qemuMigrationAnyCompressionParse(NULL, 0, flags))) + if (!(migParams = qemuMigrationParamsFromFlags(NULL, 0, flags, + QEMU_MIGRATION_SOURCE))) goto cleanup; if (!(vm = qemuDomObjFromDomain(dom))) @@ -12430,6 +12443,7 @@ qemuDomainMigratePrepare3(virConnectPtr dconn, virDomainDefPtr def = NULL; char *origname = NULL; qemuMigrationCompressionPtr compression = NULL; + qemuMigrationParamsPtr migParams = NULL; int ret = -1; virCheckFlags(QEMU_MIGRATION_FLAGS, -1); @@ -12447,6 +12461,10 @@ qemuDomainMigratePrepare3(virConnectPtr dconn, if (!(compression = qemuMigrationAnyCompressionParse(NULL, 0, flags))) goto cleanup; + if (!(migParams = qemuMigrationParamsFromFlags(NULL, 0, flags, + QEMU_MIGRATION_DESTINATION))) + goto cleanup; + if (!(def = qemuMigrationAnyPrepareDef(driver, dom_xml, dname, &origname))) goto cleanup; @@ -12458,9 +12476,10 @@ qemuDomainMigratePrepare3(virConnectPtr dconn, cookieout, cookieoutlen, uri_in, uri_out, &def, origname, NULL, 0, NULL, 0, - compression, flags); + compression, migParams, flags); cleanup: + qemuMigrationParamsFree(migParams); VIR_FREE(compression); VIR_FREE(origname); virDomainDefFree(def); @@ -12490,6 +12509,7 @@ qemuDomainMigratePrepare3Params(virConnectPtr dconn, const char **migrate_disks = NULL; char *origname = NULL; qemuMigrationCompressionPtr compression = NULL; + qemuMigrationParamsPtr migParams = NULL; int ret = -1; virCheckFlagsGoto(QEMU_MIGRATION_FLAGS, cleanup); @@ -12523,6 +12543,10 @@ qemuDomainMigratePrepare3Params(virConnectPtr dconn, if (!(compression = qemuMigrationAnyCompressionParse(params, nparams, flags))) goto cleanup; + if (!(migParams = qemuMigrationParamsFromFlags(params, nparams, flags, + QEMU_MIGRATION_DESTINATION))) + goto cleanup; + if (flags & VIR_MIGRATE_TUNNELLED) { /* this is a logical error; we never should have gotten here with * VIR_MIGRATE_TUNNELLED set @@ -12545,9 +12569,10 @@ qemuDomainMigratePrepare3Params(virConnectPtr dconn, uri_in, uri_out, &def, origname, listenAddress, nmigrate_disks, migrate_disks, nbdPort, - compression, flags); + compression, migParams, flags); cleanup: + qemuMigrationParamsFree(migParams); VIR_FREE(compression); VIR_FREE(migrate_disks); VIR_FREE(origname); @@ -12572,6 +12597,7 @@ qemuDomainMigratePrepareTunnel3(virConnectPtr dconn, virQEMUDriverPtr driver = dconn->privateData; virDomainDefPtr def = NULL; char *origname = NULL; + qemuMigrationParamsPtr migParams = NULL; int ret = -1; virCheckFlags(QEMU_MIGRATION_FLAGS, -1); @@ -12582,6 +12608,10 @@ qemuDomainMigratePrepareTunnel3(virConnectPtr dconn, goto cleanup; } + if (!(migParams = qemuMigrationParamsFromFlags(NULL, 0, flags, + QEMU_MIGRATION_DESTINATION))) + goto cleanup; + if (!(def = qemuMigrationAnyPrepareDef(driver, dom_xml, dname, &origname))) goto cleanup; @@ -12591,9 +12621,10 @@ qemuDomainMigratePrepareTunnel3(virConnectPtr dconn, ret = qemuMigrationDstPrepareTunnel(driver, dconn, cookiein, cookieinlen, cookieout, cookieoutlen, - st, &def, origname, flags); + st, &def, origname, migParams, flags); cleanup: + qemuMigrationParamsFree(migParams); VIR_FREE(origname); virDomainDefFree(def); return ret; @@ -12615,6 +12646,7 @@ qemuDomainMigratePrepareTunnel3Params(virConnectPtr dconn, const char *dom_xml = NULL; const char *dname = NULL; char *origname = NULL; + qemuMigrationParamsPtr migParams = NULL; int ret = -1; virCheckFlags(QEMU_MIGRATION_FLAGS, -1); @@ -12635,6 +12667,10 @@ qemuDomainMigratePrepareTunnel3Params(virConnectPtr dconn, goto cleanup; } + if (!(migParams = qemuMigrationParamsFromFlags(params, nparams, flags, + QEMU_MIGRATION_DESTINATION))) + goto cleanup; + if (!(def = qemuMigrationAnyPrepareDef(driver, dom_xml, dname, &origname))) goto cleanup; @@ -12644,9 +12680,10 @@ qemuDomainMigratePrepareTunnel3Params(virConnectPtr dconn, ret = qemuMigrationDstPrepareTunnel(driver, dconn, cookiein, cookieinlen, cookieout, cookieoutlen, - st, &def, origname, flags); + st, &def, origname, migParams, flags); cleanup: + qemuMigrationParamsFree(migParams); VIR_FREE(origname); virDomainDefFree(def); return ret; @@ -12674,10 +12711,11 @@ qemuDomainMigratePerform3(virDomainPtr dom, virCheckFlags(QEMU_MIGRATION_FLAGS, -1); - if (!(migParams = qemuMigrationParamsNew())) + if (!(compression = qemuMigrationAnyCompressionParse(NULL, 0, flags))) goto cleanup; - if (!(compression = qemuMigrationAnyCompressionParse(NULL, 0, flags))) + if (!(migParams = qemuMigrationParamsFromFlags(NULL, 0, flags, + QEMU_MIGRATION_SOURCE))) goto cleanup; if (!(vm = qemuDomObjFromDomain(dom))) @@ -12765,11 +12803,11 @@ qemuDomainMigratePerform3Params(virDomainPtr dom, if (nmigrate_disks < 0) goto cleanup; - if (!(migParams = qemuMigrationParamsFromFlags(params, nparams, flags, - QEMU_MIGRATION_SOURCE))) + if (!(compression = qemuMigrationAnyCompressionParse(params, nparams, flags))) goto cleanup; - if (!(compression = qemuMigrationAnyCompressionParse(params, nparams, flags))) + if (!(migParams = qemuMigrationParamsFromFlags(params, nparams, flags, + QEMU_MIGRATION_SOURCE))) goto cleanup; if (!(vm = qemuDomObjFromDomain(dom))) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index eb544bbb77..5614f0d43e 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2164,6 +2164,7 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, const char **migrate_disks, int nbdPort, qemuMigrationCompressionPtr compression, + qemuMigrationParamsPtr migParams, unsigned long flags) { virDomainObjPtr vm = NULL; @@ -2184,7 +2185,6 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, int rv; char *tlsAlias = NULL; char *secAlias = NULL; - qemuMigrationParamsPtr migParams = NULL; virNWFilterReadLockFilterUpdates(); @@ -2234,9 +2234,6 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, if (!qemuMigrationSrcIsAllowedHostdev(*def)) goto cleanup; - if (!(migParams = qemuMigrationParamsNew())) - goto cleanup; - /* Let migration hook filter domain XML */ if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) { char *xml; @@ -2503,7 +2500,6 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, virDomainObjRemoveTransientDef(vm); qemuDomainRemoveInactiveJob(driver, vm); } - qemuMigrationParamsFree(migParams); virDomainObjEndAPI(&vm); qemuDomainEventQueue(driver, event); qemuMigrationCookieFree(mig); @@ -2543,6 +2539,7 @@ qemuMigrationDstPrepareTunnel(virQEMUDriverPtr driver, virStreamPtr st, virDomainDefPtr *def, const char *origname, + qemuMigrationParamsPtr migParams, unsigned long flags) { qemuMigrationCompressionPtr compression = NULL; @@ -2566,7 +2563,7 @@ qemuMigrationDstPrepareTunnel(virQEMUDriverPtr driver, ret = qemuMigrationDstPrepareAny(driver, dconn, cookiein, cookieinlen, cookieout, cookieoutlen, def, origname, st, NULL, 0, false, NULL, 0, NULL, 0, - compression, flags); + compression, migParams, flags); VIR_FREE(compression); return ret; } @@ -2611,6 +2608,7 @@ qemuMigrationDstPrepareDirect(virQEMUDriverPtr driver, const char **migrate_disks, int nbdPort, qemuMigrationCompressionPtr compression, + qemuMigrationParamsPtr migParams, unsigned long flags) { unsigned short port = 0; @@ -2734,7 +2732,7 @@ qemuMigrationDstPrepareDirect(virQEMUDriverPtr driver, NULL, uri ? uri->scheme : "tcp", port, autoPort, listenAddress, nmigrate_disks, migrate_disks, nbdPort, - compression, flags); + compression, migParams, flags); cleanup: virURIFree(uri); VIR_FREE(hostname); @@ -3788,7 +3786,8 @@ qemuMigrationSrcPerformPeer2Peer2(virQEMUDriverPtr driver, const char *dconnuri, unsigned long flags, const char *dname, - unsigned long resource) + unsigned long resource, + qemuMigrationParamsPtr migParams) { virDomainPtr ddomain = NULL; char *uri_out = NULL; @@ -3800,7 +3799,6 @@ qemuMigrationSrcPerformPeer2Peer2(virQEMUDriverPtr driver, virStreamPtr st = NULL; unsigned long destflags; qemuMigrationCompressionPtr compression = NULL; - qemuMigrationParamsPtr migParams = NULL; VIR_DEBUG("driver=%p, sconn=%p, dconn=%p, vm=%p, dconnuri=%s, " "flags=0x%lx, dname=%s, resource=%lu", @@ -3822,9 +3820,6 @@ qemuMigrationSrcPerformPeer2Peer2(virQEMUDriverPtr driver, destflags = flags & ~(VIR_MIGRATE_ABORT_ON_ERROR | VIR_MIGRATE_AUTO_CONVERGE); - if (!(migParams = qemuMigrationParamsNew())) - goto cleanup; - if (!(compression = qemuMigrationAnyCompressionParse(NULL, 0, flags))) goto cleanup; @@ -3926,7 +3921,6 @@ qemuMigrationSrcPerformPeer2Peer2(virQEMUDriverPtr driver, virSetError(orig_err); virFreeError(orig_err); } - qemuMigrationParamsFree(migParams); VIR_FREE(uri_out); VIR_FREE(cookie); VIR_FREE(compression); @@ -4442,7 +4436,8 @@ qemuMigrationSrcPerformPeer2Peer(virQEMUDriverPtr driver, useParams, flags); } else { ret = qemuMigrationSrcPerformPeer2Peer2(driver, sconn, dconn, vm, - dconnuri, flags, dname, resource); + dconnuri, flags, dname, resource, + migParams); } cleanup: diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h index fc81eb5016..2bf710a919 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -148,6 +148,7 @@ qemuMigrationDstPrepareTunnel(virQEMUDriverPtr driver, virStreamPtr st, virDomainDefPtr *def, const char *origname, + qemuMigrationParamsPtr migParams, unsigned long flags); int @@ -166,6 +167,7 @@ qemuMigrationDstPrepareDirect(virQEMUDriverPtr driver, const char **migrate_disks, int nbdPort, qemuMigrationCompressionPtr compression, + qemuMigrationParamsPtr migParams, unsigned long flags); int -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:25PM +0200, Jiri Denemark wrote:
Every migration entry point in qemu_driver is supposed to call qemuMigrationParamsFromFlags to transform flags and parameters into qemuMigrationParams structure and pass the result to qemuMigration* APIs.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_driver.c | 64 +++++++++++++++++++++++++++++++-------- src/qemu/qemu_migration.c | 23 ++++++-------- src/qemu/qemu_migration.h | 2 ++ 3 files changed, 62 insertions(+), 27 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

It is no longer used outside qemu_migration_params.c. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 2 +- src/qemu/qemu_migration_params.h | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index b55abc2e36..a0a00d0fc7 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -44,7 +44,7 @@ struct _qemuMigrationParams { }; -qemuMigrationParamsPtr +static qemuMigrationParamsPtr qemuMigrationParamsNew(void) { qemuMigrationParamsPtr params; diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index d66fdb7cde..4350b14d6d 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -56,9 +56,6 @@ typedef enum { } qemuMigrationParty; -qemuMigrationParamsPtr -qemuMigrationParamsNew(void); - qemuMigrationParamsPtr qemuMigrationParamsFromFlags(virTypedParameterPtr params, int nparams, -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:26PM +0200, Jiri Denemark wrote:
It is no longer used outside qemu_migration_params.c.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 2 +- src/qemu/qemu_migration_params.h | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

It's just a tiny wrapper around qemuMigrationParamsSetCapability and setting priv->job.postcopyEnabled is not something qemuMigrationParams code should be doing anyway so let the callers do it. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 16 ++++++++++++---- src/qemu/qemu_migration_params.c | 17 ----------------- src/qemu/qemu_migration_params.h | 5 ----- 3 files changed, 12 insertions(+), 26 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 5614f0d43e..400eb0710c 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2391,8 +2391,10 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, migParams) < 0) goto stopjob; - if (qemuMigrationParamsSetPostCopy(vm, flags & VIR_MIGRATE_POSTCOPY, - migParams) < 0) + if (qemuMigrationParamsSetCapability(vm, + QEMU_MONITOR_MIGRATION_CAPS_POSTCOPY, + flags & VIR_MIGRATE_POSTCOPY, + migParams) < 0) goto stopjob; if (qemuMigrationParamsCheck(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN, @@ -2416,6 +2418,8 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, migParams) < 0) goto stopjob; + priv->job.postcopyEnabled = flags & VIR_MIGRATE_POSTCOPY; + if (mig->nbd && flags & (VIR_MIGRATE_NON_SHARED_DISK | VIR_MIGRATE_NON_SHARED_INC) && virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NBD_SERVER)) { @@ -3349,8 +3353,10 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, migParams) < 0) goto error; - if (qemuMigrationParamsSetPostCopy(vm, flags & VIR_MIGRATE_POSTCOPY, - migParams) < 0) + if (qemuMigrationParamsSetCapability(vm, + QEMU_MONITOR_MIGRATION_CAPS_POSTCOPY, + flags & VIR_MIGRATE_POSTCOPY, + migParams) < 0) goto error; if (qemuMigrationCapsGet(vm, QEMU_MONITOR_MIGRATION_CAPS_PAUSE_BEFORE_SWITCHOVER) && @@ -3386,6 +3392,8 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, migParams) < 0) goto error; + priv->job.postcopyEnabled = flags & VIR_MIGRATE_POSTCOPY; + if (migrate_flags & (QEMU_MONITOR_MIGRATE_NON_SHARED_DISK | QEMU_MONITOR_MIGRATE_NON_SHARED_INC)) { if (mig->nbd) { diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index a0a00d0fc7..bf95fb4f59 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -199,23 +199,6 @@ qemuMigrationParamsSetCapability(virDomainObjPtr vm ATTRIBUTE_UNUSED, } -int -qemuMigrationParamsSetPostCopy(virDomainObjPtr vm, - bool state, - qemuMigrationParamsPtr migParams) -{ - qemuDomainObjPrivatePtr priv = vm->privateData; - - if (qemuMigrationParamsSetCapability(vm, - QEMU_MONITOR_MIGRATION_CAPS_POSTCOPY, - state, migParams) < 0) - return -1; - - priv->job.postcopyEnabled = state; - return 0; -} - - /* qemuMigrationParamsEnableTLS * @driver: pointer to qemu driver * @vm: domain object diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index 4350b14d6d..fac901e35c 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -77,11 +77,6 @@ qemuMigrationParamsSetCapability(virDomainObjPtr vm, bool state, qemuMigrationParamsPtr migParams); -int -qemuMigrationParamsSetPostCopy(virDomainObjPtr vm, - bool state, - qemuMigrationParamsPtr migParams); - int qemuMigrationParamsEnableTLS(virQEMUDriverPtr driver, virDomainObjPtr vm, -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:27PM +0200, Jiri Denemark wrote:
It's just a tiny wrapper around qemuMigrationParamsSetCapability and setting priv->job.postcopyEnabled is not something qemuMigrationParams code should be doing anyway so let the callers do it.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 16 ++++++++++++---- src/qemu/qemu_migration_params.c | 17 ----------------- src/qemu/qemu_migration_params.h | 5 ----- 3 files changed, 12 insertions(+), 26 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Some migration capabilities are always enabled if QEMU supports them. We can just drop the explicit code for them and let qemuMigrationParamsCheck automatically set such capabilities. QEMU_MONITOR_MIGRATION_CAPS_EVENTS would normally be one of the always on features, but it is the only feature we want to enable even for other jobs which internally use migration (such as save and snapshot). Hence this capability is set very early after libvirtd connects to QEMU monitor. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 6 ------ src/qemu/qemu_migration_params.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 400eb0710c..0446003f47 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -3359,12 +3359,6 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, migParams) < 0) goto error; - if (qemuMigrationCapsGet(vm, QEMU_MONITOR_MIGRATION_CAPS_PAUSE_BEFORE_SWITCHOVER) && - qemuMigrationParamsSetCapability(vm, - QEMU_MONITOR_MIGRATION_CAPS_PAUSE_BEFORE_SWITCHOVER, - true, migParams) < 0) - goto error; - if (qemuMigrationParamsCheck(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, migParams) < 0) goto error; diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index bf95fb4f59..03056eed09 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -43,6 +43,19 @@ struct _qemuMigrationParams { qemuMonitorMigrationParams params; }; +typedef struct _qemuMigrationParamsAlwaysOnItem qemuMigrationParamsAlwaysOnItem; +struct _qemuMigrationParamsAlwaysOnItem { + qemuMonitorMigrationCaps cap; + int party; /* bit-wise OR of qemuMigrationParty */ +}; + +/* Migration capabilities which should always be enabled as long as they + * are supported by QEMU. */ +static const qemuMigrationParamsAlwaysOnItem qemuMigrationParamsAlwaysOn[] = { + {QEMU_MONITOR_MIGRATION_CAPS_PAUSE_BEFORE_SWITCHOVER, + QEMU_MIGRATION_SOURCE}, +}; + static qemuMigrationParamsPtr qemuMigrationParamsNew(void) @@ -399,8 +412,15 @@ qemuMigrationParamsCheck(virQEMUDriverPtr driver, qemuDomainObjPrivatePtr priv = vm->privateData; qemuMigrationParamsPtr origParams = NULL; qemuMonitorMigrationCaps cap; + qemuMigrationParty party; + size_t i; int ret = -1; + if (asyncJob == QEMU_ASYNC_JOB_MIGRATION_OUT) + party = QEMU_MIGRATION_SOURCE; + else + party = QEMU_MIGRATION_DESTINATION; + for (cap = 0; cap < QEMU_MONITOR_MIGRATION_CAPS_LAST; cap++) { bool state = false; @@ -414,6 +434,17 @@ qemuMigrationParamsCheck(virQEMUDriverPtr driver, } } + for (i = 0; i < ARRAY_CARDINALITY(qemuMigrationParamsAlwaysOn); i++) { + cap = qemuMigrationParamsAlwaysOn[i].cap; + + if (qemuMigrationParamsAlwaysOn[i].party & party && + qemuMigrationCapsGet(vm, cap)) { + VIR_DEBUG("Enabling migration capability '%s'", + qemuMonitorMigrationCapsTypeToString(cap)); + ignore_value(virBitmapSetBit(migParams->caps, cap)); + } + } + if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) return -1; -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:28PM +0200, Jiri Denemark wrote:
Some migration capabilities are always enabled if QEMU supports them. We can just drop the explicit code for them and let qemuMigrationParamsCheck automatically set such capabilities.
QEMU_MONITOR_MIGRATION_CAPS_EVENTS would normally be one of the always on features, but it is the only feature we want to enable even for other jobs which internally use migration (such as save and snapshot). Hence this capability is set very early after libvirtd connects to QEMU monitor.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 6 ------ src/qemu/qemu_migration_params.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 6 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Most migration capabilities are directly connected with virDomainMigrateFlags so qemuMigrationParamsFromFlags can automatically enable them. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 30 --------------------- src/qemu/qemu_migration_params.c | 45 +++++++++++++++++++++++++++----- src/qemu/qemu_migration_params.h | 6 ----- 3 files changed, 39 insertions(+), 42 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 0446003f47..e1a29d9569 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2385,18 +2385,6 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, goto stopjob; } - if (qemuMigrationParamsSetCapability(vm, - QEMU_MONITOR_MIGRATION_CAPS_RDMA_PIN_ALL, - flags & VIR_MIGRATE_RDMA_PIN_ALL, - migParams) < 0) - goto stopjob; - - if (qemuMigrationParamsSetCapability(vm, - QEMU_MONITOR_MIGRATION_CAPS_POSTCOPY, - flags & VIR_MIGRATE_POSTCOPY, - migParams) < 0) - goto stopjob; - if (qemuMigrationParamsCheck(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN, migParams) < 0) goto stopjob; @@ -3341,24 +3329,6 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, if (qemuMigrationParamsSetCompression(vm, compression, migParams) < 0) goto error; - if (qemuMigrationParamsSetCapability(vm, - QEMU_MONITOR_MIGRATION_CAPS_AUTO_CONVERGE, - flags & VIR_MIGRATE_AUTO_CONVERGE, - migParams) < 0) - goto error; - - if (qemuMigrationParamsSetCapability(vm, - QEMU_MONITOR_MIGRATION_CAPS_RDMA_PIN_ALL, - flags & VIR_MIGRATE_RDMA_PIN_ALL, - migParams) < 0) - goto error; - - if (qemuMigrationParamsSetCapability(vm, - QEMU_MONITOR_MIGRATION_CAPS_POSTCOPY, - flags & VIR_MIGRATE_POSTCOPY, - migParams) < 0) - goto error; - if (qemuMigrationParamsCheck(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, migParams) < 0) goto error; diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 03056eed09..369e560990 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -49,6 +49,13 @@ struct _qemuMigrationParamsAlwaysOnItem { int party; /* bit-wise OR of qemuMigrationParty */ }; +typedef struct _qemuMigrationParamsFlagMapItem qemuMigrationParamsFlagMapItem; +struct _qemuMigrationParamsFlagMapItem { + virDomainMigrateFlags flag; + qemuMonitorMigrationCaps cap; + int party; /* bit-wise OR of qemuMigrationParty */ +}; + /* Migration capabilities which should always be enabled as long as they * are supported by QEMU. */ static const qemuMigrationParamsAlwaysOnItem qemuMigrationParamsAlwaysOn[] = { @@ -56,6 +63,21 @@ static const qemuMigrationParamsAlwaysOnItem qemuMigrationParamsAlwaysOn[] = { QEMU_MIGRATION_SOURCE}, }; +/* Translation from virDomainMigrateFlags to qemuMonitorMigrationCaps. */ +static const qemuMigrationParamsFlagMapItem qemuMigrationParamsFlagMap[] = { + {VIR_MIGRATE_RDMA_PIN_ALL, + QEMU_MONITOR_MIGRATION_CAPS_RDMA_PIN_ALL, + QEMU_MIGRATION_SOURCE | QEMU_MIGRATION_DESTINATION}, + + {VIR_MIGRATE_AUTO_CONVERGE, + QEMU_MONITOR_MIGRATION_CAPS_AUTO_CONVERGE, + QEMU_MIGRATION_SOURCE}, + + {VIR_MIGRATE_POSTCOPY, + QEMU_MONITOR_MIGRATION_CAPS_POSTCOPY, + QEMU_MIGRATION_SOURCE | QEMU_MIGRATION_DESTINATION}, +}; + static qemuMigrationParamsPtr qemuMigrationParamsNew(void) @@ -97,12 +119,21 @@ qemuMigrationParamsFromFlags(virTypedParameterPtr params, qemuMigrationParty party) { qemuMigrationParamsPtr migParams; + size_t i; if (!(migParams = qemuMigrationParamsNew())) return NULL; - if (!params) - return migParams; + for (i = 0; i < ARRAY_CARDINALITY(qemuMigrationParamsFlagMap); i++) { + qemuMonitorMigrationCaps cap = qemuMigrationParamsFlagMap[i].cap; + + if (qemuMigrationParamsFlagMap[i].party & party && + flags & qemuMigrationParamsFlagMap[i].flag) { + VIR_DEBUG("Enabling migration capability '%s'", + qemuMonitorMigrationCapsTypeToString(cap)); + ignore_value(virBitmapSetBit(migParams->caps, cap)); + } + } #define GET(PARAM, VAR) \ do { \ @@ -116,9 +147,11 @@ qemuMigrationParamsFromFlags(virTypedParameterPtr params, migParams->params.VAR ## _set = true; \ } while (0) - if (party == QEMU_MIGRATION_SOURCE) { - GET(AUTO_CONVERGE_INITIAL, cpuThrottleInitial); - GET(AUTO_CONVERGE_INCREMENT, cpuThrottleIncrement); + if (params) { + if (party == QEMU_MIGRATION_SOURCE) { + GET(AUTO_CONVERGE_INITIAL, cpuThrottleInitial); + GET(AUTO_CONVERGE_INCREMENT, cpuThrottleIncrement); + } } #undef GET @@ -197,7 +230,7 @@ qemuMigrationParamsApply(virQEMUDriverPtr driver, } -int +static int qemuMigrationParamsSetCapability(virDomainObjPtr vm ATTRIBUTE_UNUSED, qemuMonitorMigrationCaps capability, bool state, diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index fac901e35c..494ac104ad 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -71,12 +71,6 @@ qemuMigrationParamsApply(virQEMUDriverPtr driver, int asyncJob, qemuMigrationParamsPtr migParams); -int -qemuMigrationParamsSetCapability(virDomainObjPtr vm, - qemuMonitorMigrationCaps capability, - bool state, - qemuMigrationParamsPtr migParams); - int qemuMigrationParamsEnableTLS(virQEMUDriverPtr driver, virDomainObjPtr vm, -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:29PM +0200, Jiri Denemark wrote:
Most migration capabilities are directly connected with virDomainMigrateFlags so qemuMigrationParamsFromFlags can automatically enable them.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 30 --------------------- src/qemu/qemu_migration_params.c | 45 +++++++++++++++++++++++++++----- src/qemu/qemu_migration_params.h | 6 ----- 3 files changed, 39 insertions(+), 42 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Propagate the calls up the stack to the point where qemuMigrationParamsFromFlags is called. The end goal achieved in the following few patches is to merge compression parameters into the general migration parameters code. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_driver.c | 21 ++++++++++++++++++--- src/qemu/qemu_migration.c | 25 +++++++------------------ src/qemu/qemu_migration.h | 1 + 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 5271e01d92..85755257aa 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -12126,6 +12126,7 @@ qemuDomainMigratePrepareTunnel(virConnectPtr dconn, virQEMUDriverPtr driver = dconn->privateData; virDomainDefPtr def = NULL; char *origname = NULL; + qemuMigrationCompressionPtr compression = NULL; qemuMigrationParamsPtr migParams = NULL; int ret = -1; @@ -12137,6 +12138,9 @@ qemuDomainMigratePrepareTunnel(virConnectPtr dconn, goto cleanup; } + if (!(compression = qemuMigrationAnyCompressionParse(NULL, 0, flags))) + goto cleanup; + if (!(migParams = qemuMigrationParamsFromFlags(NULL, 0, flags, QEMU_MIGRATION_DESTINATION))) goto cleanup; @@ -12156,9 +12160,10 @@ qemuDomainMigratePrepareTunnel(virConnectPtr dconn, ret = qemuMigrationDstPrepareTunnel(driver, dconn, NULL, 0, NULL, NULL, /* No cookies in v2 */ - st, &def, origname, migParams, flags); + st, &def, origname, compression, migParams, flags); cleanup: + VIR_FREE(compression); qemuMigrationParamsFree(migParams); VIR_FREE(origname); virDomainDefFree(def); @@ -12597,6 +12602,7 @@ qemuDomainMigratePrepareTunnel3(virConnectPtr dconn, virQEMUDriverPtr driver = dconn->privateData; virDomainDefPtr def = NULL; char *origname = NULL; + qemuMigrationCompressionPtr compression = NULL; qemuMigrationParamsPtr migParams = NULL; int ret = -1; @@ -12608,6 +12614,9 @@ qemuDomainMigratePrepareTunnel3(virConnectPtr dconn, goto cleanup; } + if (!(compression = qemuMigrationAnyCompressionParse(NULL, 0, flags))) + goto cleanup; + if (!(migParams = qemuMigrationParamsFromFlags(NULL, 0, flags, QEMU_MIGRATION_DESTINATION))) goto cleanup; @@ -12621,9 +12630,10 @@ qemuDomainMigratePrepareTunnel3(virConnectPtr dconn, ret = qemuMigrationDstPrepareTunnel(driver, dconn, cookiein, cookieinlen, cookieout, cookieoutlen, - st, &def, origname, migParams, flags); + st, &def, origname, compression, migParams, flags); cleanup: + VIR_FREE(compression); qemuMigrationParamsFree(migParams); VIR_FREE(origname); virDomainDefFree(def); @@ -12646,6 +12656,7 @@ qemuDomainMigratePrepareTunnel3Params(virConnectPtr dconn, const char *dom_xml = NULL; const char *dname = NULL; char *origname = NULL; + qemuMigrationCompressionPtr compression = NULL; qemuMigrationParamsPtr migParams = NULL; int ret = -1; @@ -12667,6 +12678,9 @@ qemuDomainMigratePrepareTunnel3Params(virConnectPtr dconn, goto cleanup; } + if (!(compression = qemuMigrationAnyCompressionParse(NULL, 0, flags))) + goto cleanup; + if (!(migParams = qemuMigrationParamsFromFlags(params, nparams, flags, QEMU_MIGRATION_DESTINATION))) goto cleanup; @@ -12680,9 +12694,10 @@ qemuDomainMigratePrepareTunnel3Params(virConnectPtr dconn, ret = qemuMigrationDstPrepareTunnel(driver, dconn, cookiein, cookieinlen, cookieout, cookieoutlen, - st, &def, origname, migParams, flags); + st, &def, origname, compression, migParams, flags); cleanup: + VIR_FREE(compression); qemuMigrationParamsFree(migParams); VIR_FREE(origname); virDomainDefFree(def); diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index e1a29d9569..d4c5994f25 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2531,12 +2531,10 @@ qemuMigrationDstPrepareTunnel(virQEMUDriverPtr driver, virStreamPtr st, virDomainDefPtr *def, const char *origname, + qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams, unsigned long flags) { - qemuMigrationCompressionPtr compression = NULL; - int ret; - VIR_DEBUG("driver=%p, dconn=%p, cookiein=%s, cookieinlen=%d, " "cookieout=%p, cookieoutlen=%p, st=%p, def=%p, " "origname=%s, flags=0x%lx", @@ -2549,15 +2547,10 @@ qemuMigrationDstPrepareTunnel(virQEMUDriverPtr driver, return -1; } - if (!(compression = qemuMigrationAnyCompressionParse(NULL, 0, flags))) - return -1; - - ret = qemuMigrationDstPrepareAny(driver, dconn, cookiein, cookieinlen, - cookieout, cookieoutlen, def, origname, - st, NULL, 0, false, NULL, 0, NULL, 0, - compression, migParams, flags); - VIR_FREE(compression); - return ret; + return qemuMigrationDstPrepareAny(driver, dconn, cookiein, cookieinlen, + cookieout, cookieoutlen, def, origname, + st, NULL, 0, false, NULL, 0, NULL, 0, + compression, migParams, flags); } @@ -3759,6 +3752,7 @@ qemuMigrationSrcPerformPeer2Peer2(virQEMUDriverPtr driver, unsigned long flags, const char *dname, unsigned long resource, + qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams) { virDomainPtr ddomain = NULL; @@ -3770,7 +3764,6 @@ qemuMigrationSrcPerformPeer2Peer2(virQEMUDriverPtr driver, bool cancelled; virStreamPtr st = NULL; unsigned long destflags; - qemuMigrationCompressionPtr compression = NULL; VIR_DEBUG("driver=%p, sconn=%p, dconn=%p, vm=%p, dconnuri=%s, " "flags=0x%lx, dname=%s, resource=%lu", @@ -3792,9 +3785,6 @@ qemuMigrationSrcPerformPeer2Peer2(virQEMUDriverPtr driver, destflags = flags & ~(VIR_MIGRATE_ABORT_ON_ERROR | VIR_MIGRATE_AUTO_CONVERGE); - if (!(compression = qemuMigrationAnyCompressionParse(NULL, 0, flags))) - goto cleanup; - VIR_DEBUG("Prepare2 %p", dconn); if (flags & VIR_MIGRATE_TUNNELLED) { /* @@ -3895,7 +3885,6 @@ qemuMigrationSrcPerformPeer2Peer2(virQEMUDriverPtr driver, } VIR_FREE(uri_out); VIR_FREE(cookie); - VIR_FREE(compression); return ret; } @@ -4409,7 +4398,7 @@ qemuMigrationSrcPerformPeer2Peer(virQEMUDriverPtr driver, } else { ret = qemuMigrationSrcPerformPeer2Peer2(driver, sconn, dconn, vm, dconnuri, flags, dname, resource, - migParams); + compression, migParams); } cleanup: diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h index 2bf710a919..3cd456568a 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -148,6 +148,7 @@ qemuMigrationDstPrepareTunnel(virQEMUDriverPtr driver, virStreamPtr st, virDomainDefPtr *def, const char *origname, + qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams, unsigned long flags); -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:30PM +0200, Jiri Denemark wrote:
Propagate the calls up the stack to the point where qemuMigrationParamsFromFlags is called. The end goal achieved in the following few patches is to merge compression parameters into the general migration parameters code.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_driver.c | 21 ++++++++++++++++++--- src/qemu/qemu_migration.c | 25 +++++++------------------ src/qemu/qemu_migration.h | 1 + 3 files changed, 26 insertions(+), 21 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

So far it's used only for CPU throttling parameters which are all ints, but we'll soon want to use it for more parameters with different types. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 369e560990..e0cbdb1a38 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -112,6 +112,17 @@ qemuMigrationParamsFree(qemuMigrationParamsPtr migParams) } +#define GET(API, PARAM, VAR) \ + do { \ + int rc; \ + if ((rc = API(params, nparams, VIR_MIGRATE_PARAM_ ## PARAM, \ + &migParams->params.VAR)) < 0) \ + goto error; \ + \ + if (rc == 1) \ + migParams->params.VAR ## _set = true; \ + } while (0) + qemuMigrationParamsPtr qemuMigrationParamsFromFlags(virTypedParameterPtr params, int nparams, @@ -135,27 +146,13 @@ qemuMigrationParamsFromFlags(virTypedParameterPtr params, } } -#define GET(PARAM, VAR) \ - do { \ - int rc; \ - if ((rc = virTypedParamsGetInt(params, nparams, \ - VIR_MIGRATE_PARAM_ ## PARAM, \ - &migParams->params.VAR)) < 0) \ - goto error; \ - \ - if (rc == 1) \ - migParams->params.VAR ## _set = true; \ - } while (0) - if (params) { if (party == QEMU_MIGRATION_SOURCE) { - GET(AUTO_CONVERGE_INITIAL, cpuThrottleInitial); - GET(AUTO_CONVERGE_INCREMENT, cpuThrottleIncrement); + GET(virTypedParamsGetInt, AUTO_CONVERGE_INITIAL, cpuThrottleInitial); + GET(virTypedParamsGetInt, AUTO_CONVERGE_INCREMENT, cpuThrottleIncrement); } } -#undef GET - if ((migParams->params.cpuThrottleInitial_set || migParams->params.cpuThrottleIncrement_set) && !(flags & VIR_MIGRATE_AUTO_CONVERGE)) { @@ -171,6 +168,8 @@ qemuMigrationParamsFromFlags(virTypedParameterPtr params, return NULL; } +#undef GET + /** * qemuMigrationParamsApply -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:31PM +0200, Jiri Denemark wrote:
So far it's used only for CPU throttling parameters which are all ints, but we'll soon want to use it for more parameters with different types.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-)
diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 369e560990..e0cbdb1a38 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -112,6 +112,17 @@ qemuMigrationParamsFree(qemuMigrationParamsPtr migParams) }
+#define GET(API, PARAM, VAR) \ + do { \ + int rc; \ + if ((rc = API(params, nparams, VIR_MIGRATE_PARAM_ ## PARAM, \ + &migParams->params.VAR)) < 0) \ + goto error; \ + \ + if (rc == 1) \ + migParams->params.VAR ## _set = true; \ + } while (0) + qemuMigrationParamsPtr qemuMigrationParamsFromFlags(virTypedParameterPtr params, int nparams, @@ -135,27 +146,13 @@ qemuMigrationParamsFromFlags(virTypedParameterPtr params, } }
-#define GET(PARAM, VAR) \ - do { \ - int rc; \ - if ((rc = virTypedParamsGetInt(params, nparams, \ - VIR_MIGRATE_PARAM_ ## PARAM, \ - &migParams->params.VAR)) < 0) \ - goto error; \ - \ - if (rc == 1) \ - migParams->params.VAR ## _set = true; \ - } while (0) - if (params) { if (party == QEMU_MIGRATION_SOURCE) { - GET(AUTO_CONVERGE_INITIAL, cpuThrottleInitial); - GET(AUTO_CONVERGE_INCREMENT, cpuThrottleIncrement); + GET(virTypedParamsGetInt, AUTO_CONVERGE_INITIAL, cpuThrottleInitial); + GET(virTypedParamsGetInt, AUTO_CONVERGE_INCREMENT, cpuThrottleIncrement);
If all the getter APIs start with virTypedParamsGet, you can hide the prefix inside the macro definition to save columns. Regardless: Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

On Fri, Apr 13, 2018 at 16:22:00 +0200, Ján Tomko wrote:
On Wed, Apr 11, 2018 at 04:41:31PM +0200, Jiri Denemark wrote:
So far it's used only for CPU throttling parameters which are all ints, but we'll soon want to use it for more parameters with different types.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-)
diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 369e560990..e0cbdb1a38 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -112,6 +112,17 @@ qemuMigrationParamsFree(qemuMigrationParamsPtr migParams) }
+#define GET(API, PARAM, VAR) \ + do { \ + int rc; \ + if ((rc = API(params, nparams, VIR_MIGRATE_PARAM_ ## PARAM, \ + &migParams->params.VAR)) < 0) \ + goto error; \ + \ + if (rc == 1) \ + migParams->params.VAR ## _set = true; \ + } while (0) + qemuMigrationParamsPtr qemuMigrationParamsFromFlags(virTypedParameterPtr params, int nparams, @@ -135,27 +146,13 @@ qemuMigrationParamsFromFlags(virTypedParameterPtr params, } }
-#define GET(PARAM, VAR) \ - do { \ - int rc; \ - if ((rc = virTypedParamsGetInt(params, nparams, \ - VIR_MIGRATE_PARAM_ ## PARAM, \ - &migParams->params.VAR)) < 0) \ - goto error; \ - \ - if (rc == 1) \ - migParams->params.VAR ## _set = true; \ - } while (0) - if (params) { if (party == QEMU_MIGRATION_SOURCE) { - GET(AUTO_CONVERGE_INITIAL, cpuThrottleInitial); - GET(AUTO_CONVERGE_INCREMENT, cpuThrottleIncrement); + GET(virTypedParamsGetInt, AUTO_CONVERGE_INITIAL, cpuThrottleInitial); + GET(virTypedParamsGetInt, AUTO_CONVERGE_INCREMENT, cpuThrottleIncrement);
If all the getter APIs start with virTypedParamsGet, you can hide the prefix inside the macro definition to save columns.
The macro will go away completely later in this series anyway. Jirka

It's become only a tiny wrapper around virBitmapSetBit, which can easily be called directly. We don't need to call virBitmapClearBit since migParams->caps bitmap is initialized with zeros. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 35 +++++++------------------------- 1 file changed, 7 insertions(+), 28 deletions(-) diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index e0cbdb1a38..262825972c 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -229,21 +229,6 @@ qemuMigrationParamsApply(virQEMUDriverPtr driver, } -static int -qemuMigrationParamsSetCapability(virDomainObjPtr vm ATTRIBUTE_UNUSED, - qemuMonitorMigrationCaps capability, - bool state, - qemuMigrationParamsPtr migParams) -{ - if (state) - ignore_value(virBitmapSetBit(migParams->caps, capability)); - else - ignore_value(virBitmapClearBit(migParams->caps, capability)); - - return 0; -} - - /* qemuMigrationParamsEnableTLS * @driver: pointer to qemu driver * @vm: domain object @@ -358,23 +343,17 @@ qemuMigrationParamsDisableTLS(virDomainObjPtr vm, int -qemuMigrationParamsSetCompression(virDomainObjPtr vm, +qemuMigrationParamsSetCompression(virDomainObjPtr vm ATTRIBUTE_UNUSED, qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams) { - if (qemuMigrationParamsSetCapability(vm, - QEMU_MONITOR_MIGRATION_CAPS_XBZRLE, - compression->methods & - (1ULL << QEMU_MIGRATION_COMPRESS_XBZRLE), - migParams) < 0) - return -1; + if (compression->methods & (1ULL << QEMU_MIGRATION_COMPRESS_XBZRLE)) + ignore_value(virBitmapSetBit(migParams->caps, + QEMU_MONITOR_MIGRATION_CAPS_XBZRLE)); - if (qemuMigrationParamsSetCapability(vm, - QEMU_MONITOR_MIGRATION_CAPS_COMPRESS, - compression->methods & - (1ULL << QEMU_MIGRATION_COMPRESS_MT), - migParams) < 0) - return -1; + if (compression->methods & (1ULL << QEMU_MIGRATION_COMPRESS_MT)) + ignore_value(virBitmapSetBit(migParams->caps, + QEMU_MONITOR_MIGRATION_CAPS_COMPRESS)); migParams->params.compressLevel_set = compression->level_set; migParams->params.compressLevel = compression->level; -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:32PM +0200, Jiri Denemark wrote:
It's become only a tiny wrapper around virBitmapSetBit, which can easily be called directly. We don't need to call virBitmapClearBit since migParams->caps bitmap is initialized with zeros.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 35 +++++++------------------------- 1 file changed, 7 insertions(+), 28 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

The API will soon be called from qemuMigrationParamsFromFlags. Let's move it to avoid the need to add a forward declaration. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 59 ++++++++++++++++---------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 262825972c..b532299a5f 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -123,6 +123,36 @@ qemuMigrationParamsFree(qemuMigrationParamsPtr migParams) migParams->params.VAR ## _set = true; \ } while (0) + +int +qemuMigrationParamsSetCompression(virDomainObjPtr vm ATTRIBUTE_UNUSED, + qemuMigrationCompressionPtr compression, + qemuMigrationParamsPtr migParams) +{ + if (compression->methods & (1ULL << QEMU_MIGRATION_COMPRESS_XBZRLE)) + ignore_value(virBitmapSetBit(migParams->caps, + QEMU_MONITOR_MIGRATION_CAPS_XBZRLE)); + + if (compression->methods & (1ULL << QEMU_MIGRATION_COMPRESS_MT)) + ignore_value(virBitmapSetBit(migParams->caps, + QEMU_MONITOR_MIGRATION_CAPS_COMPRESS)); + + migParams->params.compressLevel_set = compression->level_set; + migParams->params.compressLevel = compression->level; + + migParams->params.compressThreads_set = compression->threads_set; + migParams->params.compressThreads = compression->threads; + + migParams->params.decompressThreads_set = compression->dthreads_set; + migParams->params.decompressThreads = compression->dthreads; + + migParams->params.xbzrleCacheSize_set = compression->xbzrle_cache_set; + migParams->params.xbzrleCacheSize = compression->xbzrle_cache; + + return 0; +} + + qemuMigrationParamsPtr qemuMigrationParamsFromFlags(virTypedParameterPtr params, int nparams, @@ -342,35 +372,6 @@ qemuMigrationParamsDisableTLS(virDomainObjPtr vm, } -int -qemuMigrationParamsSetCompression(virDomainObjPtr vm ATTRIBUTE_UNUSED, - qemuMigrationCompressionPtr compression, - qemuMigrationParamsPtr migParams) -{ - if (compression->methods & (1ULL << QEMU_MIGRATION_COMPRESS_XBZRLE)) - ignore_value(virBitmapSetBit(migParams->caps, - QEMU_MONITOR_MIGRATION_CAPS_XBZRLE)); - - if (compression->methods & (1ULL << QEMU_MIGRATION_COMPRESS_MT)) - ignore_value(virBitmapSetBit(migParams->caps, - QEMU_MONITOR_MIGRATION_CAPS_COMPRESS)); - - migParams->params.compressLevel_set = compression->level_set; - migParams->params.compressLevel = compression->level; - - migParams->params.compressThreads_set = compression->threads_set; - migParams->params.compressThreads = compression->threads; - - migParams->params.decompressThreads_set = compression->dthreads_set; - migParams->params.decompressThreads = compression->dthreads; - - migParams->params.xbzrleCacheSize_set = compression->xbzrle_cache_set; - migParams->params.xbzrleCacheSize = compression->xbzrle_cache; - - return 0; -} - - /* qemuMigrationParamsResetTLS * @driver: pointer to qemu driver * @vm: domain object -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:33PM +0200, Jiri Denemark wrote:
The API will soon be called from qemuMigrationParamsFromFlags. Let's move it to avoid the need to add a forward declaration.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 59 ++++++++++++++++---------------- 1 file changed, 30 insertions(+), 29 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

The code really belongs to qemu_migration_params.c. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 140 ----------------------------- src/qemu/qemu_migration.h | 19 ---- src/qemu/qemu_migration_params.c | 147 +++++++++++++++++++++++++++++++ src/qemu/qemu_migration_params.h | 11 +++ 4 files changed, 158 insertions(+), 159 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index d4c5994f25..d0d0d97be4 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -77,11 +77,6 @@ VIR_ENUM_IMPL(qemuMigrationJobPhase, QEMU_MIGRATION_PHASE_LAST, "finish3", ); -VIR_ENUM_IMPL(qemuMigrationCompressMethod, QEMU_MIGRATION_COMPRESS_LAST, - "xbzrle", - "mt", -); - static int qemuMigrationJobStart(virQEMUDriverPtr driver, virDomainObjPtr vm, @@ -5439,141 +5434,6 @@ qemuMigrationDstErrorReport(virQEMUDriverPtr driver, } -/* don't ever pass NULL params with non zero nparams */ -qemuMigrationCompressionPtr -qemuMigrationAnyCompressionParse(virTypedParameterPtr params, - int nparams, - unsigned long flags) -{ - size_t i; - qemuMigrationCompressionPtr compression = NULL; - - if (VIR_ALLOC(compression) < 0) - return NULL; - - for (i = 0; i < nparams; i++) { - int method; - - if (STRNEQ(params[i].field, VIR_MIGRATE_PARAM_COMPRESSION)) - continue; - - method = qemuMigrationCompressMethodTypeFromString(params[i].value.s); - if (method < 0) { - virReportError(VIR_ERR_INVALID_ARG, - _("Unsupported compression method '%s'"), - params[i].value.s); - goto error; - } - - if (compression->methods & (1ULL << method)) { - virReportError(VIR_ERR_INVALID_ARG, - _("Compression method '%s' is specified twice"), - params[i].value.s); - goto error; - } - - compression->methods |= 1ULL << method; - } - -#define GET_PARAM(PARAM, TYPE, VALUE) \ - do { \ - int rc; \ - const char *par = VIR_MIGRATE_PARAM_COMPRESSION_ ## PARAM; \ - \ - if ((rc = virTypedParamsGet ## TYPE(params, nparams, \ - par, &compression->VALUE)) < 0) \ - goto error; \ - \ - if (rc == 1) \ - compression->VALUE ## _set = true; \ - } while (0) - - if (params) { - GET_PARAM(MT_LEVEL, Int, level); - GET_PARAM(MT_THREADS, Int, threads); - GET_PARAM(MT_DTHREADS, Int, dthreads); - GET_PARAM(XBZRLE_CACHE, ULLong, xbzrle_cache); - } - -#undef GET_PARAM - - if ((compression->level_set || - compression->threads_set || - compression->dthreads_set) && - !(compression->methods & (1ULL << QEMU_MIGRATION_COMPRESS_MT))) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("Turn multithread compression on to tune it")); - goto error; - } - - if (compression->xbzrle_cache_set && - !(compression->methods & (1ULL << QEMU_MIGRATION_COMPRESS_XBZRLE))) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("Turn xbzrle compression on to tune it")); - goto error; - } - - if (!compression->methods && (flags & VIR_MIGRATE_COMPRESSED)) - compression->methods = 1ULL << QEMU_MIGRATION_COMPRESS_XBZRLE; - - return compression; - - error: - VIR_FREE(compression); - return NULL; -} - -int -qemuMigrationAnyCompressionDump(qemuMigrationCompressionPtr compression, - virTypedParameterPtr *params, - int *nparams, - int *maxparams, - unsigned long *flags) -{ - size_t i; - - if (compression->methods == 1ULL << QEMU_MIGRATION_COMPRESS_XBZRLE && - !compression->xbzrle_cache_set) { - *flags |= VIR_MIGRATE_COMPRESSED; - return 0; - } - - for (i = 0; i < QEMU_MIGRATION_COMPRESS_LAST; ++i) { - if ((compression->methods & (1ULL << i)) && - virTypedParamsAddString(params, nparams, maxparams, - VIR_MIGRATE_PARAM_COMPRESSION, - qemuMigrationCompressMethodTypeToString(i)) < 0) - return -1; - } - - if (compression->level_set && - virTypedParamsAddInt(params, nparams, maxparams, - VIR_MIGRATE_PARAM_COMPRESSION_MT_LEVEL, - compression->level) < 0) - return -1; - - if (compression->threads_set && - virTypedParamsAddInt(params, nparams, maxparams, - VIR_MIGRATE_PARAM_COMPRESSION_MT_THREADS, - compression->threads) < 0) - return -1; - - if (compression->dthreads_set && - virTypedParamsAddInt(params, nparams, maxparams, - VIR_MIGRATE_PARAM_COMPRESSION_MT_DTHREADS, - compression->dthreads) < 0) - return -1; - - if (compression->xbzrle_cache_set && - virTypedParamsAddULLong(params, nparams, maxparams, - VIR_MIGRATE_PARAM_COMPRESSION_XBZRLE_CACHE, - compression->xbzrle_cache) < 0) - return -1; - - return 0; -} - - int qemuMigrationSrcFetchMirrorStats(virQEMUDriverPtr driver, virDomainObjPtr vm, diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h index 3cd456568a..53d8c529fc 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -98,25 +98,6 @@ typedef enum { } qemuMigrationJobPhase; VIR_ENUM_DECL(qemuMigrationJobPhase) -typedef enum { - QEMU_MIGRATION_COMPRESS_XBZRLE = 0, - QEMU_MIGRATION_COMPRESS_MT, - - QEMU_MIGRATION_COMPRESS_LAST -} qemuMigrationCompressMethod; -VIR_ENUM_DECL(qemuMigrationCompressMethod) - -qemuMigrationCompressionPtr -qemuMigrationAnyCompressionParse(virTypedParameterPtr params, - int nparams, - unsigned long flags); -int -qemuMigrationAnyCompressionDump(qemuMigrationCompressionPtr compression, - virTypedParameterPtr *params, - int *nparams, - int *maxparams, - unsigned long *flags); - int qemuMigrationSrcSetOffline(virQEMUDriverPtr driver, virDomainObjPtr vm); diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index b532299a5f..94eb08a6bb 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -43,6 +43,19 @@ struct _qemuMigrationParams { qemuMonitorMigrationParams params; }; +typedef enum { + QEMU_MIGRATION_COMPRESS_XBZRLE = 0, + QEMU_MIGRATION_COMPRESS_MT, + + QEMU_MIGRATION_COMPRESS_LAST +} qemuMigrationCompressMethod; +VIR_ENUM_DECL(qemuMigrationCompressMethod) +VIR_ENUM_IMPL(qemuMigrationCompressMethod, QEMU_MIGRATION_COMPRESS_LAST, + "xbzrle", + "mt", +); + + typedef struct _qemuMigrationParamsAlwaysOnItem qemuMigrationParamsAlwaysOnItem; struct _qemuMigrationParamsAlwaysOnItem { qemuMonitorMigrationCaps cap; @@ -201,6 +214,140 @@ qemuMigrationParamsFromFlags(virTypedParameterPtr params, #undef GET +qemuMigrationCompressionPtr +qemuMigrationAnyCompressionParse(virTypedParameterPtr params, + int nparams, + unsigned long flags) +{ + size_t i; + qemuMigrationCompressionPtr compression = NULL; + + if (VIR_ALLOC(compression) < 0) + return NULL; + + for (i = 0; i < nparams; i++) { + int method; + + if (STRNEQ(params[i].field, VIR_MIGRATE_PARAM_COMPRESSION)) + continue; + + method = qemuMigrationCompressMethodTypeFromString(params[i].value.s); + if (method < 0) { + virReportError(VIR_ERR_INVALID_ARG, + _("Unsupported compression method '%s'"), + params[i].value.s); + goto error; + } + + if (compression->methods & (1ULL << method)) { + virReportError(VIR_ERR_INVALID_ARG, + _("Compression method '%s' is specified twice"), + params[i].value.s); + goto error; + } + + compression->methods |= 1ULL << method; + } + +#define GET_PARAM(PARAM, TYPE, VALUE) \ + do { \ + int rc; \ + const char *par = VIR_MIGRATE_PARAM_COMPRESSION_ ## PARAM; \ + \ + if ((rc = virTypedParamsGet ## TYPE(params, nparams, \ + par, &compression->VALUE)) < 0) \ + goto error; \ + \ + if (rc == 1) \ + compression->VALUE ## _set = true; \ + } while (0) + + if (params) { + GET_PARAM(MT_LEVEL, Int, level); + GET_PARAM(MT_THREADS, Int, threads); + GET_PARAM(MT_DTHREADS, Int, dthreads); + GET_PARAM(XBZRLE_CACHE, ULLong, xbzrle_cache); + } + +#undef GET_PARAM + + if ((compression->level_set || + compression->threads_set || + compression->dthreads_set) && + !(compression->methods & (1ULL << QEMU_MIGRATION_COMPRESS_MT))) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("Turn multithread compression on to tune it")); + goto error; + } + + if (compression->xbzrle_cache_set && + !(compression->methods & (1ULL << QEMU_MIGRATION_COMPRESS_XBZRLE))) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("Turn xbzrle compression on to tune it")); + goto error; + } + + if (!compression->methods && (flags & VIR_MIGRATE_COMPRESSED)) + compression->methods = 1ULL << QEMU_MIGRATION_COMPRESS_XBZRLE; + + return compression; + + error: + VIR_FREE(compression); + return NULL; +} + +int +qemuMigrationAnyCompressionDump(qemuMigrationCompressionPtr compression, + virTypedParameterPtr *params, + int *nparams, + int *maxparams, + unsigned long *flags) +{ + size_t i; + + if (compression->methods == 1ULL << QEMU_MIGRATION_COMPRESS_XBZRLE && + !compression->xbzrle_cache_set) { + *flags |= VIR_MIGRATE_COMPRESSED; + return 0; + } + + for (i = 0; i < QEMU_MIGRATION_COMPRESS_LAST; ++i) { + if ((compression->methods & (1ULL << i)) && + virTypedParamsAddString(params, nparams, maxparams, + VIR_MIGRATE_PARAM_COMPRESSION, + qemuMigrationCompressMethodTypeToString(i)) < 0) + return -1; + } + + if (compression->level_set && + virTypedParamsAddInt(params, nparams, maxparams, + VIR_MIGRATE_PARAM_COMPRESSION_MT_LEVEL, + compression->level) < 0) + return -1; + + if (compression->threads_set && + virTypedParamsAddInt(params, nparams, maxparams, + VIR_MIGRATE_PARAM_COMPRESSION_MT_THREADS, + compression->threads) < 0) + return -1; + + if (compression->dthreads_set && + virTypedParamsAddInt(params, nparams, maxparams, + VIR_MIGRATE_PARAM_COMPRESSION_MT_DTHREADS, + compression->dthreads) < 0) + return -1; + + if (compression->xbzrle_cache_set && + virTypedParamsAddULLong(params, nparams, maxparams, + VIR_MIGRATE_PARAM_COMPRESSION_XBZRLE_CACHE, + compression->xbzrle_cache) < 0) + return -1; + + return 0; +} + + /** * qemuMigrationParamsApply * @driver: qemu driver diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index 494ac104ad..165e1267ab 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -62,6 +62,17 @@ qemuMigrationParamsFromFlags(virTypedParameterPtr params, unsigned long flags, qemuMigrationParty party); +qemuMigrationCompressionPtr +qemuMigrationAnyCompressionParse(virTypedParameterPtr params, + int nparams, + unsigned long flags); +int +qemuMigrationAnyCompressionDump(qemuMigrationCompressionPtr compression, + virTypedParameterPtr *params, + int *nparams, + int *maxparams, + unsigned long *flags); + void qemuMigrationParamsFree(qemuMigrationParamsPtr migParams); -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:34PM +0200, Jiri Denemark wrote:
The code really belongs to qemu_migration_params.c.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 140 ----------------------------- src/qemu/qemu_migration.h | 19 ---- src/qemu/qemu_migration_params.c | 147 +++++++++++++++++++++++++++++++ src/qemu/qemu_migration_params.h | 11 +++ 4 files changed, 158 insertions(+), 159 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

There's no need to call this API explicitly in the migration code. We can pass the compression parameters to qemuMigrationParamsFromFlags and it can internally call qemuMigrationParamsSetCompression to apply them to the qemuMigrationParams structure. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_driver.c | 30 ++++++++++++------------- src/qemu/qemu_migration.c | 38 ++++++++++---------------------- src/qemu/qemu_migration.h | 2 -- src/qemu/qemu_migration_params.c | 11 +++++---- src/qemu/qemu_migration_params.h | 8 ++----- 5 files changed, 36 insertions(+), 53 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 85755257aa..3b0c3a3ffb 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -12142,7 +12142,7 @@ qemuDomainMigratePrepareTunnel(virConnectPtr dconn, goto cleanup; if (!(migParams = qemuMigrationParamsFromFlags(NULL, 0, flags, - QEMU_MIGRATION_DESTINATION))) + QEMU_MIGRATION_DESTINATION, compression))) goto cleanup; if (virLockManagerPluginUsesState(driver->lockManager)) { @@ -12160,7 +12160,7 @@ qemuDomainMigratePrepareTunnel(virConnectPtr dconn, ret = qemuMigrationDstPrepareTunnel(driver, dconn, NULL, 0, NULL, NULL, /* No cookies in v2 */ - st, &def, origname, compression, migParams, flags); + st, &def, origname, migParams, flags); cleanup: VIR_FREE(compression); @@ -12208,7 +12208,7 @@ qemuDomainMigratePrepare2(virConnectPtr dconn, goto cleanup; if (!(migParams = qemuMigrationParamsFromFlags(NULL, 0, flags, - QEMU_MIGRATION_DESTINATION))) + QEMU_MIGRATION_DESTINATION, compression))) goto cleanup; if (virLockManagerPluginUsesState(driver->lockManager)) { @@ -12232,7 +12232,7 @@ qemuDomainMigratePrepare2(virConnectPtr dconn, NULL, 0, NULL, NULL, /* No cookies */ uri_in, uri_out, &def, origname, NULL, 0, NULL, 0, - compression, migParams, flags); + migParams, flags); cleanup: qemuMigrationParamsFree(migParams); @@ -12273,7 +12273,7 @@ qemuDomainMigratePerform(virDomainPtr dom, goto cleanup; if (!(migParams = qemuMigrationParamsFromFlags(NULL, 0, flags, - QEMU_MIGRATION_SOURCE))) + QEMU_MIGRATION_SOURCE, compression))) goto cleanup; if (!(vm = qemuDomObjFromDomain(dom))) @@ -12467,7 +12467,7 @@ qemuDomainMigratePrepare3(virConnectPtr dconn, goto cleanup; if (!(migParams = qemuMigrationParamsFromFlags(NULL, 0, flags, - QEMU_MIGRATION_DESTINATION))) + QEMU_MIGRATION_DESTINATION, compression))) goto cleanup; if (!(def = qemuMigrationAnyPrepareDef(driver, dom_xml, dname, &origname))) @@ -12481,7 +12481,7 @@ qemuDomainMigratePrepare3(virConnectPtr dconn, cookieout, cookieoutlen, uri_in, uri_out, &def, origname, NULL, 0, NULL, 0, - compression, migParams, flags); + migParams, flags); cleanup: qemuMigrationParamsFree(migParams); @@ -12549,7 +12549,7 @@ qemuDomainMigratePrepare3Params(virConnectPtr dconn, goto cleanup; if (!(migParams = qemuMigrationParamsFromFlags(params, nparams, flags, - QEMU_MIGRATION_DESTINATION))) + QEMU_MIGRATION_DESTINATION, compression))) goto cleanup; if (flags & VIR_MIGRATE_TUNNELLED) { @@ -12574,7 +12574,7 @@ qemuDomainMigratePrepare3Params(virConnectPtr dconn, uri_in, uri_out, &def, origname, listenAddress, nmigrate_disks, migrate_disks, nbdPort, - compression, migParams, flags); + migParams, flags); cleanup: qemuMigrationParamsFree(migParams); @@ -12618,7 +12618,7 @@ qemuDomainMigratePrepareTunnel3(virConnectPtr dconn, goto cleanup; if (!(migParams = qemuMigrationParamsFromFlags(NULL, 0, flags, - QEMU_MIGRATION_DESTINATION))) + QEMU_MIGRATION_DESTINATION, compression))) goto cleanup; if (!(def = qemuMigrationAnyPrepareDef(driver, dom_xml, dname, &origname))) @@ -12630,7 +12630,7 @@ qemuDomainMigratePrepareTunnel3(virConnectPtr dconn, ret = qemuMigrationDstPrepareTunnel(driver, dconn, cookiein, cookieinlen, cookieout, cookieoutlen, - st, &def, origname, compression, migParams, flags); + st, &def, origname, migParams, flags); cleanup: VIR_FREE(compression); @@ -12682,7 +12682,7 @@ qemuDomainMigratePrepareTunnel3Params(virConnectPtr dconn, goto cleanup; if (!(migParams = qemuMigrationParamsFromFlags(params, nparams, flags, - QEMU_MIGRATION_DESTINATION))) + QEMU_MIGRATION_DESTINATION, compression))) goto cleanup; if (!(def = qemuMigrationAnyPrepareDef(driver, dom_xml, dname, &origname))) @@ -12694,7 +12694,7 @@ qemuDomainMigratePrepareTunnel3Params(virConnectPtr dconn, ret = qemuMigrationDstPrepareTunnel(driver, dconn, cookiein, cookieinlen, cookieout, cookieoutlen, - st, &def, origname, compression, migParams, flags); + st, &def, origname, migParams, flags); cleanup: VIR_FREE(compression); @@ -12730,7 +12730,7 @@ qemuDomainMigratePerform3(virDomainPtr dom, goto cleanup; if (!(migParams = qemuMigrationParamsFromFlags(NULL, 0, flags, - QEMU_MIGRATION_SOURCE))) + QEMU_MIGRATION_SOURCE, compression))) goto cleanup; if (!(vm = qemuDomObjFromDomain(dom))) @@ -12822,7 +12822,7 @@ qemuDomainMigratePerform3Params(virDomainPtr dom, goto cleanup; if (!(migParams = qemuMigrationParamsFromFlags(params, nparams, flags, - QEMU_MIGRATION_SOURCE))) + QEMU_MIGRATION_SOURCE, compression))) goto cleanup; if (!(vm = qemuDomObjFromDomain(dom))) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index d0d0d97be4..1c5ee67929 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2158,7 +2158,6 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, size_t nmigrate_disks, const char **migrate_disks, int nbdPort, - qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams, unsigned long flags) { @@ -2372,9 +2371,6 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, dataFD[1] = -1; /* 'st' owns the FD now & will close it */ } - if (qemuMigrationParamsSetCompression(vm, compression, migParams) < 0) - goto stopjob; - if (STREQ_NULLABLE(protocol, "rdma") && virProcessSetMaxMemLock(vm->pid, vm->def->mem.hard_limit << 10) < 0) { goto stopjob; @@ -2526,7 +2522,6 @@ qemuMigrationDstPrepareTunnel(virQEMUDriverPtr driver, virStreamPtr st, virDomainDefPtr *def, const char *origname, - qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams, unsigned long flags) { @@ -2545,7 +2540,7 @@ qemuMigrationDstPrepareTunnel(virQEMUDriverPtr driver, return qemuMigrationDstPrepareAny(driver, dconn, cookiein, cookieinlen, cookieout, cookieoutlen, def, origname, st, NULL, 0, false, NULL, 0, NULL, 0, - compression, migParams, flags); + migParams, flags); } @@ -2587,7 +2582,6 @@ qemuMigrationDstPrepareDirect(virQEMUDriverPtr driver, size_t nmigrate_disks, const char **migrate_disks, int nbdPort, - qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams, unsigned long flags) { @@ -2712,7 +2706,7 @@ qemuMigrationDstPrepareDirect(virQEMUDriverPtr driver, NULL, uri ? uri->scheme : "tcp", port, autoPort, listenAddress, nmigrate_disks, migrate_disks, nbdPort, - compression, migParams, flags); + migParams, flags); cleanup: virURIFree(uri); VIR_FREE(hostname); @@ -3239,7 +3233,6 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, const char *graphicsuri, size_t nmigrate_disks, const char **migrate_disks, - qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams) { int ret = -1; @@ -3314,9 +3307,6 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, if (qemuMigrationSrcGraphicsRelocate(driver, vm, mig, graphicsuri) < 0) VIR_WARN("unable to provide data for graphics client relocation"); - if (qemuMigrationParamsSetCompression(vm, compression, migParams) < 0) - goto error; - if (qemuMigrationParamsCheck(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, migParams) < 0) goto error; @@ -3606,7 +3596,6 @@ qemuMigrationSrcPerformNative(virQEMUDriverPtr driver, const char *graphicsuri, size_t nmigrate_disks, const char **migrate_disks, - qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams) { qemuDomainObjPrivatePtr priv = vm->privateData; @@ -3658,7 +3647,7 @@ qemuMigrationSrcPerformNative(virQEMUDriverPtr driver, ret = qemuMigrationSrcRun(driver, vm, persist_xml, cookiein, cookieinlen, cookieout, cookieoutlen, flags, resource, &spec, dconn, graphicsuri, nmigrate_disks, migrate_disks, - compression, migParams); + migParams); if (spec.destType == MIGRATION_DEST_FD) VIR_FORCE_CLOSE(spec.dest.fd.qemu); @@ -3685,7 +3674,6 @@ qemuMigrationSrcPerformTunnel(virQEMUDriverPtr driver, const char *graphicsuri, size_t nmigrate_disks, const char **migrate_disks, - qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams) { int ret = -1; @@ -3723,7 +3711,7 @@ qemuMigrationSrcPerformTunnel(virQEMUDriverPtr driver, ret = qemuMigrationSrcRun(driver, vm, persist_xml, cookiein, cookieinlen, cookieout, cookieoutlen, flags, resource, &spec, dconn, graphicsuri, nmigrate_disks, migrate_disks, - compression, migParams); + migParams); cleanup: VIR_FORCE_CLOSE(spec.dest.fd.qemu); @@ -3747,7 +3735,6 @@ qemuMigrationSrcPerformPeer2Peer2(virQEMUDriverPtr driver, unsigned long flags, const char *dname, unsigned long resource, - qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams) { virDomainPtr ddomain = NULL; @@ -3832,13 +3819,13 @@ qemuMigrationSrcPerformPeer2Peer2(virQEMUDriverPtr driver, ret = qemuMigrationSrcPerformTunnel(driver, vm, st, NULL, NULL, 0, NULL, NULL, flags, resource, dconn, - NULL, 0, NULL, compression, migParams); + NULL, 0, NULL, migParams); else ret = qemuMigrationSrcPerformNative(driver, vm, NULL, uri_out, cookie, cookielen, NULL, NULL, /* No out cookie with v2 migration */ flags, resource, dconn, NULL, 0, NULL, - compression, migParams); + migParams); /* Perform failed. Make sure Finish doesn't overwrite the error */ if (ret < 0) @@ -4077,14 +4064,14 @@ qemuMigrationSrcPerformPeer2Peer3(virQEMUDriverPtr driver, cookiein, cookieinlen, &cookieout, &cookieoutlen, flags, bandwidth, dconn, graphicsuri, - nmigrate_disks, migrate_disks, compression, + nmigrate_disks, migrate_disks, migParams); } else { ret = qemuMigrationSrcPerformNative(driver, vm, persist_xml, uri, cookiein, cookieinlen, &cookieout, &cookieoutlen, flags, bandwidth, dconn, graphicsuri, - nmigrate_disks, migrate_disks, compression, + nmigrate_disks, migrate_disks, migParams); } @@ -4393,7 +4380,7 @@ qemuMigrationSrcPerformPeer2Peer(virQEMUDriverPtr driver, } else { ret = qemuMigrationSrcPerformPeer2Peer2(driver, sconn, dconn, vm, dconnuri, flags, dname, resource, - compression, migParams); + migParams); } cleanup: @@ -4475,7 +4462,7 @@ qemuMigrationSrcPerformJob(virQEMUDriverPtr driver, ret = qemuMigrationSrcPerformNative(driver, vm, persist_xml, uri, cookiein, cookieinlen, cookieout, cookieoutlen, flags, resource, NULL, NULL, 0, NULL, - compression, migParams); + migParams); } if (ret < 0) goto endjob; @@ -4544,7 +4531,6 @@ qemuMigrationSrcPerformPhase(virQEMUDriverPtr driver, const char *graphicsuri, size_t nmigrate_disks, const char **migrate_disks, - qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams, const char *cookiein, int cookieinlen, @@ -4572,7 +4558,7 @@ qemuMigrationSrcPerformPhase(virQEMUDriverPtr driver, ret = qemuMigrationSrcPerformNative(driver, vm, persist_xml, uri, cookiein, cookieinlen, cookieout, cookieoutlen, flags, resource, NULL, graphicsuri, - nmigrate_disks, migrate_disks, compression, migParams); + nmigrate_disks, migrate_disks, migParams); if (ret < 0) { if (qemuMigrationSrcRestoreDomainState(driver, vm)) { @@ -4667,7 +4653,7 @@ qemuMigrationSrcPerform(virQEMUDriverPtr driver, return qemuMigrationSrcPerformPhase(driver, conn, vm, persist_xml, uri, graphicsuri, nmigrate_disks, migrate_disks, - compression, migParams, + migParams, cookiein, cookieinlen, cookieout, cookieoutlen, flags, resource); diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h index 53d8c529fc..b135f740c1 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -129,7 +129,6 @@ qemuMigrationDstPrepareTunnel(virQEMUDriverPtr driver, virStreamPtr st, virDomainDefPtr *def, const char *origname, - qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams, unsigned long flags); @@ -148,7 +147,6 @@ qemuMigrationDstPrepareDirect(virQEMUDriverPtr driver, size_t nmigrate_disks, const char **migrate_disks, int nbdPort, - qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams, unsigned long flags); diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 94eb08a6bb..5808aa761d 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -137,9 +137,8 @@ qemuMigrationParamsFree(qemuMigrationParamsPtr migParams) } while (0) -int -qemuMigrationParamsSetCompression(virDomainObjPtr vm ATTRIBUTE_UNUSED, - qemuMigrationCompressionPtr compression, +static int +qemuMigrationParamsSetCompression(qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams) { if (compression->methods & (1ULL << QEMU_MIGRATION_COMPRESS_XBZRLE)) @@ -170,7 +169,8 @@ qemuMigrationParamsPtr qemuMigrationParamsFromFlags(virTypedParameterPtr params, int nparams, unsigned long flags, - qemuMigrationParty party) + qemuMigrationParty party, + qemuMigrationCompressionPtr compression) { qemuMigrationParamsPtr migParams; size_t i; @@ -204,6 +204,9 @@ qemuMigrationParamsFromFlags(virTypedParameterPtr params, goto error; } + if (qemuMigrationParamsSetCompression(compression, migParams) < 0) + goto error; + return migParams; error: diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index 165e1267ab..65bd3125dc 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -60,7 +60,8 @@ qemuMigrationParamsPtr qemuMigrationParamsFromFlags(virTypedParameterPtr params, int nparams, unsigned long flags, - qemuMigrationParty party); + qemuMigrationParty party, + qemuMigrationCompressionPtr compression); qemuMigrationCompressionPtr qemuMigrationAnyCompressionParse(virTypedParameterPtr params, @@ -96,11 +97,6 @@ int qemuMigrationParamsDisableTLS(virDomainObjPtr vm, qemuMigrationParamsPtr migParams); -int -qemuMigrationParamsSetCompression(virDomainObjPtr vm, - qemuMigrationCompressionPtr compression, - qemuMigrationParamsPtr migParams); - int qemuMigrationParamsCheck(virQEMUDriverPtr driver, virDomainObjPtr vm, -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:35PM +0200, Jiri Denemark wrote:
There's no need to call this API explicitly in the migration code. We can pass the compression parameters to qemuMigrationParamsFromFlags and it can internally call qemuMigrationParamsSetCompression to apply them to the qemuMigrationParams structure.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_driver.c | 30 ++++++++++++------------- src/qemu/qemu_migration.c | 38 ++++++++++---------------------- src/qemu/qemu_migration.h | 2 -- src/qemu/qemu_migration_params.c | 11 +++++---- src/qemu/qemu_migration_params.h | 8 ++----- 5 files changed, 36 insertions(+), 53 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Since every parameter or capability set in qemuMigrationCompression structure is now reflected in qemuMigrationParams structure, we can replace qemuMigrationAnyCompressionDump with a new API which will work on qemuMigrationParams. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_driver.c | 6 ++-- src/qemu/qemu_migration.c | 16 ++++------ src/qemu/qemu_migration.h | 1 - src/qemu/qemu_migration_params.c | 52 ++++++++++++++------------------ src/qemu/qemu_migration_params.h | 10 +++--- 5 files changed, 37 insertions(+), 48 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 3b0c3a3ffb..5e79e90609 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -12297,7 +12297,7 @@ qemuDomainMigratePerform(virDomainPtr dom, */ ret = qemuMigrationSrcPerform(driver, dom->conn, vm, NULL, NULL, dconnuri, uri, NULL, NULL, 0, NULL, 0, - compression, migParams, cookie, cookielen, + migParams, cookie, cookielen, NULL, NULL, /* No output cookies in v2 */ flags, dname, resource, false); @@ -12743,7 +12743,7 @@ qemuDomainMigratePerform3(virDomainPtr dom, ret = qemuMigrationSrcPerform(driver, dom->conn, vm, xmlin, NULL, dconnuri, uri, NULL, NULL, 0, NULL, 0, - compression, migParams, + migParams, cookiein, cookieinlen, cookieout, cookieoutlen, flags, dname, resource, true); @@ -12836,7 +12836,7 @@ qemuDomainMigratePerform3Params(virDomainPtr dom, ret = qemuMigrationSrcPerform(driver, dom->conn, vm, dom_xml, persist_xml, dconnuri, uri, graphicsuri, listenAddress, nmigrate_disks, migrate_disks, nbdPort, - compression, migParams, + migParams, cookiein, cookieinlen, cookieout, cookieoutlen, flags, dname, bandwidth, true); cleanup: diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 1c5ee67929..319b4d000a 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -3891,7 +3891,6 @@ qemuMigrationSrcPerformPeer2Peer3(virQEMUDriverPtr driver, size_t nmigrate_disks, const char **migrate_disks, int nbdPort, - qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams, unsigned long long bandwidth, bool useParams, @@ -3976,8 +3975,8 @@ qemuMigrationSrcPerformPeer2Peer3(virQEMUDriverPtr driver, nbdPort) < 0) goto cleanup; - if (qemuMigrationAnyCompressionDump(compression, ¶ms, &nparams, - &maxparams, &flags) < 0) + if (qemuMigrationParamsDump(migParams, ¶ms, &nparams, + &maxparams, &flags) < 0) goto cleanup; } @@ -4250,7 +4249,6 @@ qemuMigrationSrcPerformPeer2Peer(virQEMUDriverPtr driver, size_t nmigrate_disks, const char **migrate_disks, int nbdPort, - qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams, unsigned long flags, const char *dname, @@ -4375,7 +4373,7 @@ qemuMigrationSrcPerformPeer2Peer(virQEMUDriverPtr driver, ret = qemuMigrationSrcPerformPeer2Peer3(driver, sconn, dconn, dconnuri, vm, xmlin, persist_xml, dname, uri, graphicsuri, listenAddress, nmigrate_disks, migrate_disks, - nbdPort, compression, migParams, resource, + nbdPort, migParams, resource, useParams, flags); } else { ret = qemuMigrationSrcPerformPeer2Peer2(driver, sconn, dconn, vm, @@ -4416,7 +4414,6 @@ qemuMigrationSrcPerformJob(virQEMUDriverPtr driver, size_t nmigrate_disks, const char **migrate_disks, int nbdPort, - qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams, const char *cookiein, int cookieinlen, @@ -4455,7 +4452,7 @@ qemuMigrationSrcPerformJob(virQEMUDriverPtr driver, ret = qemuMigrationSrcPerformPeer2Peer(driver, conn, vm, xmlin, persist_xml, dconnuri, uri, graphicsuri, listenAddress, nmigrate_disks, migrate_disks, nbdPort, - compression, migParams, flags, dname, resource, + migParams, flags, dname, resource, &v3proto); } else { qemuMigrationJobSetPhase(driver, vm, QEMU_MIGRATION_PHASE_PERFORM2); @@ -4606,7 +4603,6 @@ qemuMigrationSrcPerform(virQEMUDriverPtr driver, size_t nmigrate_disks, const char **migrate_disks, int nbdPort, - qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams, const char *cookiein, int cookieinlen, @@ -4638,7 +4634,7 @@ qemuMigrationSrcPerform(virQEMUDriverPtr driver, return qemuMigrationSrcPerformJob(driver, conn, vm, xmlin, persist_xml, dconnuri, uri, graphicsuri, listenAddress, nmigrate_disks, migrate_disks, nbdPort, - compression, migParams, + migParams, cookiein, cookieinlen, cookieout, cookieoutlen, flags, dname, resource, v3proto); @@ -4661,7 +4657,7 @@ qemuMigrationSrcPerform(virQEMUDriverPtr driver, return qemuMigrationSrcPerformJob(driver, conn, vm, xmlin, persist_xml, NULL, uri, graphicsuri, listenAddress, nmigrate_disks, migrate_disks, nbdPort, - compression, migParams, + migParams, cookiein, cookieinlen, cookieout, cookieoutlen, flags, dname, resource, v3proto); diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h index b135f740c1..e12b6972db 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -163,7 +163,6 @@ qemuMigrationSrcPerform(virQEMUDriverPtr driver, size_t nmigrate_disks, const char **migrate_disks, int nbdPort, - qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams, const char *cookiein, int cookieinlen, diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 5808aa761d..33d91ccf38 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -39,6 +39,7 @@ VIR_LOG_INIT("qemu.qemu_migration_params"); #define QEMU_MIGRATION_TLS_ALIAS_BASE "libvirt_migrate" struct _qemuMigrationParams { + unsigned long long compMethods; /* bit-wise OR of qemuMigrationCompressMethod */ virBitmapPtr caps; qemuMonitorMigrationParams params; }; @@ -149,6 +150,8 @@ qemuMigrationParamsSetCompression(qemuMigrationCompressionPtr compression, ignore_value(virBitmapSetBit(migParams->caps, QEMU_MONITOR_MIGRATION_CAPS_COMPRESS)); + migParams->compMethods = compression->methods; + migParams->params.compressLevel_set = compression->level_set; migParams->params.compressLevel = compression->level; @@ -301,51 +304,42 @@ qemuMigrationAnyCompressionParse(virTypedParameterPtr params, } int -qemuMigrationAnyCompressionDump(qemuMigrationCompressionPtr compression, - virTypedParameterPtr *params, - int *nparams, - int *maxparams, - unsigned long *flags) +qemuMigrationParamsDump(qemuMigrationParamsPtr migParams, + virTypedParameterPtr *params, + int *nparams, + int *maxparams, + unsigned long *flags) { size_t i; - if (compression->methods == 1ULL << QEMU_MIGRATION_COMPRESS_XBZRLE && - !compression->xbzrle_cache_set) { + if (migParams->compMethods == 1ULL << QEMU_MIGRATION_COMPRESS_XBZRLE && + !migParams->params.xbzrleCacheSize_set) { *flags |= VIR_MIGRATE_COMPRESSED; return 0; } for (i = 0; i < QEMU_MIGRATION_COMPRESS_LAST; ++i) { - if ((compression->methods & (1ULL << i)) && + if ((migParams->compMethods & (1ULL << i)) && virTypedParamsAddString(params, nparams, maxparams, VIR_MIGRATE_PARAM_COMPRESSION, qemuMigrationCompressMethodTypeToString(i)) < 0) return -1; } - if (compression->level_set && - virTypedParamsAddInt(params, nparams, maxparams, - VIR_MIGRATE_PARAM_COMPRESSION_MT_LEVEL, - compression->level) < 0) - return -1; +#define SET(API, PARAM, VAR) \ + do { \ + if (migParams->params.VAR ## _set && \ + API(params, nparams, maxparams, VIR_MIGRATE_PARAM_ ## PARAM, \ + migParams->params.VAR) < 0) \ + return -1; \ + } while (0) - if (compression->threads_set && - virTypedParamsAddInt(params, nparams, maxparams, - VIR_MIGRATE_PARAM_COMPRESSION_MT_THREADS, - compression->threads) < 0) - return -1; + SET(virTypedParamsAddInt, COMPRESSION_MT_LEVEL, compressLevel); + SET(virTypedParamsAddInt, COMPRESSION_MT_THREADS, compressThreads); + SET(virTypedParamsAddInt, COMPRESSION_MT_DTHREADS, decompressThreads); + SET(virTypedParamsAddULLong, COMPRESSION_XBZRLE_CACHE, xbzrleCacheSize); - if (compression->dthreads_set && - virTypedParamsAddInt(params, nparams, maxparams, - VIR_MIGRATE_PARAM_COMPRESSION_MT_DTHREADS, - compression->dthreads) < 0) - return -1; - - if (compression->xbzrle_cache_set && - virTypedParamsAddULLong(params, nparams, maxparams, - VIR_MIGRATE_PARAM_COMPRESSION_XBZRLE_CACHE, - compression->xbzrle_cache) < 0) - return -1; +#undef SET return 0; } diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index 65bd3125dc..d778a8e339 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -68,11 +68,11 @@ qemuMigrationAnyCompressionParse(virTypedParameterPtr params, int nparams, unsigned long flags); int -qemuMigrationAnyCompressionDump(qemuMigrationCompressionPtr compression, - virTypedParameterPtr *params, - int *nparams, - int *maxparams, - unsigned long *flags); +qemuMigrationParamsDump(qemuMigrationParamsPtr migParams, + virTypedParameterPtr *params, + int *nparams, + int *maxparams, + unsigned long *flags); void qemuMigrationParamsFree(qemuMigrationParamsPtr migParams); -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:36PM +0200, Jiri Denemark wrote:
Since every parameter or capability set in qemuMigrationCompression structure is now reflected in qemuMigrationParams structure, we can replace qemuMigrationAnyCompressionDump with a new API which will work on qemuMigrationParams.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_driver.c | 6 ++-- src/qemu/qemu_migration.c | 16 ++++------ src/qemu/qemu_migration.h | 1 - src/qemu/qemu_migration_params.c | 52 ++++++++++++++------------------ src/qemu/qemu_migration_params.h | 10 +++--- 5 files changed, 37 insertions(+), 48 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

By merging qemuMigrationAnyCompressionParse into qemuMigrationParamsSetCompression we can drop the useless intermediate qemuMigrationCompression structure and parse compression related typed parameters and flags directly into qemuMigrationParams. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_driver.c | 63 ++--------- src/qemu/qemu_migration_params.c | 181 +++++++++++++------------------ src/qemu/qemu_migration_params.h | 26 +---- 3 files changed, 85 insertions(+), 185 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 5e79e90609..8e880280ec 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -12126,7 +12126,6 @@ qemuDomainMigratePrepareTunnel(virConnectPtr dconn, virQEMUDriverPtr driver = dconn->privateData; virDomainDefPtr def = NULL; char *origname = NULL; - qemuMigrationCompressionPtr compression = NULL; qemuMigrationParamsPtr migParams = NULL; int ret = -1; @@ -12138,11 +12137,8 @@ qemuDomainMigratePrepareTunnel(virConnectPtr dconn, goto cleanup; } - if (!(compression = qemuMigrationAnyCompressionParse(NULL, 0, flags))) - goto cleanup; - if (!(migParams = qemuMigrationParamsFromFlags(NULL, 0, flags, - QEMU_MIGRATION_DESTINATION, compression))) + QEMU_MIGRATION_DESTINATION))) goto cleanup; if (virLockManagerPluginUsesState(driver->lockManager)) { @@ -12163,7 +12159,6 @@ qemuDomainMigratePrepareTunnel(virConnectPtr dconn, st, &def, origname, migParams, flags); cleanup: - VIR_FREE(compression); qemuMigrationParamsFree(migParams); VIR_FREE(origname); virDomainDefFree(def); @@ -12188,7 +12183,6 @@ qemuDomainMigratePrepare2(virConnectPtr dconn, virQEMUDriverPtr driver = dconn->privateData; virDomainDefPtr def = NULL; char *origname = NULL; - qemuMigrationCompressionPtr compression = NULL; qemuMigrationParamsPtr migParams = NULL; int ret = -1; @@ -12204,11 +12198,8 @@ qemuDomainMigratePrepare2(virConnectPtr dconn, goto cleanup; } - if (!(compression = qemuMigrationAnyCompressionParse(NULL, 0, flags))) - goto cleanup; - if (!(migParams = qemuMigrationParamsFromFlags(NULL, 0, flags, - QEMU_MIGRATION_DESTINATION, compression))) + QEMU_MIGRATION_DESTINATION))) goto cleanup; if (virLockManagerPluginUsesState(driver->lockManager)) { @@ -12236,7 +12227,6 @@ qemuDomainMigratePrepare2(virConnectPtr dconn, cleanup: qemuMigrationParamsFree(migParams); - VIR_FREE(compression); VIR_FREE(origname); virDomainDefFree(def); return ret; @@ -12257,7 +12247,6 @@ qemuDomainMigratePerform(virDomainPtr dom, virDomainObjPtr vm; int ret = -1; const char *dconnuri = NULL; - qemuMigrationCompressionPtr compression = NULL; qemuMigrationParamsPtr migParams = NULL; virCheckFlags(QEMU_MIGRATION_FLAGS, -1); @@ -12269,11 +12258,8 @@ qemuDomainMigratePerform(virDomainPtr dom, goto cleanup; } - if (!(compression = qemuMigrationAnyCompressionParse(NULL, 0, flags))) - goto cleanup; - if (!(migParams = qemuMigrationParamsFromFlags(NULL, 0, flags, - QEMU_MIGRATION_SOURCE, compression))) + QEMU_MIGRATION_SOURCE))) goto cleanup; if (!(vm = qemuDomObjFromDomain(dom))) @@ -12303,7 +12289,6 @@ qemuDomainMigratePerform(virDomainPtr dom, cleanup: qemuMigrationParamsFree(migParams); - VIR_FREE(compression); return ret; } @@ -12447,7 +12432,6 @@ qemuDomainMigratePrepare3(virConnectPtr dconn, virQEMUDriverPtr driver = dconn->privateData; virDomainDefPtr def = NULL; char *origname = NULL; - qemuMigrationCompressionPtr compression = NULL; qemuMigrationParamsPtr migParams = NULL; int ret = -1; @@ -12463,11 +12447,8 @@ qemuDomainMigratePrepare3(virConnectPtr dconn, goto cleanup; } - if (!(compression = qemuMigrationAnyCompressionParse(NULL, 0, flags))) - goto cleanup; - if (!(migParams = qemuMigrationParamsFromFlags(NULL, 0, flags, - QEMU_MIGRATION_DESTINATION, compression))) + QEMU_MIGRATION_DESTINATION))) goto cleanup; if (!(def = qemuMigrationAnyPrepareDef(driver, dom_xml, dname, &origname))) @@ -12485,7 +12466,6 @@ qemuDomainMigratePrepare3(virConnectPtr dconn, cleanup: qemuMigrationParamsFree(migParams); - VIR_FREE(compression); VIR_FREE(origname); virDomainDefFree(def); return ret; @@ -12513,7 +12493,6 @@ qemuDomainMigratePrepare3Params(virConnectPtr dconn, int nmigrate_disks; const char **migrate_disks = NULL; char *origname = NULL; - qemuMigrationCompressionPtr compression = NULL; qemuMigrationParamsPtr migParams = NULL; int ret = -1; @@ -12545,11 +12524,8 @@ qemuDomainMigratePrepare3Params(virConnectPtr dconn, if (nmigrate_disks < 0) goto cleanup; - if (!(compression = qemuMigrationAnyCompressionParse(params, nparams, flags))) - goto cleanup; - if (!(migParams = qemuMigrationParamsFromFlags(params, nparams, flags, - QEMU_MIGRATION_DESTINATION, compression))) + QEMU_MIGRATION_DESTINATION))) goto cleanup; if (flags & VIR_MIGRATE_TUNNELLED) { @@ -12578,7 +12554,6 @@ qemuDomainMigratePrepare3Params(virConnectPtr dconn, cleanup: qemuMigrationParamsFree(migParams); - VIR_FREE(compression); VIR_FREE(migrate_disks); VIR_FREE(origname); virDomainDefFree(def); @@ -12602,7 +12577,6 @@ qemuDomainMigratePrepareTunnel3(virConnectPtr dconn, virQEMUDriverPtr driver = dconn->privateData; virDomainDefPtr def = NULL; char *origname = NULL; - qemuMigrationCompressionPtr compression = NULL; qemuMigrationParamsPtr migParams = NULL; int ret = -1; @@ -12614,11 +12588,8 @@ qemuDomainMigratePrepareTunnel3(virConnectPtr dconn, goto cleanup; } - if (!(compression = qemuMigrationAnyCompressionParse(NULL, 0, flags))) - goto cleanup; - if (!(migParams = qemuMigrationParamsFromFlags(NULL, 0, flags, - QEMU_MIGRATION_DESTINATION, compression))) + QEMU_MIGRATION_DESTINATION))) goto cleanup; if (!(def = qemuMigrationAnyPrepareDef(driver, dom_xml, dname, &origname))) @@ -12633,7 +12604,6 @@ qemuDomainMigratePrepareTunnel3(virConnectPtr dconn, st, &def, origname, migParams, flags); cleanup: - VIR_FREE(compression); qemuMigrationParamsFree(migParams); VIR_FREE(origname); virDomainDefFree(def); @@ -12656,7 +12626,6 @@ qemuDomainMigratePrepareTunnel3Params(virConnectPtr dconn, const char *dom_xml = NULL; const char *dname = NULL; char *origname = NULL; - qemuMigrationCompressionPtr compression = NULL; qemuMigrationParamsPtr migParams = NULL; int ret = -1; @@ -12678,11 +12647,8 @@ qemuDomainMigratePrepareTunnel3Params(virConnectPtr dconn, goto cleanup; } - if (!(compression = qemuMigrationAnyCompressionParse(NULL, 0, flags))) - goto cleanup; - if (!(migParams = qemuMigrationParamsFromFlags(params, nparams, flags, - QEMU_MIGRATION_DESTINATION, compression))) + QEMU_MIGRATION_DESTINATION))) goto cleanup; if (!(def = qemuMigrationAnyPrepareDef(driver, dom_xml, dname, &origname))) @@ -12697,7 +12663,6 @@ qemuDomainMigratePrepareTunnel3Params(virConnectPtr dconn, st, &def, origname, migParams, flags); cleanup: - VIR_FREE(compression); qemuMigrationParamsFree(migParams); VIR_FREE(origname); virDomainDefFree(def); @@ -12720,17 +12685,13 @@ qemuDomainMigratePerform3(virDomainPtr dom, { virQEMUDriverPtr driver = dom->conn->privateData; virDomainObjPtr vm; - qemuMigrationCompressionPtr compression = NULL; qemuMigrationParamsPtr migParams = NULL; int ret = -1; virCheckFlags(QEMU_MIGRATION_FLAGS, -1); - if (!(compression = qemuMigrationAnyCompressionParse(NULL, 0, flags))) - goto cleanup; - if (!(migParams = qemuMigrationParamsFromFlags(NULL, 0, flags, - QEMU_MIGRATION_SOURCE, compression))) + QEMU_MIGRATION_SOURCE))) goto cleanup; if (!(vm = qemuDomObjFromDomain(dom))) @@ -12750,7 +12711,6 @@ qemuDomainMigratePerform3(virDomainPtr dom, cleanup: qemuMigrationParamsFree(migParams); - VIR_FREE(compression); return ret; } @@ -12777,7 +12737,6 @@ qemuDomainMigratePerform3Params(virDomainPtr dom, const char **migrate_disks = NULL; unsigned long long bandwidth = 0; int nbdPort = 0; - qemuMigrationCompressionPtr compression = NULL; qemuMigrationParamsPtr migParams = NULL; int ret = -1; @@ -12818,11 +12777,8 @@ qemuDomainMigratePerform3Params(virDomainPtr dom, if (nmigrate_disks < 0) goto cleanup; - if (!(compression = qemuMigrationAnyCompressionParse(params, nparams, flags))) - goto cleanup; - if (!(migParams = qemuMigrationParamsFromFlags(params, nparams, flags, - QEMU_MIGRATION_SOURCE, compression))) + QEMU_MIGRATION_SOURCE))) goto cleanup; if (!(vm = qemuDomObjFromDomain(dom))) @@ -12840,7 +12796,6 @@ qemuDomainMigratePerform3Params(virDomainPtr dom, cookiein, cookieinlen, cookieout, cookieoutlen, flags, dname, bandwidth, true); cleanup: - VIR_FREE(compression); qemuMigrationParamsFree(migParams); VIR_FREE(migrate_disks); return ret; diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 33d91ccf38..388a1f5804 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -139,32 +139,85 @@ qemuMigrationParamsFree(qemuMigrationParamsPtr migParams) static int -qemuMigrationParamsSetCompression(qemuMigrationCompressionPtr compression, +qemuMigrationParamsSetCompression(virTypedParameterPtr params, + int nparams, + unsigned long flags, qemuMigrationParamsPtr migParams) { - if (compression->methods & (1ULL << QEMU_MIGRATION_COMPRESS_XBZRLE)) + size_t i; + int method; + qemuMonitorMigrationCaps cap; + + for (i = 0; i < nparams; i++) { + if (STRNEQ(params[i].field, VIR_MIGRATE_PARAM_COMPRESSION)) + continue; + + method = qemuMigrationCompressMethodTypeFromString(params[i].value.s); + if (method < 0) { + virReportError(VIR_ERR_INVALID_ARG, + _("Unsupported compression method '%s'"), + params[i].value.s); + goto error; + } + + if (migParams->compMethods & (1ULL << method)) { + virReportError(VIR_ERR_INVALID_ARG, + _("Compression method '%s' is specified twice"), + params[i].value.s); + goto error; + } + + migParams->compMethods |= 1ULL << method; + + switch ((qemuMigrationCompressMethod) method) { + case QEMU_MIGRATION_COMPRESS_XBZRLE: + cap = QEMU_MONITOR_MIGRATION_CAPS_XBZRLE; + break; + + case QEMU_MIGRATION_COMPRESS_MT: + cap = QEMU_MONITOR_MIGRATION_CAPS_COMPRESS; + break; + + case QEMU_MIGRATION_COMPRESS_LAST: + default: + continue; + } + ignore_value(virBitmapSetBit(migParams->caps, cap)); + } + + if (params) { + GET(virTypedParamsGetInt, COMPRESSION_MT_LEVEL, compressLevel); + GET(virTypedParamsGetInt, COMPRESSION_MT_THREADS, compressThreads); + GET(virTypedParamsGetInt, COMPRESSION_MT_DTHREADS, decompressThreads); + GET(virTypedParamsGetULLong, COMPRESSION_XBZRLE_CACHE, xbzrleCacheSize); + } + + if ((migParams->params.compressLevel_set || + migParams->params.compressThreads_set || + migParams->params.decompressThreads_set) && + !(migParams->compMethods & (1ULL << QEMU_MIGRATION_COMPRESS_MT))) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("Turn multithread compression on to tune it")); + goto error; + } + + if (migParams->params.xbzrleCacheSize_set && + !(migParams->compMethods & (1ULL << QEMU_MIGRATION_COMPRESS_XBZRLE))) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("Turn xbzrle compression on to tune it")); + goto error; + } + + if (!migParams->compMethods && (flags & VIR_MIGRATE_COMPRESSED)) { + migParams->compMethods = 1ULL << QEMU_MIGRATION_COMPRESS_XBZRLE; ignore_value(virBitmapSetBit(migParams->caps, QEMU_MONITOR_MIGRATION_CAPS_XBZRLE)); - - if (compression->methods & (1ULL << QEMU_MIGRATION_COMPRESS_MT)) - ignore_value(virBitmapSetBit(migParams->caps, - QEMU_MONITOR_MIGRATION_CAPS_COMPRESS)); - - migParams->compMethods = compression->methods; - - migParams->params.compressLevel_set = compression->level_set; - migParams->params.compressLevel = compression->level; - - migParams->params.compressThreads_set = compression->threads_set; - migParams->params.compressThreads = compression->threads; - - migParams->params.decompressThreads_set = compression->dthreads_set; - migParams->params.decompressThreads = compression->dthreads; - - migParams->params.xbzrleCacheSize_set = compression->xbzrle_cache_set; - migParams->params.xbzrleCacheSize = compression->xbzrle_cache; + } return 0; + + error: + return -1; } @@ -172,8 +225,7 @@ qemuMigrationParamsPtr qemuMigrationParamsFromFlags(virTypedParameterPtr params, int nparams, unsigned long flags, - qemuMigrationParty party, - qemuMigrationCompressionPtr compression) + qemuMigrationParty party) { qemuMigrationParamsPtr migParams; size_t i; @@ -207,7 +259,7 @@ qemuMigrationParamsFromFlags(virTypedParameterPtr params, goto error; } - if (qemuMigrationParamsSetCompression(compression, migParams) < 0) + if (qemuMigrationParamsSetCompression(params, nparams, flags, migParams) < 0) goto error; return migParams; @@ -220,89 +272,6 @@ qemuMigrationParamsFromFlags(virTypedParameterPtr params, #undef GET -qemuMigrationCompressionPtr -qemuMigrationAnyCompressionParse(virTypedParameterPtr params, - int nparams, - unsigned long flags) -{ - size_t i; - qemuMigrationCompressionPtr compression = NULL; - - if (VIR_ALLOC(compression) < 0) - return NULL; - - for (i = 0; i < nparams; i++) { - int method; - - if (STRNEQ(params[i].field, VIR_MIGRATE_PARAM_COMPRESSION)) - continue; - - method = qemuMigrationCompressMethodTypeFromString(params[i].value.s); - if (method < 0) { - virReportError(VIR_ERR_INVALID_ARG, - _("Unsupported compression method '%s'"), - params[i].value.s); - goto error; - } - - if (compression->methods & (1ULL << method)) { - virReportError(VIR_ERR_INVALID_ARG, - _("Compression method '%s' is specified twice"), - params[i].value.s); - goto error; - } - - compression->methods |= 1ULL << method; - } - -#define GET_PARAM(PARAM, TYPE, VALUE) \ - do { \ - int rc; \ - const char *par = VIR_MIGRATE_PARAM_COMPRESSION_ ## PARAM; \ - \ - if ((rc = virTypedParamsGet ## TYPE(params, nparams, \ - par, &compression->VALUE)) < 0) \ - goto error; \ - \ - if (rc == 1) \ - compression->VALUE ## _set = true; \ - } while (0) - - if (params) { - GET_PARAM(MT_LEVEL, Int, level); - GET_PARAM(MT_THREADS, Int, threads); - GET_PARAM(MT_DTHREADS, Int, dthreads); - GET_PARAM(XBZRLE_CACHE, ULLong, xbzrle_cache); - } - -#undef GET_PARAM - - if ((compression->level_set || - compression->threads_set || - compression->dthreads_set) && - !(compression->methods & (1ULL << QEMU_MIGRATION_COMPRESS_MT))) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("Turn multithread compression on to tune it")); - goto error; - } - - if (compression->xbzrle_cache_set && - !(compression->methods & (1ULL << QEMU_MIGRATION_COMPRESS_XBZRLE))) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("Turn xbzrle compression on to tune it")); - goto error; - } - - if (!compression->methods && (flags & VIR_MIGRATE_COMPRESSED)) - compression->methods = 1ULL << QEMU_MIGRATION_COMPRESS_XBZRLE; - - return compression; - - error: - VIR_FREE(compression); - return NULL; -} - int qemuMigrationParamsDump(qemuMigrationParamsPtr migParams, virTypedParameterPtr *params, diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index d778a8e339..3d1ada1a61 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -28,25 +28,6 @@ # include "qemu_conf.h" -typedef struct _qemuMigrationCompression qemuMigrationCompression; -typedef qemuMigrationCompression *qemuMigrationCompressionPtr; -struct _qemuMigrationCompression { - unsigned long long methods; - - bool level_set; - int level; - - bool threads_set; - int threads; - - bool dthreads_set; - int dthreads; - - bool xbzrle_cache_set; - unsigned long long xbzrle_cache; -}; - - typedef struct _qemuMigrationParams qemuMigrationParams; typedef qemuMigrationParams *qemuMigrationParamsPtr; @@ -60,13 +41,8 @@ qemuMigrationParamsPtr qemuMigrationParamsFromFlags(virTypedParameterPtr params, int nparams, unsigned long flags, - qemuMigrationParty party, - qemuMigrationCompressionPtr compression); + qemuMigrationParty party); -qemuMigrationCompressionPtr -qemuMigrationAnyCompressionParse(virTypedParameterPtr params, - int nparams, - unsigned long flags); int qemuMigrationParamsDump(qemuMigrationParamsPtr migParams, virTypedParameterPtr *params, -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:37PM +0200, Jiri Denemark wrote:
By merging qemuMigrationAnyCompressionParse into qemuMigrationParamsSetCompression we can drop the useless intermediate qemuMigrationCompression structure and parse compression related typed parameters and flags directly into qemuMigrationParams.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_driver.c | 63 ++--------- src/qemu/qemu_migration_params.c | 181 +++++++++++++------------------ src/qemu/qemu_migration_params.h | 26 +---- 3 files changed, 85 insertions(+), 185 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Let's separate the code which queries QEMU for migration parameters from qemuMigrationParamsCheck into a dedicated function. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 56 +++++++++++++++++++------------- src/qemu/qemu_migration_params.h | 6 ++++ 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 388a1f5804..94de0458f5 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -520,6 +520,39 @@ qemuMigrationParamsResetTLS(virQEMUDriverPtr driver, } +int +qemuMigrationParamsFetch(virQEMUDriverPtr driver, + virDomainObjPtr vm, + int asyncJob, + qemuMigrationParamsPtr *migParams) +{ + qemuDomainObjPrivatePtr priv = vm->privateData; + qemuMigrationParamsPtr params = NULL; + int ret = -1; + int rc; + + *migParams = NULL; + + if (!(params = qemuMigrationParamsNew())) + return -1; + + if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) + goto cleanup; + + rc = qemuMonitorGetMigrationParams(priv->mon, ¶ms->params); + + if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0) + goto cleanup; + + VIR_STEAL_PTR(*migParams, params); + ret = 0; + + cleanup: + qemuMigrationParamsFree(params); + return ret; +} + + /** * qemuMigrationParamsCheck: * @@ -535,11 +568,9 @@ qemuMigrationParamsCheck(virQEMUDriverPtr driver, qemuMigrationParamsPtr migParams) { qemuDomainObjPrivatePtr priv = vm->privateData; - qemuMigrationParamsPtr origParams = NULL; qemuMonitorMigrationCaps cap; qemuMigrationParty party; size_t i; - int ret = -1; if (asyncJob == QEMU_ASYNC_JOB_MIGRATION_OUT) party = QEMU_MIGRATION_SOURCE; @@ -570,31 +601,12 @@ qemuMigrationParamsCheck(virQEMUDriverPtr driver, } } - if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) - return -1; - - if (!(origParams = qemuMigrationParamsNew())) - goto cleanup; - /* * We want to disable all migration capabilities after migration, no need * to ask QEMU for their current settings. */ - if (qemuMonitorGetMigrationParams(priv->mon, &origParams->params) < 0) - goto cleanup; - - ret = 0; - - cleanup: - if (qemuDomainObjExitMonitor(driver, vm) < 0) - ret = -1; - - if (ret == 0) - VIR_STEAL_PTR(priv->job.migParams, origParams); - qemuMigrationParamsFree(origParams); - - return ret; + return qemuMigrationParamsFetch(driver, vm, asyncJob, &priv->job.migParams); } diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index 3d1ada1a61..0a30dcd623 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -73,6 +73,12 @@ int qemuMigrationParamsDisableTLS(virDomainObjPtr vm, qemuMigrationParamsPtr migParams); +int +qemuMigrationParamsFetch(virQEMUDriverPtr driver, + virDomainObjPtr vm, + int asyncJob, + qemuMigrationParamsPtr *migParams); + int qemuMigrationParamsCheck(virQEMUDriverPtr driver, virDomainObjPtr vm, -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:38PM +0200, Jiri Denemark wrote:
Let's separate the code which queries QEMU for migration parameters from qemuMigrationParamsCheck into a dedicated function.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 56 +++++++++++++++++++------------- src/qemu/qemu_migration_params.h | 6 ++++ 2 files changed, 40 insertions(+), 22 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Use this internal structure only in qemu_migration_params.c and change other non-test users to use the high level qemuMigrationParams struct. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_driver.c | 26 +++++++++++--------------- src/qemu/qemu_migration_params.c | 16 ++++++++++++++++ src/qemu/qemu_migration_params.h | 4 ++++ 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 8e880280ec..761f84ee7f 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -13555,8 +13555,7 @@ qemuDomainMigrateGetMaxDowntime(virDomainPtr dom, { virQEMUDriverPtr driver = dom->conn->privateData; virDomainObjPtr vm; - qemuDomainObjPrivatePtr priv; - qemuMonitorMigrationParams migparams = { 0 }; + qemuMigrationParamsPtr migParams = NULL; int ret = -1; virCheckFlags(0, -1); @@ -13576,27 +13575,24 @@ qemuDomainMigrateGetMaxDowntime(virDomainPtr dom, goto endjob; } - priv = vm->privateData; - qemuDomainObjEnterMonitor(driver, vm); + if (qemuMigrationParamsFetch(driver, vm, QEMU_ASYNC_JOB_NONE, + &migParams) < 0) + goto endjob; - if (qemuMonitorGetMigrationParams(priv->mon, &migparams) == 0) { - if (migparams.downtimeLimit_set) { - *downtime = migparams.downtimeLimit; - ret = 0; - } else { - virReportError(VIR_ERR_OPERATION_INVALID, "%s", - _("Querying migration downtime is not supported by " - "QEMU binary")); - } + if (qemuMigrationParamsGetDowntimeLimit(migParams, downtime) == 1) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("Querying migration downtime is not supported by " + "QEMU binary")); + goto endjob; } - if (qemuDomainObjExitMonitor(driver, vm) < 0) - ret = -1; + ret = 0; endjob: qemuDomainObjEndJob(driver, vm); cleanup: + qemuMigrationParamsFree(migParams); virDomainObjEndAPI(&vm); return ret; } diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 94de0458f5..cadb402b0f 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -553,6 +553,22 @@ qemuMigrationParamsFetch(virQEMUDriverPtr driver, } +/** + * Returns 0 on success, + * 1 if the parameter is not supported by QEMU. + */ +int +qemuMigrationParamsGetDowntimeLimit(qemuMigrationParamsPtr migParams, + unsigned long long *value) +{ + if (!migParams->params.downtimeLimit_set) + return 1; + + *value = migParams->params.downtimeLimit; + return 0; +} + + /** * qemuMigrationParamsCheck: * diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index 0a30dcd623..cc9a14601b 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -79,6 +79,10 @@ qemuMigrationParamsFetch(virQEMUDriverPtr driver, int asyncJob, qemuMigrationParamsPtr *migParams); +int +qemuMigrationParamsGetDowntimeLimit(qemuMigrationParamsPtr migParams, + unsigned long long *value); + int qemuMigrationParamsCheck(virQEMUDriverPtr driver, virDomainObjPtr vm, -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:39PM +0200, Jiri Denemark wrote:
Use this internal structure only in qemu_migration_params.c and change other non-test users to use the high level qemuMigrationParams struct.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_driver.c | 26 +++++++++++--------------- src/qemu/qemu_migration_params.c | 16 ++++++++++++++++ src/qemu/qemu_migration_params.h | 4 ++++ 3 files changed, 31 insertions(+), 15 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

The test is mostly useless and we want to refactor migration parameters even further. The refactoring will allow us to introduce enhanced tests for migration parameters. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- tests/qemumonitorjsontest.c | 99 ------------------------------------- 1 file changed, 99 deletions(-) diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index 8a5b0be64b..dafcccebad 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -1787,104 +1787,6 @@ testQemuMonitorJSONqemuMonitorJSONGetBlockStatsInfo(const void *data) return ret; } -static int -testQemuMonitorJSONqemuMonitorJSONGetMigrationParams(const void *data) -{ - virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data; - qemuMonitorTestPtr test = qemuMonitorTestNewSimple(true, xmlopt); - qemuMonitorMigrationParams params; - int ret = -1; - - if (!test) - return -1; - - if (qemuMonitorTestAddItem(test, "query-migrate-parameters", - "{" - " \"return\": {" - " \"decompress-threads\": 2," - " \"cpu-throttle-increment\": 10," - " \"compress-threads\": 8," - " \"compress-level\": 1," - " \"cpu-throttle-initial\": 20," - " \"tls-creds\": \"tls0\"," - " \"tls-hostname\": \"\"," - " \"max-bandwidth\": 1234567890," - " \"downtime-limit\": 500," - " \"block-incremental\": true," - " \"xbzrle-cache-size\": 67108864" - " }" - "}") < 0) { - goto cleanup; - } - - if (qemuMonitorJSONGetMigrationParams(qemuMonitorTestGetMonitor(test), - ¶ms) < 0) - goto cleanup; - -#define CHECK_NUM(VAR, FIELD, VALUE, FMT) \ - do { \ - if (!params.VAR ## _set) { \ - virReportError(VIR_ERR_INTERNAL_ERROR, "%s is not set", FIELD); \ - goto cleanup; \ - } \ - if (params.VAR != VALUE) { \ - virReportError(VIR_ERR_INTERNAL_ERROR, \ - "Invalid %s: " FMT ", expected " FMT, \ - FIELD, params.VAR, VALUE); \ - goto cleanup; \ - } \ - } while (0) - -#define CHECK_INT(VAR, FIELD, VALUE) \ - CHECK_NUM(VAR, FIELD, VALUE, "%d") - -#define CHECK_ULONG(VAR, FIELD, VALUE) \ - CHECK_NUM(VAR, FIELD, VALUE, "%llu") - -#define CHECK_BOOL(VAR, FIELD, VALUE) \ - CHECK_NUM(VAR, FIELD, VALUE, "%d") - -#define CHECK_STR(VAR, FIELD, VALUE) \ - do { \ - if (!params.VAR) { \ - virReportError(VIR_ERR_INTERNAL_ERROR, "%s is not set", FIELD); \ - goto cleanup; \ - } \ - if (STRNEQ(params.VAR, VALUE)) { \ - virReportError(VIR_ERR_INTERNAL_ERROR, \ - "Invalid %s:'%s', expected '%s'", \ - FIELD, params.VAR, VALUE); \ - goto cleanup; \ - } \ - } while (0) - - CHECK_INT(compressLevel, "compress-level", 1); - CHECK_INT(compressThreads, "compress-threads", 8); - CHECK_INT(decompressThreads, "decompress-threads", 2); - CHECK_INT(cpuThrottleInitial, "cpu-throttle-initial", 20); - CHECK_INT(cpuThrottleIncrement, "cpu-throttle-increment", 10); - CHECK_STR(tlsCreds, "tls-creds", "tls0"); - CHECK_STR(tlsHostname, "tls-hostname", ""); - CHECK_ULONG(maxBandwidth, "max-bandwidth", 1234567890ULL); - CHECK_ULONG(downtimeLimit, "downtime-limit", 500ULL); - CHECK_BOOL(blockIncremental, "block-incremental", true); - CHECK_ULONG(xbzrleCacheSize, "xbzrle-cache-size", 67108864ULL); - -#undef CHECK_NUM -#undef CHECK_INT -#undef CHECK_ULONG -#undef CHECK_BOOL -#undef CHECK_STR - - ret = 0; - - cleanup: - VIR_FREE(params.tlsCreds); - VIR_FREE(params.tlsHostname); - qemuMonitorTestFree(test); - return ret; -} - static int testQemuMonitorJSONqemuMonitorJSONGetMigrationCacheSize(const void *data) @@ -3002,7 +2904,6 @@ mymain(void) DO_TEST(qemuMonitorJSONGetBlockInfo); DO_TEST(qemuMonitorJSONGetBlockStatsInfo); DO_TEST(qemuMonitorJSONGetMigrationCacheSize); - DO_TEST(qemuMonitorJSONGetMigrationParams); DO_TEST(qemuMonitorJSONGetMigrationStats); DO_TEST(qemuMonitorJSONGetChardevInfo); DO_TEST(qemuMonitorJSONSetBlockIoThrottle); -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:40PM +0200, Jiri Denemark wrote:
The test is mostly useless and we want to refactor migration parameters even further. The refactoring will allow us to introduce enhanced tests for migration parameters.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- tests/qemumonitorjsontest.c | 99 ------------------------------------- 1 file changed, 99 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/libvirt_private.syms | 1 + src/util/virjson.c | 8 ++++++++ src/util/virjson.h | 2 ++ 3 files changed, 11 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index cab324c4d7..0918e69525 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2098,6 +2098,7 @@ virJSONValueObjectIsNull; virJSONValueObjectKeysNumber; virJSONValueObjectRemoveKey; virJSONValueObjectStealArray; +virJSONValueObjectStealObject; virJSONValueToString; diff --git a/src/util/virjson.c b/src/util/virjson.c index 3ddefc34ca..dfe00d9280 100644 --- a/src/util/virjson.c +++ b/src/util/virjson.c @@ -1400,6 +1400,14 @@ virJSONValueObjectStealArray(virJSONValuePtr object, const char *key) } +virJSONValuePtr +virJSONValueObjectStealObject(virJSONValuePtr object, + const char *key) +{ + return virJSONValueObjectStealByType(object, key, VIR_JSON_TYPE_OBJECT); +} + + int virJSONValueObjectIsNull(virJSONValuePtr object, const char *key) diff --git a/src/util/virjson.h b/src/util/virjson.h index f7283dcf97..0f098892b4 100644 --- a/src/util/virjson.h +++ b/src/util/virjson.h @@ -112,6 +112,8 @@ virJSONValuePtr virJSONValueObjectGetArray(virJSONValuePtr object, const char *key); virJSONValuePtr virJSONValueObjectStealArray(virJSONValuePtr object, const char *key); +virJSONValuePtr virJSONValueObjectStealObject(virJSONValuePtr object, + const char *key); const char *virJSONValueObjectGetString(virJSONValuePtr object, const char *key); const char *virJSONValueObjectGetStringOrNumber(virJSONValuePtr object, const char *key); -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:41PM +0200, Jiri Denemark wrote:
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/libvirt_private.syms | 1 + src/util/virjson.c | 8 ++++++++ src/util/virjson.h | 2 ++ 3 files changed, 11 insertions(+)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

We want to have all migration parameters parsing and formatting at once place, i.e., in qemu_migration_params.c. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 74 +++++++++++++++++++++++++++++--- src/qemu/qemu_monitor.c | 13 +++++- src/qemu/qemu_monitor.h | 2 +- src/qemu/qemu_monitor_json.c | 51 ++-------------------- src/qemu/qemu_monitor_json.h | 2 +- 5 files changed, 85 insertions(+), 57 deletions(-) diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index cadb402b0f..845234c34b 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -314,6 +314,67 @@ qemuMigrationParamsDump(qemuMigrationParamsPtr migParams, } +static qemuMigrationParamsPtr +qemuMigrationParamsFromJSON(virJSONValuePtr params) +{ + qemuMigrationParamsPtr migParams = NULL; + + if (!(migParams = qemuMigrationParamsNew())) + return NULL; + + if (!params) + return migParams; + +#define PARSE_SET(API, VAR, FIELD) \ + do { \ + if (API(params, FIELD, &migParams->params.VAR) == 0) \ + migParams->params.VAR ## _set = true; \ + } while (0) + +#define PARSE_INT(VAR, FIELD) \ + PARSE_SET(virJSONValueObjectGetNumberInt, VAR, FIELD) + +#define PARSE_ULONG(VAR, FIELD) \ + PARSE_SET(virJSONValueObjectGetNumberUlong, VAR, FIELD) + +#define PARSE_BOOL(VAR, FIELD) \ + PARSE_SET(virJSONValueObjectGetBoolean, VAR, FIELD) + +#define PARSE_STR(VAR, FIELD) \ + do { \ + const char *str; \ + if ((str = virJSONValueObjectGetString(params, FIELD))) { \ + if (VIR_STRDUP(migParams->params.VAR, str) < 0) \ + goto error; \ + } \ + } while (0) + + PARSE_INT(compressLevel, "compress-level"); + PARSE_INT(compressThreads, "compress-threads"); + PARSE_INT(decompressThreads, "decompress-threads"); + PARSE_INT(cpuThrottleInitial, "cpu-throttle-initial"); + PARSE_INT(cpuThrottleIncrement, "cpu-throttle-increment"); + PARSE_STR(tlsCreds, "tls-creds"); + PARSE_STR(tlsHostname, "tls-hostname"); + PARSE_ULONG(maxBandwidth, "max-bandwidth"); + PARSE_ULONG(downtimeLimit, "downtime-limit"); + PARSE_BOOL(blockIncremental, "block-incremental"); + PARSE_ULONG(xbzrleCacheSize, "xbzrle-cache-size"); + +#undef PARSE_SET +#undef PARSE_INT +#undef PARSE_ULONG +#undef PARSE_BOOL +#undef PARSE_STR + + return migParams; + + error: + qemuMigrationParamsFree(migParams); + return NULL; +} + + /** * qemuMigrationParamsApply * @driver: qemu driver @@ -527,28 +588,27 @@ qemuMigrationParamsFetch(virQEMUDriverPtr driver, qemuMigrationParamsPtr *migParams) { qemuDomainObjPrivatePtr priv = vm->privateData; - qemuMigrationParamsPtr params = NULL; + virJSONValuePtr jsonParams = NULL; int ret = -1; int rc; *migParams = NULL; - if (!(params = qemuMigrationParamsNew())) - return -1; - if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) goto cleanup; - rc = qemuMonitorGetMigrationParams(priv->mon, ¶ms->params); + rc = qemuMonitorGetMigrationParams(priv->mon, &jsonParams); if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0) goto cleanup; - VIR_STEAL_PTR(*migParams, params); + if (!(*migParams = qemuMigrationParamsFromJSON(jsonParams))) + goto cleanup; + ret = 0; cleanup: - qemuMigrationParamsFree(params); + virJSONValueFree(jsonParams); return ret; } diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 18b54e2da8..411ce28787 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -2622,9 +2622,20 @@ qemuMonitorSetMigrationCacheSize(qemuMonitorPtr mon, } +/** + * qemuMonitorGetMigrationParams: + * @mon: Pointer to the monitor object. + * @params: Where to store migration parameters. + * + * If QEMU does not support querying migration parameters, the function will + * set @params to NULL and return 0 (success). The caller is responsible for + * freeing @params. + * + * Returns 0 on success, -1 on error. + */ int qemuMonitorGetMigrationParams(qemuMonitorPtr mon, - qemuMonitorMigrationParamsPtr params) + virJSONValuePtr *params) { QEMU_CHECK_MONITOR_JSON(mon); diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 2bb4dbc667..261f3192f5 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -679,7 +679,7 @@ struct _qemuMonitorMigrationParams { }; int qemuMonitorGetMigrationParams(qemuMonitorPtr mon, - qemuMonitorMigrationParamsPtr params); + virJSONValuePtr *params); int qemuMonitorSetMigrationParams(qemuMonitorPtr mon, qemuMonitorMigrationParamsPtr params); diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index acc126629e..7de1ade28e 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -2774,14 +2774,13 @@ qemuMonitorJSONSetMigrationCacheSize(qemuMonitorPtr mon, int qemuMonitorJSONGetMigrationParams(qemuMonitorPtr mon, - qemuMonitorMigrationParamsPtr params) + virJSONValuePtr *params) { int ret = -1; - virJSONValuePtr result; virJSONValuePtr cmd = NULL; virJSONValuePtr reply = NULL; - memset(params, 0, sizeof(*params)); + *params = NULL; if (!(cmd = qemuMonitorJSONMakeCommand("query-migrate-parameters", NULL))) return -1; @@ -2797,51 +2796,9 @@ qemuMonitorJSONGetMigrationParams(qemuMonitorPtr mon, if (qemuMonitorJSONCheckReply(cmd, reply, VIR_JSON_TYPE_OBJECT) < 0) goto cleanup; - result = virJSONValueObjectGet(reply, "return"); - -#define PARSE_SET(API, VAR, FIELD) \ - do { \ - if (API(result, FIELD, ¶ms->VAR) == 0) \ - params->VAR ## _set = true; \ - } while (0) - -#define PARSE_INT(VAR, FIELD) \ - PARSE_SET(virJSONValueObjectGetNumberInt, VAR, FIELD) - -#define PARSE_ULONG(VAR, FIELD) \ - PARSE_SET(virJSONValueObjectGetNumberUlong, VAR, FIELD) - -#define PARSE_BOOL(VAR, FIELD) \ - PARSE_SET(virJSONValueObjectGetBoolean, VAR, FIELD) - -#define PARSE_STR(VAR, FIELD) \ - do { \ - const char *str; \ - if ((str = virJSONValueObjectGetString(result, FIELD))) { \ - if (VIR_STRDUP(params->VAR, str) < 0) \ - goto cleanup; \ - } \ - } while (0) - - PARSE_INT(compressLevel, "compress-level"); - PARSE_INT(compressThreads, "compress-threads"); - PARSE_INT(decompressThreads, "decompress-threads"); - PARSE_INT(cpuThrottleInitial, "cpu-throttle-initial"); - PARSE_INT(cpuThrottleIncrement, "cpu-throttle-increment"); - PARSE_STR(tlsCreds, "tls-creds"); - PARSE_STR(tlsHostname, "tls-hostname"); - PARSE_ULONG(maxBandwidth, "max-bandwidth"); - PARSE_ULONG(downtimeLimit, "downtime-limit"); - PARSE_BOOL(blockIncremental, "block-incremental"); - PARSE_ULONG(xbzrleCacheSize, "xbzrle-cache-size"); - -#undef PARSE_SET -#undef PARSE_INT -#undef PARSE_ULONG -#undef PARSE_BOOL -#undef PARSE_STR - + *params = virJSONValueObjectStealObject(reply, "return"); ret = 0; + cleanup: virJSONValueFree(cmd); virJSONValueFree(reply); diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index a73e98815c..a52f0a1955 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -135,7 +135,7 @@ int qemuMonitorJSONSetMigrationCacheSize(qemuMonitorPtr mon, unsigned long long cacheSize); int qemuMonitorJSONGetMigrationParams(qemuMonitorPtr mon, - qemuMonitorMigrationParamsPtr params); + virJSONValuePtr *params); int qemuMonitorJSONSetMigrationParams(qemuMonitorPtr mon, qemuMonitorMigrationParamsPtr params); -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:42PM +0200, Jiri Denemark wrote:
We want to have all migration parameters parsing and formatting at once place, i.e., in qemu_migration_params.c.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 74 +++++++++++++++++++++++++++++--- src/qemu/qemu_monitor.c | 13 +++++- src/qemu/qemu_monitor.h | 2 +- src/qemu/qemu_monitor_json.c | 51 ++-------------------- src/qemu/qemu_monitor_json.h | 2 +- 5 files changed, 85 insertions(+), 57 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

We want to have all migration parameters parsing and formatting at one place, i.e., in qemu_migration_params.c. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 68 +++++++++++++++++++++++++++++++- src/qemu/qemu_monitor.c | 35 ++++++++-------- src/qemu/qemu_monitor.h | 2 +- src/qemu/qemu_monitor_json.c | 56 ++------------------------ src/qemu/qemu_monitor_json.h | 2 +- 5 files changed, 90 insertions(+), 73 deletions(-) diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 845234c34b..560c2d3ea5 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -375,6 +375,61 @@ qemuMigrationParamsFromJSON(virJSONValuePtr params) } +static virJSONValuePtr +qemuMigrationParamsToJSON(qemuMigrationParamsPtr migParams) +{ + virJSONValuePtr params = NULL; + + if (!(params = virJSONValueNewObject())) + return NULL; + +#define APPEND(VALID, API, VAR, FIELD) \ + do { \ + if (VALID && API(params, FIELD, migParams->params.VAR) < 0) \ + goto error; \ + } while (0) + +#define APPEND_INT(VAR, FIELD) \ + APPEND(migParams->params.VAR ## _set, \ + virJSONValueObjectAppendNumberInt, VAR, FIELD) + +#define APPEND_STR(VAR, FIELD) \ + APPEND(migParams->params.VAR, \ + virJSONValueObjectAppendString, VAR, FIELD) + +#define APPEND_ULONG(VAR, FIELD) \ + APPEND(migParams->params.VAR ## _set, \ + virJSONValueObjectAppendNumberUlong, VAR, FIELD) + +#define APPEND_BOOL(VAR, FIELD) \ + APPEND(migParams->params.VAR ## _set, \ + virJSONValueObjectAppendBoolean, VAR, FIELD) + + APPEND_INT(compressLevel, "compress-level"); + APPEND_INT(compressThreads, "compress-threads"); + APPEND_INT(decompressThreads, "decompress-threads"); + APPEND_INT(cpuThrottleInitial, "cpu-throttle-initial"); + APPEND_INT(cpuThrottleIncrement, "cpu-throttle-increment"); + APPEND_STR(tlsCreds, "tls-creds"); + APPEND_STR(tlsHostname, "tls-hostname"); + APPEND_ULONG(maxBandwidth, "max-bandwidth"); + APPEND_ULONG(downtimeLimit, "downtime-limit"); + APPEND_BOOL(blockIncremental, "block-incremental"); + APPEND_ULONG(xbzrleCacheSize, "xbzrle-cache-size"); + +#undef APPEND +#undef APPEND_INT +#undef APPEND_STR +#undef APPEND_ULONG + + return params; + + error: + virJSONValueFree(params); + return NULL; +} + + /** * qemuMigrationParamsApply * @driver: qemu driver @@ -394,7 +449,9 @@ qemuMigrationParamsApply(virQEMUDriverPtr driver, { qemuDomainObjPrivatePtr priv = vm->privateData; bool xbzrleCacheSize_old = false; + virJSONValuePtr params = NULL; int ret = -1; + int rc; if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) return -1; @@ -417,9 +474,16 @@ qemuMigrationParamsApply(virQEMUDriverPtr driver, migParams->params.xbzrleCacheSize_set = false; } - if (qemuMonitorSetMigrationParams(priv->mon, &migParams->params) < 0) + if (!(params = qemuMigrationParamsToJSON(migParams))) goto cleanup; + if (virJSONValueObjectKeysNumber(params) > 0) { + rc = qemuMonitorSetMigrationParams(priv->mon, params); + params = NULL; + if (rc < 0) + goto cleanup; + } + ret = 0; cleanup: @@ -429,6 +493,8 @@ qemuMigrationParamsApply(virQEMUDriverPtr driver, if (xbzrleCacheSize_old) migParams->params.xbzrleCacheSize_set = true; + virJSONValueFree(params); + return ret; } diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 411ce28787..641465f227 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -2642,29 +2642,28 @@ qemuMonitorGetMigrationParams(qemuMonitorPtr mon, return qemuMonitorJSONGetMigrationParams(mon, params); } + +/** + * qemuMonitorSetMigrationParams: + * @mon: Pointer to the monitor object. + * @params: Migration parameters. + * + * The @params object is consumed and should not be referenced by the caller + * after this function returns. + * + * Returns 0 on success, -1 on error. + */ int qemuMonitorSetMigrationParams(qemuMonitorPtr mon, - qemuMonitorMigrationParamsPtr params) + virJSONValuePtr params) { - VIR_DEBUG("compressLevel=%d:%d compressThreads=%d:%d " - "decompressThreads=%d:%d cpuThrottleInitial=%d:%d " - "cpuThrottleIncrement=%d:%d tlsCreds=%s tlsHostname=%s " - "maxBandwidth=%d:%llu downtimeLimit=%d:%llu " - "blockIncremental=%d:%d xbzrleCacheSize=%d:%llu", - params->compressLevel_set, params->compressLevel, - params->compressThreads_set, params->compressThreads, - params->decompressThreads_set, params->decompressThreads, - params->cpuThrottleInitial_set, params->cpuThrottleInitial, - params->cpuThrottleIncrement_set, params->cpuThrottleIncrement, - NULLSTR(params->tlsCreds), NULLSTR(params->tlsHostname), - params->maxBandwidth_set, params->maxBandwidth, - params->downtimeLimit_set, params->downtimeLimit, - params->blockIncremental_set, params->blockIncremental, - params->xbzrleCacheSize_set, params->xbzrleCacheSize); - - QEMU_CHECK_MONITOR_JSON(mon); + QEMU_CHECK_MONITOR_JSON_GOTO(mon, error); return qemuMonitorJSONSetMigrationParams(mon, params); + + error: + virJSONValueFree(params); + return -1; } diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 261f3192f5..fd3c767dcf 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -681,7 +681,7 @@ struct _qemuMonitorMigrationParams { int qemuMonitorGetMigrationParams(qemuMonitorPtr mon, virJSONValuePtr *params); int qemuMonitorSetMigrationParams(qemuMonitorPtr mon, - qemuMonitorMigrationParamsPtr params); + virJSONValuePtr params); typedef enum { QEMU_MONITOR_MIGRATION_STATUS_INACTIVE, diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 7de1ade28e..b00bca7d46 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -2807,11 +2807,10 @@ qemuMonitorJSONGetMigrationParams(qemuMonitorPtr mon, int qemuMonitorJSONSetMigrationParams(qemuMonitorPtr mon, - qemuMonitorMigrationParamsPtr params) + virJSONValuePtr params) { int ret = -1; virJSONValuePtr cmd = NULL; - virJSONValuePtr args = NULL; virJSONValuePtr reply = NULL; if (!(cmd = virJSONValueNewObject())) @@ -2821,56 +2820,9 @@ qemuMonitorJSONSetMigrationParams(qemuMonitorPtr mon, "migrate-set-parameters") < 0) goto cleanup; - if (!(args = virJSONValueNewObject())) + if (virJSONValueObjectAppend(cmd, "arguments", params) < 0) goto cleanup; - -#define APPEND(VALID, API, VAR, FIELD) \ - do { \ - if (VALID && API(args, FIELD, params->VAR) < 0) \ - goto cleanup; \ - } while (0) - -#define APPEND_INT(VAR, FIELD) \ - APPEND(params->VAR ## _set, \ - virJSONValueObjectAppendNumberInt, VAR, FIELD) - -#define APPEND_STR(VAR, FIELD) \ - APPEND(params->VAR, \ - virJSONValueObjectAppendString, VAR, FIELD) - -#define APPEND_ULONG(VAR, FIELD) \ - APPEND(params->VAR ## _set, \ - virJSONValueObjectAppendNumberUlong, VAR, FIELD) - -#define APPEND_BOOL(VAR, FIELD) \ - APPEND(params->VAR ## _set, \ - virJSONValueObjectAppendBoolean, VAR, FIELD) - - APPEND_INT(compressLevel, "compress-level"); - APPEND_INT(compressThreads, "compress-threads"); - APPEND_INT(decompressThreads, "decompress-threads"); - APPEND_INT(cpuThrottleInitial, "cpu-throttle-initial"); - APPEND_INT(cpuThrottleIncrement, "cpu-throttle-increment"); - APPEND_STR(tlsCreds, "tls-creds"); - APPEND_STR(tlsHostname, "tls-hostname"); - APPEND_ULONG(maxBandwidth, "max-bandwidth"); - APPEND_ULONG(downtimeLimit, "downtime-limit"); - APPEND_BOOL(blockIncremental, "block-incremental"); - APPEND_ULONG(xbzrleCacheSize, "xbzrle-cache-size"); - -#undef APPEND -#undef APPEND_INT -#undef APPEND_STR -#undef APPEND_ULONG - - if (virJSONValueObjectKeysNumber(args) == 0) { - ret = 0; - goto cleanup; - } - - if (virJSONValueObjectAppend(cmd, "arguments", args) < 0) - goto cleanup; - args = NULL; + params = NULL; if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) goto cleanup; @@ -2881,7 +2833,7 @@ qemuMonitorJSONSetMigrationParams(qemuMonitorPtr mon, ret = 0; cleanup: virJSONValueFree(cmd); - virJSONValueFree(args); + virJSONValueFree(params); virJSONValueFree(reply); return ret; } diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index a52f0a1955..5ada38b9fa 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -137,7 +137,7 @@ int qemuMonitorJSONSetMigrationCacheSize(qemuMonitorPtr mon, int qemuMonitorJSONGetMigrationParams(qemuMonitorPtr mon, virJSONValuePtr *params); int qemuMonitorJSONSetMigrationParams(qemuMonitorPtr mon, - qemuMonitorMigrationParamsPtr params); + virJSONValuePtr params); int qemuMonitorJSONGetMigrationStats(qemuMonitorPtr mon, qemuMonitorMigrationStatsPtr stats, -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:43PM +0200, Jiri Denemark wrote:
We want to have all migration parameters parsing and formatting at one place, i.e., in qemu_migration_params.c.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 68 +++++++++++++++++++++++++++++++- src/qemu/qemu_monitor.c | 35 ++++++++-------- src/qemu/qemu_monitor.h | 2 +- src/qemu/qemu_monitor_json.c | 56 ++------------------------ src/qemu/qemu_monitor_json.h | 2 +- 5 files changed, 90 insertions(+), 73 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/Makefile.inc.am | 1 + src/qemu/qemu_migration_params.c | 5 +++-- src/qemu/qemu_migration_paramspriv.h | 31 ++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 src/qemu/qemu_migration_paramspriv.h diff --git a/src/qemu/Makefile.inc.am b/src/qemu/Makefile.inc.am index 25706ba4bc..63e7c878d1 100644 --- a/src/qemu/Makefile.inc.am +++ b/src/qemu/Makefile.inc.am @@ -35,6 +35,7 @@ QEMU_DRIVER_SOURCES = \ qemu/qemu_migration_cookie.h \ qemu/qemu_migration_params.c \ qemu/qemu_migration_params.h \ + qemu/qemu_migration_paramspriv.h \ qemu/qemu_monitor.c \ qemu/qemu_monitor.h \ qemu/qemu_monitor_text.c \ diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 560c2d3ea5..e9908cf8d4 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -30,6 +30,7 @@ #include "qemu_hotplug.h" #include "qemu_migration.h" #include "qemu_migration_params.h" +#include "qemu_migration_paramspriv.h" #include "qemu_monitor.h" #define VIR_FROM_THIS VIR_FROM_QEMU @@ -314,7 +315,7 @@ qemuMigrationParamsDump(qemuMigrationParamsPtr migParams, } -static qemuMigrationParamsPtr +qemuMigrationParamsPtr qemuMigrationParamsFromJSON(virJSONValuePtr params) { qemuMigrationParamsPtr migParams = NULL; @@ -375,7 +376,7 @@ qemuMigrationParamsFromJSON(virJSONValuePtr params) } -static virJSONValuePtr +virJSONValuePtr qemuMigrationParamsToJSON(qemuMigrationParamsPtr migParams) { virJSONValuePtr params = NULL; diff --git a/src/qemu/qemu_migration_paramspriv.h b/src/qemu/qemu_migration_paramspriv.h new file mode 100644 index 0000000000..350973b6f9 --- /dev/null +++ b/src/qemu/qemu_migration_paramspriv.h @@ -0,0 +1,31 @@ +/* + * qemu_migration_paramspriv.h: private declarations for migration parameters + * + * Copyright (C) 2006-2018 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#ifndef __QEMU_MIGRATION_PARAMSPRIV_H__ +# define __QEMU_MIGRATION_PARAMSPRIV_H__ + +virJSONValuePtr +qemuMigrationParamsToJSON(qemuMigrationParamsPtr migParams); + +qemuMigrationParamsPtr +qemuMigrationParamsFromJSON(virJSONValuePtr params); + +#endif /* __QEMU_MIGRATION_PARAMSPRIV_H__ */ -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:44PM +0200, Jiri Denemark wrote:
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/Makefile.inc.am | 1 + src/qemu/qemu_migration_params.c | 5 +++-- src/qemu/qemu_migration_paramspriv.h | 31 ++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 src/qemu/qemu_migration_paramspriv.h
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

It's no longer used by the monitor code so we can hide it inside qemu_migration_params.c. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 36 ++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor.h | 36 -------------------------------- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index e9908cf8d4..8027896c12 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -39,6 +39,42 @@ VIR_LOG_INIT("qemu.qemu_migration_params"); #define QEMU_MIGRATION_TLS_ALIAS_BASE "libvirt_migrate" +typedef struct _qemuMonitorMigrationParams qemuMonitorMigrationParams; +typedef qemuMonitorMigrationParams *qemuMonitorMigrationParamsPtr; +struct _qemuMonitorMigrationParams { + bool compressLevel_set; + int compressLevel; + + bool compressThreads_set; + int compressThreads; + + bool decompressThreads_set; + int decompressThreads; + + bool cpuThrottleInitial_set; + int cpuThrottleInitial; + + bool cpuThrottleIncrement_set; + int cpuThrottleIncrement; + + /* Value is either NULL, "", or some string. NULL indicates no support; + * whereas, some string value indicates we can support setting/clearing */ + char *tlsCreds; + char *tlsHostname; + + bool maxBandwidth_set; + unsigned long long maxBandwidth; + + bool downtimeLimit_set; + unsigned long long downtimeLimit; + + bool blockIncremental_set; + bool blockIncremental; + + bool xbzrleCacheSize_set; + unsigned long long xbzrleCacheSize; +}; + struct _qemuMigrationParams { unsigned long long compMethods; /* bit-wise OR of qemuMigrationCompressMethod */ virBitmapPtr caps; diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index fd3c767dcf..1c49cc2370 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -642,42 +642,6 @@ int qemuMonitorGetMigrationCacheSize(qemuMonitorPtr mon, int qemuMonitorSetMigrationCacheSize(qemuMonitorPtr mon, unsigned long long cacheSize); -typedef struct _qemuMonitorMigrationParams qemuMonitorMigrationParams; -typedef qemuMonitorMigrationParams *qemuMonitorMigrationParamsPtr; -struct _qemuMonitorMigrationParams { - bool compressLevel_set; - int compressLevel; - - bool compressThreads_set; - int compressThreads; - - bool decompressThreads_set; - int decompressThreads; - - bool cpuThrottleInitial_set; - int cpuThrottleInitial; - - bool cpuThrottleIncrement_set; - int cpuThrottleIncrement; - - /* Value is either NULL, "", or some string. NULL indicates no support; - * whereas, some string value indicates we can support setting/clearing */ - char *tlsCreds; - char *tlsHostname; - - bool maxBandwidth_set; - unsigned long long maxBandwidth; - - bool downtimeLimit_set; - unsigned long long downtimeLimit; - - bool blockIncremental_set; - bool blockIncremental; - - bool xbzrleCacheSize_set; - unsigned long long xbzrleCacheSize; -}; - int qemuMonitorGetMigrationParams(qemuMonitorPtr mon, virJSONValuePtr *params); int qemuMonitorSetMigrationParams(qemuMonitorPtr mon, -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:45PM +0200, Jiri Denemark wrote:
It's no longer used by the monitor code so we can hide it inside qemu_migration_params.c.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 36 ++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor.h | 36 -------------------------------- 2 files changed, 36 insertions(+), 36 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Adding support for new migration parameter requires a lot of places to be changed (most likely by copy&paste engineering): new variables to store the parameter value and the associated *_set bool, JSON formatter and parser, XML formatter and parser (to be added soon), and the actual code to set the parameter. It's pretty easy to forget about some of the places which need to be updated and end up with incorrect support. The goal of this patch is to let most of the places do their job without any modifications when new parameters are added. To achieve the goal, a new qemuMigrationParam enum is introduced and all parameters are stored in an array indexed by the items of this enum. This will also allow us to automatically set the migration parameters which directly correspond to libvirt's typed parameters accepted by virDomainMigrate* APIs. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 470 ++++++++++++++++++++----------- src/qemu/qemu_migration_params.h | 20 ++ 2 files changed, 328 insertions(+), 162 deletions(-) diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 8027896c12..77abc7191f 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -39,46 +39,29 @@ VIR_LOG_INIT("qemu.qemu_migration_params"); #define QEMU_MIGRATION_TLS_ALIAS_BASE "libvirt_migrate" -typedef struct _qemuMonitorMigrationParams qemuMonitorMigrationParams; -typedef qemuMonitorMigrationParams *qemuMonitorMigrationParamsPtr; -struct _qemuMonitorMigrationParams { - bool compressLevel_set; - int compressLevel; +typedef enum { + QEMU_MIGRATION_PARAM_TYPE_INT, + QEMU_MIGRATION_PARAM_TYPE_ULL, + QEMU_MIGRATION_PARAM_TYPE_BOOL, + QEMU_MIGRATION_PARAM_TYPE_STRING, +} qemuMigrationParamType; - bool compressThreads_set; - int compressThreads; - - bool decompressThreads_set; - int decompressThreads; - - bool cpuThrottleInitial_set; - int cpuThrottleInitial; - - bool cpuThrottleIncrement_set; - int cpuThrottleIncrement; - - /* Value is either NULL, "", or some string. NULL indicates no support; - * whereas, some string value indicates we can support setting/clearing */ - char *tlsCreds; - char *tlsHostname; - - bool maxBandwidth_set; - unsigned long long maxBandwidth; - - bool downtimeLimit_set; - unsigned long long downtimeLimit; - - bool blockIncremental_set; - bool blockIncremental; - - bool xbzrleCacheSize_set; - unsigned long long xbzrleCacheSize; +typedef struct _qemuMigrationParamValue qemuMigrationParamValue; +typedef qemuMigrationParamValue *qemuMigrationParamValuePtr; +struct _qemuMigrationParamValue { + bool set; + union { + int i; /* exempt from syntax-check */ + unsigned long long ull; + bool b; + char *s; + } value; }; struct _qemuMigrationParams { unsigned long long compMethods; /* bit-wise OR of qemuMigrationCompressMethod */ virBitmapPtr caps; - qemuMonitorMigrationParams params; + qemuMigrationParamValue params[QEMU_MIGRATION_PARAM_LAST]; }; typedef enum { @@ -93,6 +76,20 @@ VIR_ENUM_IMPL(qemuMigrationCompressMethod, QEMU_MIGRATION_COMPRESS_LAST, "mt", ); +VIR_ENUM_DECL(qemuMigrationParam) +VIR_ENUM_IMPL(qemuMigrationParam, QEMU_MIGRATION_PARAM_LAST, + "compress-level", + "compress-threads", + "decompress-threads", + "cpu-throttle-initial", + "cpu-throttle-increment", + "tls-creds", + "tls-hostname", + "max-bandwidth", + "downtime-limit", + "block-incremental", + "xbzrle-cache-size", +); typedef struct _qemuMigrationParamsAlwaysOnItem qemuMigrationParamsAlwaysOnItem; struct _qemuMigrationParamsAlwaysOnItem { @@ -129,6 +126,21 @@ static const qemuMigrationParamsFlagMapItem qemuMigrationParamsFlagMap[] = { QEMU_MIGRATION_SOURCE | QEMU_MIGRATION_DESTINATION}, }; +static const qemuMigrationParamType qemuMigrationParamTypes[] = { + [QEMU_MIGRATION_PARAM_COMPRESS_LEVEL] = QEMU_MIGRATION_PARAM_TYPE_INT, + [QEMU_MIGRATION_PARAM_COMPRESS_THREADS] = QEMU_MIGRATION_PARAM_TYPE_INT, + [QEMU_MIGRATION_PARAM_DECOMPRESS_THREADS] = QEMU_MIGRATION_PARAM_TYPE_INT, + [QEMU_MIGRATION_PARAM_THROTTLE_INITIAL] = QEMU_MIGRATION_PARAM_TYPE_INT, + [QEMU_MIGRATION_PARAM_THROTTLE_INCREMENT] = QEMU_MIGRATION_PARAM_TYPE_INT, + [QEMU_MIGRATION_PARAM_TLS_CREDS] = QEMU_MIGRATION_PARAM_TYPE_STRING, + [QEMU_MIGRATION_PARAM_TLS_HOSTNAME] = QEMU_MIGRATION_PARAM_TYPE_STRING, + [QEMU_MIGRATION_PARAM_MAX_BANDWIDTH] = QEMU_MIGRATION_PARAM_TYPE_ULL, + [QEMU_MIGRATION_PARAM_DOWNTIME_LIMIT] = QEMU_MIGRATION_PARAM_TYPE_ULL, + [QEMU_MIGRATION_PARAM_BLOCK_INCREMENTAL] = QEMU_MIGRATION_PARAM_TYPE_BOOL, + [QEMU_MIGRATION_PARAM_XBZRLE_CACHE_SIZE] = QEMU_MIGRATION_PARAM_TYPE_ULL, +}; +verify(ARRAY_CARDINALITY(qemuMigrationParamTypes) == QEMU_MIGRATION_PARAM_LAST); + static qemuMigrationParamsPtr qemuMigrationParamsNew(void) @@ -153,26 +165,120 @@ qemuMigrationParamsNew(void) void qemuMigrationParamsFree(qemuMigrationParamsPtr migParams) { + size_t i; + if (!migParams) return; + for (i = 0; i < QEMU_MIGRATION_PARAM_LAST; i++) { + if (qemuMigrationParamTypes[i] == QEMU_MIGRATION_PARAM_TYPE_STRING) + VIR_FREE(migParams->params[i].value.s); + } + virBitmapFree(migParams->caps); - VIR_FREE(migParams->params.tlsCreds); - VIR_FREE(migParams->params.tlsHostname); VIR_FREE(migParams); } -#define GET(API, PARAM, VAR) \ - do { \ - int rc; \ - if ((rc = API(params, nparams, VIR_MIGRATE_PARAM_ ## PARAM, \ - &migParams->params.VAR)) < 0) \ - goto error; \ - \ - if (rc == 1) \ - migParams->params.VAR ## _set = true; \ - } while (0) +static int +qemuMigrationParamsCheckType(qemuMigrationParam param, + qemuMigrationParamType type) +{ + if (qemuMigrationParamTypes[param] != type) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Type mismatch for '%s' migration parameter"), + qemuMigrationParamTypeToString(param)); + return -1; + } + + return 0; +} + + +static int +qemuMigrationParamsGetTPInt(qemuMigrationParamsPtr migParams, + qemuMigrationParam param, + virTypedParameterPtr params, + int nparams, + const char *name) +{ + int rc; + + if (qemuMigrationParamsCheckType(param, QEMU_MIGRATION_PARAM_TYPE_INT) < 0) + return -1; + + if (!params) + return 0; + + if ((rc = virTypedParamsGetInt(params, nparams, name, + &migParams->params[param].value.i)) < 0) + return -1; + + migParams->params[param].set = !!rc; + return 0; +} + + +static int +qemuMigrationParamsSetTPInt(qemuMigrationParamsPtr migParams, + qemuMigrationParam param, + virTypedParameterPtr *params, + int *nparams, + int *maxparams, + const char *name) +{ + if (qemuMigrationParamsCheckType(param, QEMU_MIGRATION_PARAM_TYPE_INT) < 0) + return -1; + + if (!migParams->params[param].set) + return 0; + + return virTypedParamsAddInt(params, nparams, maxparams, name, + migParams->params[param].value.i); +} + + +static int +qemuMigrationParamsGetTPULL(qemuMigrationParamsPtr migParams, + qemuMigrationParam param, + virTypedParameterPtr params, + int nparams, + const char *name) +{ + int rc; + + if (qemuMigrationParamsCheckType(param, QEMU_MIGRATION_PARAM_TYPE_ULL) < 0) + return -1; + + if (!params) + return 0; + + if ((rc = virTypedParamsGetULLong(params, nparams, name, + &migParams->params[param].value.ull)) < 0) + return -1; + + migParams->params[param].set = !!rc; + return 0; +} + + +static int +qemuMigrationParamsSetTPULL(qemuMigrationParamsPtr migParams, + qemuMigrationParam param, + virTypedParameterPtr *params, + int *nparams, + int *maxparams, + const char *name) +{ + if (qemuMigrationParamsCheckType(param, QEMU_MIGRATION_PARAM_TYPE_ULL) < 0) + return -1; + + if (!migParams->params[param].set) + return 0; + + return virTypedParamsAddULLong(params, nparams, maxparams, name, + migParams->params[param].value.ull); +} static int @@ -222,23 +328,40 @@ qemuMigrationParamsSetCompression(virTypedParameterPtr params, ignore_value(virBitmapSetBit(migParams->caps, cap)); } - if (params) { - GET(virTypedParamsGetInt, COMPRESSION_MT_LEVEL, compressLevel); - GET(virTypedParamsGetInt, COMPRESSION_MT_THREADS, compressThreads); - GET(virTypedParamsGetInt, COMPRESSION_MT_DTHREADS, decompressThreads); - GET(virTypedParamsGetULLong, COMPRESSION_XBZRLE_CACHE, xbzrleCacheSize); - } + if (qemuMigrationParamsGetTPInt(migParams, + QEMU_MIGRATION_PARAM_COMPRESS_LEVEL, + params, nparams, + VIR_MIGRATE_PARAM_COMPRESSION_MT_LEVEL) < 0) + goto error; - if ((migParams->params.compressLevel_set || - migParams->params.compressThreads_set || - migParams->params.decompressThreads_set) && + if (qemuMigrationParamsGetTPInt(migParams, + QEMU_MIGRATION_PARAM_COMPRESS_THREADS, + params, nparams, + VIR_MIGRATE_PARAM_COMPRESSION_MT_THREADS) < 0) + goto error; + + if (qemuMigrationParamsGetTPInt(migParams, + QEMU_MIGRATION_PARAM_DECOMPRESS_THREADS, + params, nparams, + VIR_MIGRATE_PARAM_COMPRESSION_MT_DTHREADS) < 0) + goto error; + + if (qemuMigrationParamsGetTPULL(migParams, + QEMU_MIGRATION_PARAM_XBZRLE_CACHE_SIZE, + params, nparams, + VIR_MIGRATE_PARAM_COMPRESSION_XBZRLE_CACHE) < 0) + goto error; + + if ((migParams->params[QEMU_MIGRATION_PARAM_COMPRESS_LEVEL].set || + migParams->params[QEMU_MIGRATION_PARAM_COMPRESS_THREADS].set || + migParams->params[QEMU_MIGRATION_PARAM_DECOMPRESS_THREADS].set) && !(migParams->compMethods & (1ULL << QEMU_MIGRATION_COMPRESS_MT))) { virReportError(VIR_ERR_INVALID_ARG, "%s", _("Turn multithread compression on to tune it")); goto error; } - if (migParams->params.xbzrleCacheSize_set && + if (migParams->params[QEMU_MIGRATION_PARAM_XBZRLE_CACHE_SIZE].set && !(migParams->compMethods & (1ULL << QEMU_MIGRATION_COMPRESS_XBZRLE))) { virReportError(VIR_ERR_INVALID_ARG, "%s", _("Turn xbzrle compression on to tune it")); @@ -281,15 +404,22 @@ qemuMigrationParamsFromFlags(virTypedParameterPtr params, } } - if (params) { - if (party == QEMU_MIGRATION_SOURCE) { - GET(virTypedParamsGetInt, AUTO_CONVERGE_INITIAL, cpuThrottleInitial); - GET(virTypedParamsGetInt, AUTO_CONVERGE_INCREMENT, cpuThrottleIncrement); - } + if (party == QEMU_MIGRATION_SOURCE) { + if (qemuMigrationParamsGetTPInt(migParams, + QEMU_MIGRATION_PARAM_THROTTLE_INITIAL, + params, nparams, + VIR_MIGRATE_PARAM_AUTO_CONVERGE_INITIAL) < 0) + goto error; + + if (qemuMigrationParamsGetTPInt(migParams, + QEMU_MIGRATION_PARAM_THROTTLE_INCREMENT, + params, nparams, + VIR_MIGRATE_PARAM_AUTO_CONVERGE_INCREMENT) < 0) + goto error; } - if ((migParams->params.cpuThrottleInitial_set || - migParams->params.cpuThrottleIncrement_set) && + if ((migParams->params[QEMU_MIGRATION_PARAM_THROTTLE_INITIAL].set || + migParams->params[QEMU_MIGRATION_PARAM_THROTTLE_INCREMENT].set) && !(flags & VIR_MIGRATE_AUTO_CONVERGE)) { virReportError(VIR_ERR_INVALID_ARG, "%s", _("Turn auto convergence on to tune it")); @@ -306,8 +436,6 @@ qemuMigrationParamsFromFlags(virTypedParameterPtr params, return NULL; } -#undef GET - int qemuMigrationParamsDump(qemuMigrationParamsPtr migParams, @@ -319,7 +447,7 @@ qemuMigrationParamsDump(qemuMigrationParamsPtr migParams, size_t i; if (migParams->compMethods == 1ULL << QEMU_MIGRATION_COMPRESS_XBZRLE && - !migParams->params.xbzrleCacheSize_set) { + !migParams->params[QEMU_MIGRATION_PARAM_XBZRLE_CACHE_SIZE].set) { *flags |= VIR_MIGRATE_COMPRESSED; return 0; } @@ -332,20 +460,29 @@ qemuMigrationParamsDump(qemuMigrationParamsPtr migParams, return -1; } -#define SET(API, PARAM, VAR) \ - do { \ - if (migParams->params.VAR ## _set && \ - API(params, nparams, maxparams, VIR_MIGRATE_PARAM_ ## PARAM, \ - migParams->params.VAR) < 0) \ - return -1; \ - } while (0) + if (qemuMigrationParamsSetTPInt(migParams, + QEMU_MIGRATION_PARAM_COMPRESS_LEVEL, + params, nparams, maxparams, + VIR_MIGRATE_PARAM_COMPRESSION_MT_LEVEL) < 0) + return -1; - SET(virTypedParamsAddInt, COMPRESSION_MT_LEVEL, compressLevel); - SET(virTypedParamsAddInt, COMPRESSION_MT_THREADS, compressThreads); - SET(virTypedParamsAddInt, COMPRESSION_MT_DTHREADS, decompressThreads); - SET(virTypedParamsAddULLong, COMPRESSION_XBZRLE_CACHE, xbzrleCacheSize); + if (qemuMigrationParamsSetTPInt(migParams, + QEMU_MIGRATION_PARAM_COMPRESS_THREADS, + params, nparams, maxparams, + VIR_MIGRATE_PARAM_COMPRESSION_MT_THREADS) < 0) + return -1; -#undef SET + if (qemuMigrationParamsSetTPInt(migParams, + QEMU_MIGRATION_PARAM_DECOMPRESS_THREADS, + params, nparams, maxparams, + VIR_MIGRATE_PARAM_COMPRESSION_MT_DTHREADS) < 0) + return -1; + + if (qemuMigrationParamsSetTPULL(migParams, + QEMU_MIGRATION_PARAM_XBZRLE_CACHE_SIZE, + params, nparams, maxparams, + VIR_MIGRATE_PARAM_COMPRESSION_XBZRLE_CACHE) < 0) + return -1; return 0; } @@ -354,7 +491,11 @@ qemuMigrationParamsDump(qemuMigrationParamsPtr migParams, qemuMigrationParamsPtr qemuMigrationParamsFromJSON(virJSONValuePtr params) { - qemuMigrationParamsPtr migParams = NULL; + qemuMigrationParamsPtr migParams; + qemuMigrationParamValuePtr pv; + const char *name; + const char *str; + size_t i; if (!(migParams = qemuMigrationParamsNew())) return NULL; @@ -362,47 +503,35 @@ qemuMigrationParamsFromJSON(virJSONValuePtr params) if (!params) return migParams; -#define PARSE_SET(API, VAR, FIELD) \ - do { \ - if (API(params, FIELD, &migParams->params.VAR) == 0) \ - migParams->params.VAR ## _set = true; \ - } while (0) + for (i = 0; i < QEMU_MIGRATION_PARAM_LAST; i++) { + name = qemuMigrationParamTypeToString(i); + pv = &migParams->params[i]; -#define PARSE_INT(VAR, FIELD) \ - PARSE_SET(virJSONValueObjectGetNumberInt, VAR, FIELD) + switch (qemuMigrationParamTypes[i]) { + case QEMU_MIGRATION_PARAM_TYPE_INT: + if (virJSONValueObjectGetNumberInt(params, name, &pv->value.i) == 0) + pv->set = true; + break; -#define PARSE_ULONG(VAR, FIELD) \ - PARSE_SET(virJSONValueObjectGetNumberUlong, VAR, FIELD) + case QEMU_MIGRATION_PARAM_TYPE_ULL: + if (virJSONValueObjectGetNumberUlong(params, name, &pv->value.ull) == 0) + pv->set = true; + break; -#define PARSE_BOOL(VAR, FIELD) \ - PARSE_SET(virJSONValueObjectGetBoolean, VAR, FIELD) + case QEMU_MIGRATION_PARAM_TYPE_BOOL: + if (virJSONValueObjectGetBoolean(params, name, &pv->value.b) == 0) + pv->set = true; + break; -#define PARSE_STR(VAR, FIELD) \ - do { \ - const char *str; \ - if ((str = virJSONValueObjectGetString(params, FIELD))) { \ - if (VIR_STRDUP(migParams->params.VAR, str) < 0) \ - goto error; \ - } \ - } while (0) - - PARSE_INT(compressLevel, "compress-level"); - PARSE_INT(compressThreads, "compress-threads"); - PARSE_INT(decompressThreads, "decompress-threads"); - PARSE_INT(cpuThrottleInitial, "cpu-throttle-initial"); - PARSE_INT(cpuThrottleIncrement, "cpu-throttle-increment"); - PARSE_STR(tlsCreds, "tls-creds"); - PARSE_STR(tlsHostname, "tls-hostname"); - PARSE_ULONG(maxBandwidth, "max-bandwidth"); - PARSE_ULONG(downtimeLimit, "downtime-limit"); - PARSE_BOOL(blockIncremental, "block-incremental"); - PARSE_ULONG(xbzrleCacheSize, "xbzrle-cache-size"); - -#undef PARSE_SET -#undef PARSE_INT -#undef PARSE_ULONG -#undef PARSE_BOOL -#undef PARSE_STR + case QEMU_MIGRATION_PARAM_TYPE_STRING: + if ((str = virJSONValueObjectGetString(params, name))) { + if (VIR_STRDUP(pv->value.s, str) < 0) + goto error; + pv->set = true; + } + break; + } + } return migParams; @@ -416,48 +545,43 @@ virJSONValuePtr qemuMigrationParamsToJSON(qemuMigrationParamsPtr migParams) { virJSONValuePtr params = NULL; + qemuMigrationParamValuePtr pv; + const char *name; + size_t i; + int rc; if (!(params = virJSONValueNewObject())) return NULL; -#define APPEND(VALID, API, VAR, FIELD) \ - do { \ - if (VALID && API(params, FIELD, migParams->params.VAR) < 0) \ - goto error; \ - } while (0) + for (i = 0; i < QEMU_MIGRATION_PARAM_LAST; i++) { + name = qemuMigrationParamTypeToString(i); + pv = &migParams->params[i]; -#define APPEND_INT(VAR, FIELD) \ - APPEND(migParams->params.VAR ## _set, \ - virJSONValueObjectAppendNumberInt, VAR, FIELD) + if (!pv->set) + continue; -#define APPEND_STR(VAR, FIELD) \ - APPEND(migParams->params.VAR, \ - virJSONValueObjectAppendString, VAR, FIELD) + rc = 0; + switch (qemuMigrationParamTypes[i]) { + case QEMU_MIGRATION_PARAM_TYPE_INT: + rc = virJSONValueObjectAppendNumberInt(params, name, pv->value.i); + break; -#define APPEND_ULONG(VAR, FIELD) \ - APPEND(migParams->params.VAR ## _set, \ - virJSONValueObjectAppendNumberUlong, VAR, FIELD) + case QEMU_MIGRATION_PARAM_TYPE_ULL: + rc = virJSONValueObjectAppendNumberUlong(params, name, pv->value.ull); + break; -#define APPEND_BOOL(VAR, FIELD) \ - APPEND(migParams->params.VAR ## _set, \ - virJSONValueObjectAppendBoolean, VAR, FIELD) + case QEMU_MIGRATION_PARAM_TYPE_BOOL: + rc = virJSONValueObjectAppendBoolean(params, name, pv->value.b); + break; - APPEND_INT(compressLevel, "compress-level"); - APPEND_INT(compressThreads, "compress-threads"); - APPEND_INT(decompressThreads, "decompress-threads"); - APPEND_INT(cpuThrottleInitial, "cpu-throttle-initial"); - APPEND_INT(cpuThrottleIncrement, "cpu-throttle-increment"); - APPEND_STR(tlsCreds, "tls-creds"); - APPEND_STR(tlsHostname, "tls-hostname"); - APPEND_ULONG(maxBandwidth, "max-bandwidth"); - APPEND_ULONG(downtimeLimit, "downtime-limit"); - APPEND_BOOL(blockIncremental, "block-incremental"); - APPEND_ULONG(xbzrleCacheSize, "xbzrle-cache-size"); + case QEMU_MIGRATION_PARAM_TYPE_STRING: + rc = virJSONValueObjectAppendString(params, name, pv->value.s); + break; + } -#undef APPEND -#undef APPEND_INT -#undef APPEND_STR -#undef APPEND_ULONG + if (rc < 0) + goto error; + } return params; @@ -487,6 +611,7 @@ qemuMigrationParamsApply(virQEMUDriverPtr driver, qemuDomainObjPrivatePtr priv = vm->privateData; bool xbzrleCacheSize_old = false; virJSONValuePtr params = NULL; + qemuMigrationParam xbzrle = QEMU_MIGRATION_PARAM_XBZRLE_CACHE_SIZE; int ret = -1; int rc; @@ -501,14 +626,14 @@ qemuMigrationParamsApply(virQEMUDriverPtr driver, * we need to set it via migrate-set-cache-size and tell * qemuMonitorSetMigrationParams to ignore this parameter. */ - if (migParams->params.xbzrleCacheSize_set && + if (migParams->params[xbzrle].set && (!priv->job.migParams || - !priv->job.migParams->params.xbzrleCacheSize_set)) { + !priv->job.migParams->params[xbzrle].set)) { if (qemuMonitorSetMigrationCacheSize(priv->mon, - migParams->params.xbzrleCacheSize) < 0) + migParams->params[xbzrle].value.ull) < 0) goto cleanup; xbzrleCacheSize_old = true; - migParams->params.xbzrleCacheSize_set = false; + migParams->params[xbzrle].set = false; } if (!(params = qemuMigrationParamsToJSON(migParams))) @@ -528,7 +653,7 @@ qemuMigrationParamsApply(virQEMUDriverPtr driver, ret = -1; if (xbzrleCacheSize_old) - migParams->params.xbzrleCacheSize_set = true; + migParams->params[xbzrle].set = true; virJSONValueFree(params); @@ -574,7 +699,7 @@ qemuMigrationParamsEnableTLS(virQEMUDriverPtr driver, goto error; } - if ((!priv->job.migParams->params.tlsCreds)) { + if (!priv->job.migParams->params[QEMU_MIGRATION_PARAM_TLS_CREDS].set) { virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", _("TLS migration is not supported with this " "QEMU binary")); @@ -605,8 +730,12 @@ qemuMigrationParamsEnableTLS(virQEMUDriverPtr driver, *tlsAlias, &tlsProps) < 0) goto error; - if (VIR_STRDUP(migParams->params.tlsCreds, *tlsAlias) < 0 || - VIR_STRDUP(migParams->params.tlsHostname, hostname ? hostname : "") < 0) + if (qemuMigrationParamsSetString(migParams, + QEMU_MIGRATION_PARAM_TLS_CREDS, + *tlsAlias) < 0 || + qemuMigrationParamsSetString(migParams, + QEMU_MIGRATION_PARAM_TLS_HOSTNAME, + hostname ? hostname : "") < 0) goto error; ret = 0; @@ -638,11 +767,13 @@ qemuMigrationParamsDisableTLS(virDomainObjPtr vm, { qemuDomainObjPrivatePtr priv = vm->privateData; - if (!priv->job.migParams->params.tlsCreds) + if (!priv->job.migParams->params[QEMU_MIGRATION_PARAM_TLS_CREDS].set) return 0; - if (VIR_STRDUP(migParams->params.tlsCreds, "") < 0 || - VIR_STRDUP(migParams->params.tlsHostname, "") < 0) + if (qemuMigrationParamsSetString(migParams, + QEMU_MIGRATION_PARAM_TLS_CREDS, "") < 0 || + qemuMigrationParamsSetString(migParams, + QEMU_MIGRATION_PARAM_TLS_HOSTNAME, "") < 0) return -1; return 0; @@ -667,7 +798,7 @@ qemuMigrationParamsResetTLS(virQEMUDriverPtr driver, char *secAlias = NULL; /* If QEMU does not support TLS migration we didn't set the aliases. */ - if (!origParams->params.tlsCreds) + if (!origParams->params[QEMU_MIGRATION_PARAM_TLS_CREDS].set) return; /* NB: If either or both fail to allocate memory we can still proceed @@ -716,6 +847,21 @@ qemuMigrationParamsFetch(virQEMUDriverPtr driver, } +int +qemuMigrationParamsSetString(qemuMigrationParamsPtr migParams, + qemuMigrationParam param, + const char *value) +{ + if (qemuMigrationParamsCheckType(param, QEMU_MIGRATION_PARAM_TYPE_STRING) < 0) + return -1; + + if (VIR_STRDUP(migParams->params[param].value.s, value) < 0) + return -1; + + return 0; +} + + /** * Returns 0 on success, * 1 if the parameter is not supported by QEMU. @@ -724,10 +870,10 @@ int qemuMigrationParamsGetDowntimeLimit(qemuMigrationParamsPtr migParams, unsigned long long *value) { - if (!migParams->params.downtimeLimit_set) + if (!migParams->params[QEMU_MIGRATION_PARAM_DOWNTIME_LIMIT].set) return 1; - *value = migParams->params.downtimeLimit; + *value = migParams->params[QEMU_MIGRATION_PARAM_DOWNTIME_LIMIT].value.ull; return 0; } diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index cc9a14601b..76b26a50d4 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -27,6 +27,21 @@ # include "qemu_monitor.h" # include "qemu_conf.h" +typedef enum { + QEMU_MIGRATION_PARAM_COMPRESS_LEVEL, + QEMU_MIGRATION_PARAM_COMPRESS_THREADS, + QEMU_MIGRATION_PARAM_DECOMPRESS_THREADS, + QEMU_MIGRATION_PARAM_THROTTLE_INITIAL, + QEMU_MIGRATION_PARAM_THROTTLE_INCREMENT, + QEMU_MIGRATION_PARAM_TLS_CREDS, + QEMU_MIGRATION_PARAM_TLS_HOSTNAME, + QEMU_MIGRATION_PARAM_MAX_BANDWIDTH, + QEMU_MIGRATION_PARAM_DOWNTIME_LIMIT, + QEMU_MIGRATION_PARAM_BLOCK_INCREMENTAL, + QEMU_MIGRATION_PARAM_XBZRLE_CACHE_SIZE, + + QEMU_MIGRATION_PARAM_LAST +} qemuMigrationParam; typedef struct _qemuMigrationParams qemuMigrationParams; typedef qemuMigrationParams *qemuMigrationParamsPtr; @@ -79,6 +94,11 @@ qemuMigrationParamsFetch(virQEMUDriverPtr driver, int asyncJob, qemuMigrationParamsPtr *migParams); +int +qemuMigrationParamsSetString(qemuMigrationParamsPtr migParams, + qemuMigrationParam param, + const char *value); + int qemuMigrationParamsGetDowntimeLimit(qemuMigrationParamsPtr migParams, unsigned long long *value); -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:46PM +0200, Jiri Denemark wrote:
Adding support for new migration parameter requires a lot of places to be changed (most likely by copy&paste engineering): new variables to store the parameter value and the associated *_set bool, JSON formatter and parser, XML formatter and parser (to be added soon), and the actual code to set the parameter. It's pretty easy to forget about some of the places which need to be updated and end up with incorrect support. The goal of this patch is to let most of the places do their job without any modifications when new parameters are added.
To achieve the goal, a new qemuMigrationParam enum is introduced and all parameters are stored in an array indexed by the items of this enum. This will also allow us to automatically set the migration parameters which directly correspond to libvirt's typed parameters accepted by virDomainMigrate* APIs.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 470 ++++++++++++++++++++----------- src/qemu/qemu_migration_params.h | 20 ++ 2 files changed, 328 insertions(+), 162 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

We want to have all migration capabilities parsing and formatting at one place, i.e., in qemu_migration_params.c. The parsing is already there in qemuMigrationCapsCheck. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 66 ++++++++++++++++++++++++++-- src/qemu/qemu_migration_paramspriv.h | 4 ++ src/qemu/qemu_monitor.c | 27 +++++++----- src/qemu/qemu_monitor.h | 3 +- src/qemu/qemu_monitor_json.c | 40 ++--------------- src/qemu/qemu_monitor_json.h | 3 +- tests/qemumonitorjsontest.c | 11 +++-- 7 files changed, 96 insertions(+), 58 deletions(-) diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 77abc7191f..548bb1c0dd 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -591,6 +591,53 @@ qemuMigrationParamsToJSON(qemuMigrationParamsPtr migParams) } +virJSONValuePtr +qemuMigrationCapsToJSON(virBitmapPtr caps, + virBitmapPtr states) +{ + virJSONValuePtr json = NULL; + virJSONValuePtr cap = NULL; + qemuMonitorMigrationCaps bit; + const char *name; + + if (!(json = virJSONValueNewArray())) + return NULL; + + for (bit = 0; bit < QEMU_MONITOR_MIGRATION_CAPS_LAST; bit++) { + bool supported = false; + bool state = false; + + ignore_value(virBitmapGetBit(caps, bit, &supported)); + if (!supported) + continue; + + ignore_value(virBitmapGetBit(states, bit, &state)); + + if (!(cap = virJSONValueNewObject())) + goto error; + + name = qemuMonitorMigrationCapsTypeToString(bit); + if (virJSONValueObjectAppendString(cap, "capability", name) < 0) + goto error; + + if (virJSONValueObjectAppendBoolean(cap, "state", state) < 0) + goto error; + + if (virJSONValueArrayAppend(json, cap) < 0) + goto error; + + cap = NULL; + } + + return json; + + error: + virJSONValueFree(json); + virJSONValueFree(cap); + return NULL; +} + + /** * qemuMigrationParamsApply * @driver: qemu driver @@ -611,6 +658,7 @@ qemuMigrationParamsApply(virQEMUDriverPtr driver, qemuDomainObjPrivatePtr priv = vm->privateData; bool xbzrleCacheSize_old = false; virJSONValuePtr params = NULL; + virJSONValuePtr caps = NULL; qemuMigrationParam xbzrle = QEMU_MIGRATION_PARAM_XBZRLE_CACHE_SIZE; int ret = -1; int rc; @@ -618,10 +666,16 @@ qemuMigrationParamsApply(virQEMUDriverPtr driver, if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) return -1; - if (qemuMonitorSetMigrationCapabilities(priv->mon, priv->migrationCaps, - migParams->caps) < 0) + if (!(caps = qemuMigrationCapsToJSON(priv->migrationCaps, migParams->caps))) goto cleanup; + if (virJSONValueArraySize(caps) > 0) { + rc = qemuMonitorSetMigrationCapabilities(priv->mon, caps); + caps = NULL; + if (rc < 0) + goto cleanup; + } + /* If QEMU is too old to support xbzrle-cache-size migration parameter, * we need to set it via migrate-set-cache-size and tell * qemuMonitorSetMigrationParams to ignore this parameter. @@ -974,6 +1028,7 @@ qemuMigrationCapsCheck(virQEMUDriverPtr driver, { qemuDomainObjPrivatePtr priv = vm->privateData; virBitmapPtr migEvent = NULL; + virJSONValuePtr json = NULL; char **caps = NULL; char **capStr; int ret = -1; @@ -1014,10 +1069,14 @@ qemuMigrationCapsCheck(virQEMUDriverPtr driver, ignore_value(virBitmapSetBit(migEvent, QEMU_MONITOR_MIGRATION_CAPS_EVENTS)); + if (!(json = qemuMigrationCapsToJSON(migEvent, migEvent))) + goto cleanup; + if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) goto cleanup; - rc = qemuMonitorSetMigrationCapabilities(priv->mon, migEvent, migEvent); + rc = qemuMonitorSetMigrationCapabilities(priv->mon, json); + json = NULL; if (qemuDomainObjExitMonitor(driver, vm) < 0) goto cleanup; @@ -1039,6 +1098,7 @@ qemuMigrationCapsCheck(virQEMUDriverPtr driver, ret = 0; cleanup: + virJSONValueFree(json); virStringListFree(caps); return ret; } diff --git a/src/qemu/qemu_migration_paramspriv.h b/src/qemu/qemu_migration_paramspriv.h index 350973b6f9..30773a679d 100644 --- a/src/qemu/qemu_migration_paramspriv.h +++ b/src/qemu/qemu_migration_paramspriv.h @@ -28,4 +28,8 @@ qemuMigrationParamsToJSON(qemuMigrationParamsPtr migParams); qemuMigrationParamsPtr qemuMigrationParamsFromJSON(virJSONValuePtr params); +virJSONValuePtr +qemuMigrationCapsToJSON(virBitmapPtr caps, + virBitmapPtr states); + #endif /* __QEMU_MIGRATION_PARAMSPRIV_H__ */ diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 641465f227..13d885ffc5 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -3988,22 +3988,27 @@ qemuMonitorGetMigrationCapabilities(qemuMonitorPtr mon, } +/** + * qemuMonitorSetMigrationCapabilities: + * @mon: Pointer to the monitor object. + * @caps: Migration capabilities. + * + * The @caps object is consumed and should not be referenced by the caller + * after this function returns. + * + * Returns 0 on success, -1 on error. + */ int qemuMonitorSetMigrationCapabilities(qemuMonitorPtr mon, - virBitmapPtr caps, - virBitmapPtr states) + virJSONValuePtr caps) { - char *capsStr = virBitmapFormat(caps); - char *statesStr = virBitmapFormat(states); + QEMU_CHECK_MONITOR_JSON_GOTO(mon, error); - VIR_DEBUG("caps=%s, states=%s", NULLSTR(capsStr), NULLSTR(statesStr)); + return qemuMonitorJSONSetMigrationCapabilities(mon, caps); - VIR_FREE(capsStr); - VIR_FREE(statesStr); - - QEMU_CHECK_MONITOR_JSON(mon); - - return qemuMonitorJSONSetMigrationCapabilities(mon, caps, states); + error: + virJSONValueFree(caps); + return -1; } diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 1c49cc2370..4ab0206713 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -728,8 +728,7 @@ VIR_ENUM_DECL(qemuMonitorMigrationCaps); int qemuMonitorGetMigrationCapabilities(qemuMonitorPtr mon, char ***capabilities); int qemuMonitorSetMigrationCapabilities(qemuMonitorPtr mon, - virBitmapPtr caps, - virBitmapPtr states); + virJSONValuePtr caps); int qemuMonitorGetGICCapabilities(qemuMonitorPtr mon, virGICCapability **capabilities); diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index b00bca7d46..7fd8e756b3 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -6111,47 +6111,14 @@ qemuMonitorJSONGetMigrationCapabilities(qemuMonitorPtr mon, int qemuMonitorJSONSetMigrationCapabilities(qemuMonitorPtr mon, - virBitmapPtr caps, - virBitmapPtr states) + virJSONValuePtr caps) { int ret = -1; - qemuMonitorMigrationCaps bit; virJSONValuePtr cmd = NULL; virJSONValuePtr reply = NULL; - virJSONValuePtr cap = NULL; - virJSONValuePtr array; - - if (!(array = virJSONValueNewArray())) - goto cleanup; - - for (bit = 0; bit < QEMU_MONITOR_MIGRATION_CAPS_LAST; bit++) { - bool supported = false; - bool state = false; - - ignore_value(virBitmapGetBit(caps, bit, &supported)); - if (!supported) - continue; - - ignore_value(virBitmapGetBit(states, bit, &state)); - - if (!(cap = virJSONValueNewObject())) - goto cleanup; - - if (virJSONValueObjectAppendString(cap, "capability", - qemuMonitorMigrationCapsTypeToString(bit)) < 0) - goto cleanup; - - if (virJSONValueObjectAppendBoolean(cap, "state", state) < 0) - goto cleanup; - - if (virJSONValueArrayAppend(array, cap) < 0) - goto cleanup; - - cap = NULL; - } cmd = qemuMonitorJSONMakeCommand("migrate-set-capabilities", - "a:capabilities", &array, + "a:capabilities", &caps, NULL); if (!cmd) goto cleanup; @@ -6164,8 +6131,7 @@ qemuMonitorJSONSetMigrationCapabilities(qemuMonitorPtr mon, ret = 0; cleanup: - virJSONValueFree(array); - virJSONValueFree(cap); + virJSONValueFree(caps); virJSONValueFree(cmd); virJSONValueFree(reply); return ret; diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 5ada38b9fa..c6ad83af4c 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -146,8 +146,7 @@ int qemuMonitorJSONGetMigrationStats(qemuMonitorPtr mon, int qemuMonitorJSONGetMigrationCapabilities(qemuMonitorPtr mon, char ***capabilities); int qemuMonitorJSONSetMigrationCapabilities(qemuMonitorPtr mon, - virBitmapPtr caps, - virBitmapPtr states); + virJSONValuePtr caps); int qemuMonitorJSONGetGICCapabilities(qemuMonitorPtr mon, virGICCapability **capabilities); diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index dafcccebad..697126f298 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -32,6 +32,7 @@ #include "virstring.h" #include "cpu/cpu.h" #include "qemu/qemu_monitor.h" +#include "qemu/qemu_migration_paramspriv.h" #define VIR_FROM_THIS VIR_FROM_NONE @@ -2141,6 +2142,7 @@ testQemuMonitorJSONqemuMonitorJSONGetMigrationCapabilities(const void *data) const char *cap; char **caps = NULL; virBitmapPtr bitmap = NULL; + virJSONValuePtr json = NULL; const char *reply = "{" " \"return\": [" @@ -2176,12 +2178,15 @@ testQemuMonitorJSONqemuMonitorJSONGetMigrationCapabilities(const void *data) goto cleanup; ignore_value(virBitmapSetBit(bitmap, QEMU_MONITOR_MIGRATION_CAPS_XBZRLE)); - if (qemuMonitorJSONSetMigrationCapabilities(qemuMonitorTestGetMonitor(test), - bitmap, bitmap) < 0) + if (!(json = qemuMigrationCapsToJSON(bitmap, bitmap))) goto cleanup; - ret = 0; + ret = qemuMonitorJSONSetMigrationCapabilities(qemuMonitorTestGetMonitor(test), + json); + json = NULL; + cleanup: + virJSONValueFree(json); qemuMonitorTestFree(test); virStringListFree(caps); virBitmapFree(bitmap); -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:47PM +0200, Jiri Denemark wrote:
We want to have all migration capabilities parsing and formatting at one place, i.e., in qemu_migration_params.c. The parsing is already there in qemuMigrationCapsCheck.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 66 ++++++++++++++++++++++++++-- src/qemu/qemu_migration_paramspriv.h | 4 ++ src/qemu/qemu_monitor.c | 27 +++++++----- src/qemu/qemu_monitor.h | 3 +- src/qemu/qemu_monitor_json.c | 40 ++--------------- src/qemu/qemu_monitor_json.h | 3 +- tests/qemumonitorjsontest.c | 11 +++-- 7 files changed, 96 insertions(+), 58 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Since the monitor code no longer needs to see this enum, we move it to the place where migration parameters are defined and drop the "monitor" reference from the name. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_driver.c | 4 +- src/qemu/qemu_migration_params.c | 65 +++++++++++++++++++------------- src/qemu/qemu_migration_params.h | 15 +++++++- src/qemu/qemu_monitor.c | 5 --- src/qemu/qemu_monitor.h | 14 ------- tests/qemumonitorjsontest.c | 7 ++-- 6 files changed, 58 insertions(+), 52 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 761f84ee7f..0cf08759c6 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -13627,7 +13627,7 @@ qemuDomainMigrateGetCompressionCache(virDomainPtr dom, priv = vm->privateData; - if (!qemuMigrationCapsGet(vm, QEMU_MONITOR_MIGRATION_CAPS_XBZRLE)) { + if (!qemuMigrationCapsGet(vm, QEMU_MIGRATION_CAP_XBZRLE)) { virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", _("Compressed migration is not supported by " "QEMU binary")); @@ -13678,7 +13678,7 @@ qemuDomainMigrateSetCompressionCache(virDomainPtr dom, priv = vm->privateData; - if (!qemuMigrationCapsGet(vm, QEMU_MONITOR_MIGRATION_CAPS_XBZRLE)) { + if (!qemuMigrationCapsGet(vm, QEMU_MIGRATION_CAP_XBZRLE)) { virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", _("Compressed migration is not supported by " "QEMU binary")); diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 548bb1c0dd..2723288dfc 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -76,6 +76,17 @@ VIR_ENUM_IMPL(qemuMigrationCompressMethod, QEMU_MIGRATION_COMPRESS_LAST, "mt", ); +VIR_ENUM_IMPL(qemuMigrationCapability, QEMU_MIGRATION_CAP_LAST, + "xbzrle", + "auto-converge", + "rdma-pin-all", + "events", + "postcopy-ram", + "compress", + "pause-before-switchover", +); + + VIR_ENUM_DECL(qemuMigrationParam) VIR_ENUM_IMPL(qemuMigrationParam, QEMU_MIGRATION_PARAM_LAST, "compress-level", @@ -93,36 +104,36 @@ VIR_ENUM_IMPL(qemuMigrationParam, QEMU_MIGRATION_PARAM_LAST, typedef struct _qemuMigrationParamsAlwaysOnItem qemuMigrationParamsAlwaysOnItem; struct _qemuMigrationParamsAlwaysOnItem { - qemuMonitorMigrationCaps cap; + qemuMigrationCapability cap; int party; /* bit-wise OR of qemuMigrationParty */ }; typedef struct _qemuMigrationParamsFlagMapItem qemuMigrationParamsFlagMapItem; struct _qemuMigrationParamsFlagMapItem { virDomainMigrateFlags flag; - qemuMonitorMigrationCaps cap; + qemuMigrationCapability cap; int party; /* bit-wise OR of qemuMigrationParty */ }; /* Migration capabilities which should always be enabled as long as they * are supported by QEMU. */ static const qemuMigrationParamsAlwaysOnItem qemuMigrationParamsAlwaysOn[] = { - {QEMU_MONITOR_MIGRATION_CAPS_PAUSE_BEFORE_SWITCHOVER, + {QEMU_MIGRATION_CAP_PAUSE_BEFORE_SWITCHOVER, QEMU_MIGRATION_SOURCE}, }; -/* Translation from virDomainMigrateFlags to qemuMonitorMigrationCaps. */ +/* Translation from virDomainMigrateFlags to qemuMigrationCapability. */ static const qemuMigrationParamsFlagMapItem qemuMigrationParamsFlagMap[] = { {VIR_MIGRATE_RDMA_PIN_ALL, - QEMU_MONITOR_MIGRATION_CAPS_RDMA_PIN_ALL, + QEMU_MIGRATION_CAP_RDMA_PIN_ALL, QEMU_MIGRATION_SOURCE | QEMU_MIGRATION_DESTINATION}, {VIR_MIGRATE_AUTO_CONVERGE, - QEMU_MONITOR_MIGRATION_CAPS_AUTO_CONVERGE, + QEMU_MIGRATION_CAP_AUTO_CONVERGE, QEMU_MIGRATION_SOURCE}, {VIR_MIGRATE_POSTCOPY, - QEMU_MONITOR_MIGRATION_CAPS_POSTCOPY, + QEMU_MIGRATION_CAP_POSTCOPY, QEMU_MIGRATION_SOURCE | QEMU_MIGRATION_DESTINATION}, }; @@ -150,7 +161,7 @@ qemuMigrationParamsNew(void) if (VIR_ALLOC(params) < 0) return NULL; - params->caps = virBitmapNew(QEMU_MONITOR_MIGRATION_CAPS_LAST); + params->caps = virBitmapNew(QEMU_MIGRATION_CAP_LAST); if (!params->caps) goto error; @@ -289,7 +300,7 @@ qemuMigrationParamsSetCompression(virTypedParameterPtr params, { size_t i; int method; - qemuMonitorMigrationCaps cap; + qemuMigrationCapability cap; for (i = 0; i < nparams; i++) { if (STRNEQ(params[i].field, VIR_MIGRATE_PARAM_COMPRESSION)) @@ -314,11 +325,11 @@ qemuMigrationParamsSetCompression(virTypedParameterPtr params, switch ((qemuMigrationCompressMethod) method) { case QEMU_MIGRATION_COMPRESS_XBZRLE: - cap = QEMU_MONITOR_MIGRATION_CAPS_XBZRLE; + cap = QEMU_MIGRATION_CAP_XBZRLE; break; case QEMU_MIGRATION_COMPRESS_MT: - cap = QEMU_MONITOR_MIGRATION_CAPS_COMPRESS; + cap = QEMU_MIGRATION_CAP_COMPRESS; break; case QEMU_MIGRATION_COMPRESS_LAST: @@ -371,7 +382,7 @@ qemuMigrationParamsSetCompression(virTypedParameterPtr params, if (!migParams->compMethods && (flags & VIR_MIGRATE_COMPRESSED)) { migParams->compMethods = 1ULL << QEMU_MIGRATION_COMPRESS_XBZRLE; ignore_value(virBitmapSetBit(migParams->caps, - QEMU_MONITOR_MIGRATION_CAPS_XBZRLE)); + QEMU_MIGRATION_CAP_XBZRLE)); } return 0; @@ -394,12 +405,12 @@ qemuMigrationParamsFromFlags(virTypedParameterPtr params, return NULL; for (i = 0; i < ARRAY_CARDINALITY(qemuMigrationParamsFlagMap); i++) { - qemuMonitorMigrationCaps cap = qemuMigrationParamsFlagMap[i].cap; + qemuMigrationCapability cap = qemuMigrationParamsFlagMap[i].cap; if (qemuMigrationParamsFlagMap[i].party & party && flags & qemuMigrationParamsFlagMap[i].flag) { VIR_DEBUG("Enabling migration capability '%s'", - qemuMonitorMigrationCapsTypeToString(cap)); + qemuMigrationCapabilityTypeToString(cap)); ignore_value(virBitmapSetBit(migParams->caps, cap)); } } @@ -597,13 +608,13 @@ qemuMigrationCapsToJSON(virBitmapPtr caps, { virJSONValuePtr json = NULL; virJSONValuePtr cap = NULL; - qemuMonitorMigrationCaps bit; + qemuMigrationCapability bit; const char *name; if (!(json = virJSONValueNewArray())) return NULL; - for (bit = 0; bit < QEMU_MONITOR_MIGRATION_CAPS_LAST; bit++) { + for (bit = 0; bit < QEMU_MIGRATION_CAP_LAST; bit++) { bool supported = false; bool state = false; @@ -616,7 +627,7 @@ qemuMigrationCapsToJSON(virBitmapPtr caps, if (!(cap = virJSONValueNewObject())) goto error; - name = qemuMonitorMigrationCapsTypeToString(bit); + name = qemuMigrationCapabilityTypeToString(bit); if (virJSONValueObjectAppendString(cap, "capability", name) < 0) goto error; @@ -947,7 +958,7 @@ qemuMigrationParamsCheck(virQEMUDriverPtr driver, qemuMigrationParamsPtr migParams) { qemuDomainObjPrivatePtr priv = vm->privateData; - qemuMonitorMigrationCaps cap; + qemuMigrationCapability cap; qemuMigrationParty party; size_t i; @@ -956,7 +967,7 @@ qemuMigrationParamsCheck(virQEMUDriverPtr driver, else party = QEMU_MIGRATION_DESTINATION; - for (cap = 0; cap < QEMU_MONITOR_MIGRATION_CAPS_LAST; cap++) { + for (cap = 0; cap < QEMU_MIGRATION_CAP_LAST; cap++) { bool state = false; ignore_value(virBitmapGetBit(migParams->caps, cap, &state)); @@ -964,7 +975,7 @@ qemuMigrationParamsCheck(virQEMUDriverPtr driver, if (state && !qemuMigrationCapsGet(vm, cap)) { virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, _("Migration option '%s' is not supported by QEMU binary"), - qemuMonitorMigrationCapsTypeToString(cap)); + qemuMigrationCapabilityTypeToString(cap)); return -1; } } @@ -975,7 +986,7 @@ qemuMigrationParamsCheck(virQEMUDriverPtr driver, if (qemuMigrationParamsAlwaysOn[i].party & party && qemuMigrationCapsGet(vm, cap)) { VIR_DEBUG("Enabling migration capability '%s'", - qemuMonitorMigrationCapsTypeToString(cap)); + qemuMigrationCapabilityTypeToString(cap)); ignore_value(virBitmapSetBit(migParams->caps, cap)); } } @@ -1047,12 +1058,12 @@ qemuMigrationCapsCheck(virQEMUDriverPtr driver, goto cleanup; } - priv->migrationCaps = virBitmapNew(QEMU_MONITOR_MIGRATION_CAPS_LAST); + priv->migrationCaps = virBitmapNew(QEMU_MIGRATION_CAP_LAST); if (!priv->migrationCaps) goto cleanup; for (capStr = caps; *capStr; capStr++) { - int cap = qemuMonitorMigrationCapsTypeFromString(*capStr); + int cap = qemuMigrationCapabilityTypeFromString(*capStr); if (cap < 0) { VIR_DEBUG("Unknown migration capability: '%s'", *capStr); @@ -1063,11 +1074,11 @@ qemuMigrationCapsCheck(virQEMUDriverPtr driver, } if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT)) { - migEvent = virBitmapNew(QEMU_MONITOR_MIGRATION_CAPS_LAST); + migEvent = virBitmapNew(QEMU_MIGRATION_CAP_LAST); if (!migEvent) goto cleanup; - ignore_value(virBitmapSetBit(migEvent, QEMU_MONITOR_MIGRATION_CAPS_EVENTS)); + ignore_value(virBitmapSetBit(migEvent, QEMU_MIGRATION_CAP_EVENTS)); if (!(json = qemuMigrationCapsToJSON(migEvent, migEvent))) goto cleanup; @@ -1093,7 +1104,7 @@ qemuMigrationCapsCheck(virQEMUDriverPtr driver, * else. */ ignore_value(virBitmapClearBit(priv->migrationCaps, - QEMU_MONITOR_MIGRATION_CAPS_EVENTS)); + QEMU_MIGRATION_CAP_EVENTS)); ret = 0; @@ -1106,7 +1117,7 @@ qemuMigrationCapsCheck(virQEMUDriverPtr driver, bool qemuMigrationCapsGet(virDomainObjPtr vm, - qemuMonitorMigrationCaps cap) + qemuMigrationCapability cap) { qemuDomainObjPrivatePtr priv = vm->privateData; bool enabled = false; diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index 76b26a50d4..ceba0eb68a 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -27,6 +27,19 @@ # include "qemu_monitor.h" # include "qemu_conf.h" +typedef enum { + QEMU_MIGRATION_CAP_XBZRLE, + QEMU_MIGRATION_CAP_AUTO_CONVERGE, + QEMU_MIGRATION_CAP_RDMA_PIN_ALL, + QEMU_MIGRATION_CAP_EVENTS, + QEMU_MIGRATION_CAP_POSTCOPY, + QEMU_MIGRATION_CAP_COMPRESS, + QEMU_MIGRATION_CAP_PAUSE_BEFORE_SWITCHOVER, + + QEMU_MIGRATION_CAP_LAST +} qemuMigrationCapability; +VIR_ENUM_DECL(qemuMigrationCapability) + typedef enum { QEMU_MIGRATION_PARAM_COMPRESS_LEVEL, QEMU_MIGRATION_PARAM_COMPRESS_THREADS, @@ -122,6 +135,6 @@ qemuMigrationCapsCheck(virQEMUDriverPtr driver, bool qemuMigrationCapsGet(virDomainObjPtr vm, - qemuMonitorMigrationCaps cap); + qemuMigrationCapability cap); #endif /* __QEMU_MIGRATION_PARAMS_H__ */ diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 13d885ffc5..fe0e0431d9 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -185,11 +185,6 @@ VIR_ENUM_IMPL(qemuMonitorMigrationStatus, "completed", "failed", "cancelling", "cancelled") -VIR_ENUM_IMPL(qemuMonitorMigrationCaps, - QEMU_MONITOR_MIGRATION_CAPS_LAST, - "xbzrle", "auto-converge", "rdma-pin-all", "events", - "postcopy-ram", "compress", "pause-before-switchover") - VIR_ENUM_IMPL(qemuMonitorVMStatus, QEMU_MONITOR_VM_STATUS_LAST, "debug", "inmigrate", "internal-error", "io-error", "paused", diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 4ab0206713..c272f98121 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -711,20 +711,6 @@ int qemuMonitorGetMigrationStats(qemuMonitorPtr mon, qemuMonitorMigrationStatsPtr stats, char **error); -typedef enum { - QEMU_MONITOR_MIGRATION_CAPS_XBZRLE, - QEMU_MONITOR_MIGRATION_CAPS_AUTO_CONVERGE, - QEMU_MONITOR_MIGRATION_CAPS_RDMA_PIN_ALL, - QEMU_MONITOR_MIGRATION_CAPS_EVENTS, - QEMU_MONITOR_MIGRATION_CAPS_POSTCOPY, - QEMU_MONITOR_MIGRATION_CAPS_COMPRESS, - QEMU_MONITOR_MIGRATION_CAPS_PAUSE_BEFORE_SWITCHOVER, - - QEMU_MONITOR_MIGRATION_CAPS_LAST -} qemuMonitorMigrationCaps; - -VIR_ENUM_DECL(qemuMonitorMigrationCaps); - int qemuMonitorGetMigrationCapabilities(qemuMonitorPtr mon, char ***capabilities); int qemuMonitorSetMigrationCapabilities(qemuMonitorPtr mon, diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index 697126f298..44a7a2d444 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -32,6 +32,7 @@ #include "virstring.h" #include "cpu/cpu.h" #include "qemu/qemu_monitor.h" +#include "qemu/qemu_migration_params.h" #include "qemu/qemu_migration_paramspriv.h" #define VIR_FROM_THIS VIR_FROM_NONE @@ -2166,18 +2167,18 @@ testQemuMonitorJSONqemuMonitorJSONGetMigrationCapabilities(const void *data) &caps) < 0) goto cleanup; - cap = qemuMonitorMigrationCapsTypeToString(QEMU_MONITOR_MIGRATION_CAPS_XBZRLE); + cap = qemuMigrationCapabilityTypeToString(QEMU_MIGRATION_CAP_XBZRLE); if (!virStringListHasString((const char **) caps, cap)) { virReportError(VIR_ERR_INTERNAL_ERROR, "Expected capability %s is missing", cap); goto cleanup; } - bitmap = virBitmapNew(QEMU_MONITOR_MIGRATION_CAPS_LAST); + bitmap = virBitmapNew(QEMU_MIGRATION_CAP_LAST); if (!bitmap) goto cleanup; - ignore_value(virBitmapSetBit(bitmap, QEMU_MONITOR_MIGRATION_CAPS_XBZRLE)); + ignore_value(virBitmapSetBit(bitmap, QEMU_MIGRATION_CAP_XBZRLE)); if (!(json = qemuMigrationCapsToJSON(bitmap, bitmap))) goto cleanup; -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:48PM +0200, Jiri Denemark wrote:
Since the monitor code no longer needs to see this enum, we move it to the place where migration parameters are defined and drop the "monitor" reference from the name.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_driver.c | 4 +- src/qemu/qemu_migration_params.c | 65 +++++++++++++++++++------------- src/qemu/qemu_migration_params.h | 15 +++++++- src/qemu/qemu_monitor.c | 5 --- src/qemu/qemu_monitor.h | 14 ------- tests/qemumonitorjsontest.c | 7 ++-- 6 files changed, 58 insertions(+), 52 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Some migration capabilities may be enabled automatically, but only if both sides of migration support them. Thus we need to be able transfer the list of supported migration capabilities in migration cookie. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 15 ++-- src/qemu/qemu_migration_cookie.c | 136 ++++++++++++++++++++++++++++++- src/qemu/qemu_migration_cookie.h | 15 ++++ src/qemu/qemu_migration_params.c | 20 +++++ src/qemu/qemu_migration_params.h | 3 + 5 files changed, 183 insertions(+), 6 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 319b4d000a..f573bd3eba 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -1917,6 +1917,7 @@ qemuMigrationSrcBeginPhase(virQEMUDriverPtr driver, goto cleanup; if (qemuMigrationBakeCookie(mig, driver, vm, + QEMU_MIGRATION_SOURCE, cookieout, cookieoutlen, cookieFlags) < 0) goto cleanup; @@ -2429,8 +2430,9 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, goto stopjob; done: - if (qemuMigrationBakeCookie(mig, driver, vm, cookieout, - cookieoutlen, cookieFlags) < 0) { + if (qemuMigrationBakeCookie(mig, driver, vm, + QEMU_MIGRATION_DESTINATION, + cookieout, cookieoutlen, cookieFlags) < 0) { /* We could tear down the whole guest here, but * cookie data is (so far) non-critical, so that * seems a little harsh. We'll just warn for now. @@ -3523,8 +3525,9 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, QEMU_MIGRATION_COOKIE_STATS; if (qemuMigrationCookieAddPersistent(mig, &persistDef) < 0 || - qemuMigrationBakeCookie(mig, driver, vm, cookieout, - cookieoutlen, cookieFlags) < 0) { + qemuMigrationBakeCookie(mig, driver, vm, + QEMU_MIGRATION_SOURCE, + cookieout, cookieoutlen, cookieFlags) < 0) { VIR_WARN("Unable to encode migration cookie"); } @@ -5019,7 +5022,9 @@ qemuMigrationDstFinish(virQEMUDriverPtr driver, priv->job.completed->status = QEMU_DOMAIN_JOB_STATUS_COMPLETED; } - if (qemuMigrationBakeCookie(mig, driver, vm, cookieout, cookieoutlen, + if (qemuMigrationBakeCookie(mig, driver, vm, + QEMU_MIGRATION_DESTINATION, + cookieout, cookieoutlen, QEMU_MIGRATION_COOKIE_STATS) < 0) VIR_WARN("Unable to encode migration cookie"); diff --git a/src/qemu/qemu_migration_cookie.c b/src/qemu/qemu_migration_cookie.c index 5a1e299ca2..eca1b74d63 100644 --- a/src/qemu/qemu_migration_cookie.c +++ b/src/qemu/qemu_migration_cookie.c @@ -33,6 +33,7 @@ #include "qemu_domain.h" #include "qemu_migration_cookie.h" +#include "qemu_migration_params.h" #define VIR_FROM_THIS VIR_FROM_QEMU @@ -50,7 +51,8 @@ VIR_ENUM_IMPL(qemuMigrationCookieFlag, "memory-hotplug", "cpu-hotplug", "cpu", - "allowReboot"); + "allowReboot", + "capabilities"); static void @@ -94,6 +96,18 @@ qemuMigrationCookieNBDFree(qemuMigrationCookieNBDPtr nbd) } +static void +qemuMigrationCookieCapsFree(qemuMigrationCookieCapsPtr caps) +{ + if (!caps) + return; + + virBitmapFree(caps->supported); + virBitmapFree(caps->automatic); + VIR_FREE(caps); +} + + void qemuMigrationCookieFree(qemuMigrationCookiePtr mig) { @@ -112,6 +126,7 @@ qemuMigrationCookieFree(qemuMigrationCookiePtr mig) VIR_FREE(mig->lockDriver); VIR_FREE(mig->jobInfo); virCPUDefFree(mig->cpu); + qemuMigrationCookieCapsFree(mig->caps); VIR_FREE(mig); } @@ -550,6 +565,33 @@ qemuMigrationCookieAddAllowReboot(qemuMigrationCookiePtr mig, } +static int +qemuMigrationCookieAddCaps(qemuMigrationCookiePtr mig, + virDomainObjPtr vm, + qemuMigrationParty party) +{ + qemuDomainObjPrivatePtr priv = vm->privateData; + + qemuMigrationCookieCapsFree(mig->caps); + if (VIR_ALLOC(mig->caps) < 0) + return -1; + + if (priv->migrationCaps) + mig->caps->supported = virBitmapNewCopy(priv->migrationCaps); + else + mig->caps->supported = virBitmapNew(0); + + mig->caps->automatic = qemuMigrationParamsGetAlwaysOnCaps(party); + + if (!mig->caps->supported || !mig->caps->automatic) + return -1; + + mig->flags |= QEMU_MIGRATION_COOKIE_CAPS; + + return 0; +} + + static void qemuMigrationCookieGraphicsXMLFormat(virBufferPtr buf, qemuMigrationCookieGraphicsPtr grap) @@ -710,6 +752,33 @@ qemuMigrationCookieStatisticsXMLFormat(virBufferPtr buf, } +static void +qemuMigrationCookieCapsXMLFormat(virBufferPtr buf, + qemuMigrationCookieCapsPtr caps) +{ + qemuMigrationCapability cap; + + virBufferAddLit(buf, "<capabilities>\n"); + virBufferAdjustIndent(buf, 2); + + for (cap = 0; cap < QEMU_MIGRATION_CAP_LAST; cap++) { + bool supported = false; + bool automatic = false; + + ignore_value(virBitmapGetBit(caps->supported, cap, &supported)); + ignore_value(virBitmapGetBit(caps->automatic, cap, &automatic)); + if (supported) { + virBufferAsprintf(buf, "<cap name='%s' auto='%s'/>\n", + qemuMigrationCapabilityTypeToString(cap), + automatic ? "yes" : "no"); + } + } + + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</capabilities>\n"); +} + + static int qemuMigrationCookieXMLFormat(virQEMUDriverPtr driver, virBufferPtr buf, @@ -793,6 +862,9 @@ qemuMigrationCookieXMLFormat(virQEMUDriverPtr driver, if (mig->flags & QEMU_MIGRATION_COOKIE_ALLOW_REBOOT) qemuDomainObjPrivateXMLFormatAllowReboot(buf, mig->allowReboot); + if (mig->flags & QEMU_MIGRATION_COOKIE_CAPS) + qemuMigrationCookieCapsXMLFormat(buf, mig->caps); + virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "</qemu-migration>\n"); return 0; @@ -1067,6 +1139,59 @@ qemuMigrationCookieStatisticsXMLParse(xmlXPathContextPtr ctxt) } +static qemuMigrationCookieCapsPtr +qemuMigrationCookieCapsXMLParse(xmlXPathContextPtr ctxt) +{ + qemuMigrationCookieCapsPtr caps = NULL; + xmlNodePtr *nodes = NULL; + qemuMigrationCookieCapsPtr ret = NULL; + char *name = NULL; + char *automatic = NULL; + int cap; + size_t i; + int n; + + if (VIR_ALLOC(caps) < 0) + return NULL; + + if (!(caps->supported = virBitmapNew(QEMU_MIGRATION_CAP_LAST)) || + !(caps->automatic = virBitmapNew(QEMU_MIGRATION_CAP_LAST))) + goto cleanup; + + if ((n = virXPathNodeSet("./capabilities[1]/cap", ctxt, &nodes)) < 0) + goto cleanup; + + for (i = 0; i < n; i++) { + if (!(name = virXMLPropString(nodes[i], "name"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing migration capability name")); + goto cleanup; + } + + if ((cap = qemuMigrationCapabilityTypeFromString(name)) < 0) + VIR_DEBUG("unknown migration capability '%s'", name); + else + ignore_value(virBitmapSetBit(caps->supported, cap)); + + if ((automatic = virXMLPropString(nodes[i], "auto")) && + STREQ(automatic, "yes")) + ignore_value(virBitmapSetBit(caps->automatic, cap)); + + VIR_FREE(name); + VIR_FREE(automatic); + } + + VIR_STEAL_PTR(ret, caps); + + cleanup: + qemuMigrationCookieCapsFree(caps); + VIR_FREE(nodes); + VIR_FREE(name); + VIR_FREE(automatic); + return ret; +} + + static int qemuMigrationCookieXMLParse(qemuMigrationCookiePtr mig, virQEMUDriverPtr driver, @@ -1246,6 +1371,10 @@ qemuMigrationCookieXMLParse(qemuMigrationCookiePtr mig, qemuDomainObjPrivateXMLParseAllowReboot(ctxt, &mig->allowReboot) < 0) goto error; + if (flags & QEMU_MIGRATION_COOKIE_CAPS && + !(mig->caps = qemuMigrationCookieCapsXMLParse(ctxt))) + goto error; + virObjectUnref(caps); return 0; @@ -1286,6 +1415,7 @@ int qemuMigrationBakeCookie(qemuMigrationCookiePtr mig, virQEMUDriverPtr driver, virDomainObjPtr dom, + qemuMigrationParty party, char **cookieout, int *cookieoutlen, unsigned int flags) @@ -1329,6 +1459,10 @@ qemuMigrationBakeCookie(qemuMigrationCookiePtr mig, if (flags & QEMU_MIGRATION_COOKIE_ALLOW_REBOOT) qemuMigrationCookieAddAllowReboot(mig, dom); + if (flags & QEMU_MIGRATION_COOKIE_CAPS && + qemuMigrationCookieAddCaps(mig, dom, party) < 0) + return -1; + if (!(*cookieout = qemuMigrationCookieXMLFormatStr(driver, mig))) return -1; diff --git a/src/qemu/qemu_migration_cookie.h b/src/qemu/qemu_migration_cookie.h index 4a25511a9a..08c5de8f06 100644 --- a/src/qemu/qemu_migration_cookie.h +++ b/src/qemu/qemu_migration_cookie.h @@ -19,6 +19,8 @@ #ifndef __QEMU_MIGRATION_COOKIE_H__ # define __QEMU_MIGRATION_COOKIE_H__ +# include "qemu_migration_params.h" + typedef enum { QEMU_MIGRATION_COOKIE_FLAG_GRAPHICS, QEMU_MIGRATION_COOKIE_FLAG_LOCKSTATE, @@ -30,6 +32,7 @@ typedef enum { QEMU_MIGRATION_COOKIE_FLAG_CPU_HOTPLUG, QEMU_MIGRATION_COOKIE_FLAG_CPU, QEMU_MIGRATION_COOKIE_FLAG_ALLOW_REBOOT, + QEMU_MIGRATION_COOKIE_FLAG_CAPS, QEMU_MIGRATION_COOKIE_FLAG_LAST } qemuMigrationCookieFlags; @@ -47,6 +50,7 @@ typedef enum { QEMU_MIGRATION_COOKIE_CPU_HOTPLUG = (1 << QEMU_MIGRATION_COOKIE_FLAG_CPU_HOTPLUG), QEMU_MIGRATION_COOKIE_CPU = (1 << QEMU_MIGRATION_COOKIE_FLAG_CPU), QEMU_MIGRATION_COOKIE_ALLOW_REBOOT = (1 << QEMU_MIGRATION_COOKIE_FLAG_ALLOW_REBOOT), + QEMU_MIGRATION_COOKIE_CAPS = (1 << QEMU_MIGRATION_COOKIE_FLAG_CAPS), } qemuMigrationCookieFeatures; typedef struct _qemuMigrationCookieGraphics qemuMigrationCookieGraphics; @@ -92,6 +96,13 @@ struct _qemuMigrationCookieNBD { } *disks; }; +typedef struct _qemuMigrationCookieCaps qemuMigrationCookieCaps; +typedef qemuMigrationCookieCaps *qemuMigrationCookieCapsPtr; +struct _qemuMigrationCookieCaps { + virBitmapPtr supported; + virBitmapPtr automatic; +}; + typedef struct _qemuMigrationCookie qemuMigrationCookie; typedef qemuMigrationCookie *qemuMigrationCookiePtr; struct _qemuMigrationCookie { @@ -132,6 +143,9 @@ struct _qemuMigrationCookie { /* If flags & QEMU_MIGRATION_COOKIE_ALLOW_REBOOT */ virTristateBool allowReboot; + + /* If flags & QEMU_MIGRATION_COOKIE_CAPS */ + qemuMigrationCookieCapsPtr caps; }; @@ -139,6 +153,7 @@ int qemuMigrationBakeCookie(qemuMigrationCookiePtr mig, virQEMUDriverPtr driver, virDomainObjPtr dom, + qemuMigrationParty party, char **cookieout, int *cookieoutlen, unsigned int flags); diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 2723288dfc..1b1e5829e8 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -153,6 +153,26 @@ static const qemuMigrationParamType qemuMigrationParamTypes[] = { verify(ARRAY_CARDINALITY(qemuMigrationParamTypes) == QEMU_MIGRATION_PARAM_LAST); +virBitmapPtr +qemuMigrationParamsGetAlwaysOnCaps(qemuMigrationParty party) +{ + virBitmapPtr caps = NULL; + size_t i; + + if (!(caps = virBitmapNew(QEMU_MIGRATION_CAP_LAST))) + return NULL; + + for (i = 0; i < ARRAY_CARDINALITY(qemuMigrationParamsAlwaysOn); i++) { + if (!(qemuMigrationParamsAlwaysOn[i].party & party)) + continue; + + ignore_value(virBitmapSetBit(caps, qemuMigrationParamsAlwaysOn[i].cap)); + } + + return caps; +} + + static qemuMigrationParamsPtr qemuMigrationParamsNew(void) { diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index ceba0eb68a..75a441e1e1 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -65,6 +65,9 @@ typedef enum { } qemuMigrationParty; +virBitmapPtr +qemuMigrationParamsGetAlwaysOnCaps(qemuMigrationParty party); + qemuMigrationParamsPtr qemuMigrationParamsFromFlags(virTypedParameterPtr params, int nparams, -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:49PM +0200, Jiri Denemark wrote:
Some migration capabilities may be enabled automatically, but only if both sides of migration support them. Thus we need to be able transfer the list of supported migration capabilities in migration cookie.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 15 ++-- src/qemu/qemu_migration_cookie.c | 136 ++++++++++++++++++++++++++++++- src/qemu/qemu_migration_cookie.h | 15 ++++ src/qemu/qemu_migration_params.c | 20 +++++ src/qemu/qemu_migration_params.h | 3 + 5 files changed, 183 insertions(+), 6 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

When an always-on migration capability is supposed to be enabled on both sides of migration, each side can only enable the feature if it is enabled by the other side. Thus the source host sends a list of supported migration capabilities in the migration cookie generated in the Begin phase. The destination host consumes the list in the Prepare phase and decides what capabilities can be enabled when starting a QEMU process for incoming migration. Once done the destination sends the list of supported capabilities back to the source where it is used during the Perform phase to determine what capabilities can be automatically enabled. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 17 ++++++++++++----- src/qemu/qemu_migration_params.c | 22 ++++++++++++++++++++-- src/qemu/qemu_migration_params.h | 3 ++- 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index f573bd3eba..42194c0ea8 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -1913,6 +1913,9 @@ qemuMigrationSrcBeginPhase(virQEMUDriverPtr driver, cookieFlags |= QEMU_MIGRATION_COOKIE_ALLOW_REBOOT; + if (!(flags & VIR_MIGRATE_OFFLINE)) + cookieFlags |= QEMU_MIGRATION_COOKIE_CAPS; + if (!(mig = qemuMigrationEatCookie(driver, vm, NULL, 0, 0))) goto cleanup; @@ -2205,7 +2208,8 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, } cookieFlags = 0; } else { - cookieFlags = QEMU_MIGRATION_COOKIE_GRAPHICS; + cookieFlags = QEMU_MIGRATION_COOKIE_GRAPHICS | + QEMU_MIGRATION_COOKIE_CAPS; } if (flags & VIR_MIGRATE_POSTCOPY && @@ -2299,7 +2303,8 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, QEMU_MIGRATION_COOKIE_MEMORY_HOTPLUG | QEMU_MIGRATION_COOKIE_CPU_HOTPLUG | QEMU_MIGRATION_COOKIE_CPU | - QEMU_MIGRATION_COOKIE_ALLOW_REBOOT))) + QEMU_MIGRATION_COOKIE_ALLOW_REBOOT | + QEMU_MIGRATION_COOKIE_CAPS))) goto cleanup; if (STREQ_NULLABLE(protocol, "rdma") && @@ -2378,7 +2383,7 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, } if (qemuMigrationParamsCheck(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN, - migParams) < 0) + migParams, mig->caps->automatic) < 0) goto stopjob; /* Migrations using TLS need to add the "tls-creds-x509" object and @@ -3302,7 +3307,9 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, } mig = qemuMigrationEatCookie(driver, vm, cookiein, cookieinlen, - cookieFlags | QEMU_MIGRATION_COOKIE_GRAPHICS); + cookieFlags | + QEMU_MIGRATION_COOKIE_GRAPHICS | + QEMU_MIGRATION_COOKIE_CAPS); if (!mig) goto error; @@ -3310,7 +3317,7 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, VIR_WARN("unable to provide data for graphics client relocation"); if (qemuMigrationParamsCheck(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, - migParams) < 0) + migParams, mig->caps->automatic) < 0) goto error; if (flags & VIR_MIGRATE_TLS) { diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 1b1e5829e8..979610c3a8 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -116,7 +116,9 @@ struct _qemuMigrationParamsFlagMapItem { }; /* Migration capabilities which should always be enabled as long as they - * are supported by QEMU. */ + * are supported by QEMU. If the capability is supposed to be enabled on both + * sides of migration, it won't be enabled unless both sides support it. + */ static const qemuMigrationParamsAlwaysOnItem qemuMigrationParamsAlwaysOn[] = { {QEMU_MIGRATION_CAP_PAUSE_BEFORE_SWITCHOVER, QEMU_MIGRATION_SOURCE}, @@ -975,7 +977,8 @@ int qemuMigrationParamsCheck(virQEMUDriverPtr driver, virDomainObjPtr vm, int asyncJob, - qemuMigrationParamsPtr migParams) + qemuMigrationParamsPtr migParams, + virBitmapPtr remoteCaps) { qemuDomainObjPrivatePtr priv = vm->privateData; qemuMigrationCapability cap; @@ -1005,6 +1008,21 @@ qemuMigrationParamsCheck(virQEMUDriverPtr driver, if (qemuMigrationParamsAlwaysOn[i].party & party && qemuMigrationCapsGet(vm, cap)) { + if (qemuMigrationParamsAlwaysOn[i].party != party) { + bool remote = false; + + if (remoteCaps) + ignore_value(virBitmapGetBit(remoteCaps, cap, &remote)); + + if (!remote) { + VIR_DEBUG("Not enabling migration capability '%s'; it is " + "not supported or automatically enabled by the " + "other side of migration", + qemuMigrationCapabilityTypeToString(cap)); + continue; + } + } + VIR_DEBUG("Enabling migration capability '%s'", qemuMigrationCapabilityTypeToString(cap)); ignore_value(virBitmapSetBit(migParams->caps, cap)); diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index 75a441e1e1..eb4016806d 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -123,7 +123,8 @@ int qemuMigrationParamsCheck(virQEMUDriverPtr driver, virDomainObjPtr vm, int asyncJob, - qemuMigrationParamsPtr migParams); + qemuMigrationParamsPtr migParams, + virBitmapPtr remoteCaps); void qemuMigrationParamsReset(virQEMUDriverPtr driver, -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:50PM +0200, Jiri Denemark wrote:
When an always-on migration capability is supposed to be enabled on both sides of migration, each side can only enable the feature if it is enabled by the other side.
Thus the source host sends a list of supported migration capabilities in the migration cookie generated in the Begin phase. The destination host consumes the list in the Prepare phase and decides what capabilities can be enabled when starting a QEMU process for incoming migration. Once done the destination sends the list of supported capabilities back to the source where it is used during the Perform phase to determine what capabilities can be automatically enabled.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 17 ++++++++++++----- src/qemu/qemu_migration_params.c | 22 ++++++++++++++++++++-- src/qemu/qemu_migration_params.h | 3 ++- 3 files changed, 34 insertions(+), 8 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

The API is renamed as qemuMigrationParamsGetULL and it can be used with any migration parameter stored as unsigned long long. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_driver.c | 9 ++++++++- src/qemu/qemu_migration_params.c | 15 ++++++++++----- src/qemu/qemu_migration_params.h | 5 +++-- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 0cf08759c6..8917beae35 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -13557,6 +13557,7 @@ qemuDomainMigrateGetMaxDowntime(virDomainPtr dom, virDomainObjPtr vm; qemuMigrationParamsPtr migParams = NULL; int ret = -1; + int rc; virCheckFlags(0, -1); @@ -13579,7 +13580,13 @@ qemuDomainMigrateGetMaxDowntime(virDomainPtr dom, &migParams) < 0) goto endjob; - if (qemuMigrationParamsGetDowntimeLimit(migParams, downtime) == 1) { + if ((rc = qemuMigrationParamsGetULL(migParams, + QEMU_MIGRATION_PARAM_DOWNTIME_LIMIT, + downtime)) < 0) { + goto endjob; + } + + if (rc == 1) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("Querying migration downtime is not supported by " "QEMU binary")); diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 979610c3a8..3e131207a8 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -950,17 +950,22 @@ qemuMigrationParamsSetString(qemuMigrationParamsPtr migParams, /** - * Returns 0 on success, + * Returns -1 on error, + * 0 on success, * 1 if the parameter is not supported by QEMU. */ int -qemuMigrationParamsGetDowntimeLimit(qemuMigrationParamsPtr migParams, - unsigned long long *value) +qemuMigrationParamsGetULL(qemuMigrationParamsPtr migParams, + qemuMigrationParam param, + unsigned long long *value) { - if (!migParams->params[QEMU_MIGRATION_PARAM_DOWNTIME_LIMIT].set) + if (qemuMigrationParamsCheckType(param, QEMU_MIGRATION_PARAM_TYPE_ULL) < 0) + return -1; + + if (!migParams->params[param].set) return 1; - *value = migParams->params[QEMU_MIGRATION_PARAM_DOWNTIME_LIMIT].value.ull; + *value = migParams->params[param].value.ull; return 0; } diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index eb4016806d..6950eca8ef 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -116,8 +116,9 @@ qemuMigrationParamsSetString(qemuMigrationParamsPtr migParams, const char *value); int -qemuMigrationParamsGetDowntimeLimit(qemuMigrationParamsPtr migParams, - unsigned long long *value); +qemuMigrationParamsGetULL(qemuMigrationParamsPtr migParams, + qemuMigrationParam param, + unsigned long long *value); int qemuMigrationParamsCheck(virQEMUDriverPtr driver, -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:51PM +0200, Jiri Denemark wrote:
The API is renamed as qemuMigrationParamsGetULL and it can be used with any migration parameter stored as unsigned long long.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_driver.c | 9 ++++++++- src/qemu/qemu_migration_params.c | 15 ++++++++++----- src/qemu/qemu_migration_params.h | 5 +++-- 3 files changed, 21 insertions(+), 8 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Most QEMU migration parameters directly correspond to VIR_MIGRATE_PARAM_* typed parameters and qemuMigrationParamsFromFlags can automatically set them according to a static mapping between libvirt and QEMU parameters. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 138 +++++++++++++++++++------------ 1 file changed, 83 insertions(+), 55 deletions(-) diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 3e131207a8..78ded83ee9 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -115,6 +115,13 @@ struct _qemuMigrationParamsFlagMapItem { int party; /* bit-wise OR of qemuMigrationParty */ }; +typedef struct _qemuMigrationParamsTPMapItem qemuMigrationParamsTPMapItem; +struct _qemuMigrationParamsTPMapItem { + const char *typedParam; + qemuMigrationParam param; + int party; /* bit-wise OR of qemuMigrationParty */ +}; + /* Migration capabilities which should always be enabled as long as they * are supported by QEMU. If the capability is supposed to be enabled on both * sides of migration, it won't be enabled unless both sides support it. @@ -139,6 +146,34 @@ static const qemuMigrationParamsFlagMapItem qemuMigrationParamsFlagMap[] = { QEMU_MIGRATION_SOURCE | QEMU_MIGRATION_DESTINATION}, }; +/* Translation from VIR_MIGRATE_PARAM_* typed parameters to + * qemuMigrationParams. */ +static const qemuMigrationParamsTPMapItem qemuMigrationParamsTPMap[] = { + {VIR_MIGRATE_PARAM_AUTO_CONVERGE_INITIAL, + QEMU_MIGRATION_PARAM_THROTTLE_INITIAL, + QEMU_MIGRATION_SOURCE}, + + {VIR_MIGRATE_PARAM_AUTO_CONVERGE_INCREMENT, + QEMU_MIGRATION_PARAM_THROTTLE_INCREMENT, + QEMU_MIGRATION_SOURCE}, + + {VIR_MIGRATE_PARAM_COMPRESSION_MT_LEVEL, + QEMU_MIGRATION_PARAM_COMPRESS_LEVEL, + QEMU_MIGRATION_SOURCE | QEMU_MIGRATION_DESTINATION}, + + {VIR_MIGRATE_PARAM_COMPRESSION_MT_THREADS, + QEMU_MIGRATION_PARAM_COMPRESS_THREADS, + QEMU_MIGRATION_SOURCE | QEMU_MIGRATION_DESTINATION}, + + {VIR_MIGRATE_PARAM_COMPRESSION_MT_DTHREADS, + QEMU_MIGRATION_PARAM_DECOMPRESS_THREADS, + QEMU_MIGRATION_SOURCE | QEMU_MIGRATION_DESTINATION}, + + {VIR_MIGRATE_PARAM_COMPRESSION_XBZRLE_CACHE, + QEMU_MIGRATION_PARAM_XBZRLE_CACHE_SIZE, + QEMU_MIGRATION_SOURCE | QEMU_MIGRATION_DESTINATION}, +}; + static const qemuMigrationParamType qemuMigrationParamTypes[] = { [QEMU_MIGRATION_PARAM_COMPRESS_LEVEL] = QEMU_MIGRATION_PARAM_TYPE_INT, [QEMU_MIGRATION_PARAM_COMPRESS_THREADS] = QEMU_MIGRATION_PARAM_TYPE_INT, @@ -361,30 +396,6 @@ qemuMigrationParamsSetCompression(virTypedParameterPtr params, ignore_value(virBitmapSetBit(migParams->caps, cap)); } - if (qemuMigrationParamsGetTPInt(migParams, - QEMU_MIGRATION_PARAM_COMPRESS_LEVEL, - params, nparams, - VIR_MIGRATE_PARAM_COMPRESSION_MT_LEVEL) < 0) - goto error; - - if (qemuMigrationParamsGetTPInt(migParams, - QEMU_MIGRATION_PARAM_COMPRESS_THREADS, - params, nparams, - VIR_MIGRATE_PARAM_COMPRESSION_MT_THREADS) < 0) - goto error; - - if (qemuMigrationParamsGetTPInt(migParams, - QEMU_MIGRATION_PARAM_DECOMPRESS_THREADS, - params, nparams, - VIR_MIGRATE_PARAM_COMPRESSION_MT_DTHREADS) < 0) - goto error; - - if (qemuMigrationParamsGetTPULL(migParams, - QEMU_MIGRATION_PARAM_XBZRLE_CACHE_SIZE, - params, nparams, - VIR_MIGRATE_PARAM_COMPRESSION_XBZRLE_CACHE) < 0) - goto error; - if ((migParams->params[QEMU_MIGRATION_PARAM_COMPRESS_LEVEL].set || migParams->params[QEMU_MIGRATION_PARAM_COMPRESS_THREADS].set || migParams->params[QEMU_MIGRATION_PARAM_DECOMPRESS_THREADS].set) && @@ -437,18 +448,32 @@ qemuMigrationParamsFromFlags(virTypedParameterPtr params, } } - if (party == QEMU_MIGRATION_SOURCE) { - if (qemuMigrationParamsGetTPInt(migParams, - QEMU_MIGRATION_PARAM_THROTTLE_INITIAL, - params, nparams, - VIR_MIGRATE_PARAM_AUTO_CONVERGE_INITIAL) < 0) - goto error; + for (i = 0; i < ARRAY_CARDINALITY(qemuMigrationParamsTPMap); i++) { + const qemuMigrationParamsTPMapItem *item = &qemuMigrationParamsTPMap[i]; - if (qemuMigrationParamsGetTPInt(migParams, - QEMU_MIGRATION_PARAM_THROTTLE_INCREMENT, - params, nparams, - VIR_MIGRATE_PARAM_AUTO_CONVERGE_INCREMENT) < 0) - goto error; + if (!(item->party & party)) + continue; + + VIR_DEBUG("Setting migration parameter '%s' from '%s'", + qemuMigrationParamTypeToString(item->param), item->typedParam); + + switch (qemuMigrationParamTypes[item->param]) { + case QEMU_MIGRATION_PARAM_TYPE_INT: + if (qemuMigrationParamsGetTPInt(migParams, item->param, params, + nparams, item->typedParam) < 0) + goto error; + break; + + case QEMU_MIGRATION_PARAM_TYPE_ULL: + if (qemuMigrationParamsGetTPULL(migParams, item->param, params, + nparams, item->typedParam) < 0) + goto error; + break; + + case QEMU_MIGRATION_PARAM_TYPE_BOOL: + case QEMU_MIGRATION_PARAM_TYPE_STRING: + break; + } } if ((migParams->params[QEMU_MIGRATION_PARAM_THROTTLE_INITIAL].set || @@ -493,29 +518,32 @@ qemuMigrationParamsDump(qemuMigrationParamsPtr migParams, return -1; } - if (qemuMigrationParamsSetTPInt(migParams, - QEMU_MIGRATION_PARAM_COMPRESS_LEVEL, - params, nparams, maxparams, - VIR_MIGRATE_PARAM_COMPRESSION_MT_LEVEL) < 0) - return -1; + for (i = 0; i < ARRAY_CARDINALITY(qemuMigrationParamsTPMap); i++) { + const qemuMigrationParamsTPMapItem *item = &qemuMigrationParamsTPMap[i]; - if (qemuMigrationParamsSetTPInt(migParams, - QEMU_MIGRATION_PARAM_COMPRESS_THREADS, - params, nparams, maxparams, - VIR_MIGRATE_PARAM_COMPRESSION_MT_THREADS) < 0) - return -1; + if (!(item->party & QEMU_MIGRATION_DESTINATION)) + continue; - if (qemuMigrationParamsSetTPInt(migParams, - QEMU_MIGRATION_PARAM_DECOMPRESS_THREADS, - params, nparams, maxparams, - VIR_MIGRATE_PARAM_COMPRESSION_MT_DTHREADS) < 0) - return -1; + switch (qemuMigrationParamTypes[item->param]) { + case QEMU_MIGRATION_PARAM_TYPE_INT: + if (qemuMigrationParamsSetTPInt(migParams, item->param, + params, nparams, maxparams, + item->typedParam) < 0) + return -1; + break; - if (qemuMigrationParamsSetTPULL(migParams, - QEMU_MIGRATION_PARAM_XBZRLE_CACHE_SIZE, - params, nparams, maxparams, - VIR_MIGRATE_PARAM_COMPRESSION_XBZRLE_CACHE) < 0) - return -1; + case QEMU_MIGRATION_PARAM_TYPE_ULL: + if (qemuMigrationParamsSetTPULL(migParams, item->param, + params, nparams, maxparams, + item->typedParam) < 0) + return -1; + break; + + case QEMU_MIGRATION_PARAM_TYPE_BOOL: + case QEMU_MIGRATION_PARAM_TYPE_STRING: + break; + } + } return 0; } -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:52PM +0200, Jiri Denemark wrote:
Most QEMU migration parameters directly correspond to VIR_MIGRATE_PARAM_* typed parameters and qemuMigrationParamsFromFlags can automatically set them according to a static mapping between libvirt and QEMU parameters.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 138 +++++++++++++++++++------------ 1 file changed, 83 insertions(+), 55 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

To be able to restore all migration parameters when libvirtd is restarting during an active migration job, we need to store the original values of all parameters (stored in priv->job.migParams) in the status XML. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_domain.c | 7 ++ src/qemu/qemu_migration_params.c | 145 +++++++++++++++++++++++++++++++ src/qemu/qemu_migration_params.h | 10 +++ 3 files changed, 162 insertions(+) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 03ad8d35c0..e3f58e45cb 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -32,6 +32,7 @@ #include "qemu_parse_command.h" #include "qemu_capabilities.h" #include "qemu_migration.h" +#include "qemu_migration_params.h" #include "qemu_security.h" #include "viralloc.h" #include "virlog.h" @@ -2099,6 +2100,9 @@ qemuDomainObjPrivateXMLFormatJob(virBufferPtr buf, } } + if (priv->job.migParams) + qemuMigrationParamsFormat(&childBuf, priv->job.migParams); + return virXMLFormatElement(buf, "job", &attrBuf, &childBuf); } @@ -2398,6 +2402,9 @@ qemuDomainObjPrivateXMLParseJob(virDomainObjPtr vm, } VIR_FREE(nodes); + if (qemuMigrationParamsParse(ctxt, &priv->job.migParams) < 0) + goto cleanup; + ret = 0; cleanup: diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 78ded83ee9..8af6d8ad0e 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -1103,6 +1103,151 @@ qemuMigrationParamsReset(virQEMUDriverPtr driver, } +void +qemuMigrationParamsFormat(virBufferPtr buf, + qemuMigrationParamsPtr migParams) +{ + qemuMigrationParamValuePtr pv; + size_t i; + + virBufferAddLit(buf, "<migParams>\n"); + virBufferAdjustIndent(buf, 2); + + for (i = 0; i < QEMU_MIGRATION_PARAM_LAST; i++) { + pv = &migParams->params[i]; + + if (!pv->set) + continue; + + virBufferAsprintf(buf, "<param name='%s' ", + qemuMigrationParamTypeToString(i)); + + switch (qemuMigrationParamTypes[i]) { + case QEMU_MIGRATION_PARAM_TYPE_INT: + virBufferAsprintf(buf, "value='%d'", pv->value.i); + break; + + case QEMU_MIGRATION_PARAM_TYPE_ULL: + virBufferAsprintf(buf, "value='%llu'", pv->value.ull); + break; + + case QEMU_MIGRATION_PARAM_TYPE_BOOL: + virBufferAsprintf(buf, "value='%s'", pv->value.b ? "yes" : "no"); + break; + + case QEMU_MIGRATION_PARAM_TYPE_STRING: + virBufferEscapeString(buf, "value='%s'", pv->value.s); + break; + } + + virBufferAddLit(buf, "/>\n"); + } + + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</migParams>\n"); +} + + +int +qemuMigrationParamsParse(xmlXPathContextPtr ctxt, + qemuMigrationParamsPtr *migParams) +{ + qemuMigrationParamsPtr params = NULL; + qemuMigrationParamValuePtr pv; + xmlNodePtr *nodes = NULL; + char *name = NULL; + char *value = NULL; + int param; + size_t i; + int rc; + int n; + int ret = -1; + + *migParams = NULL; + + if ((rc = virXPathBoolean("boolean(./migParams)", ctxt)) < 0) + goto cleanup; + + if (rc == 0) { + ret = 0; + goto cleanup; + } + + if ((n = virXPathNodeSet("./migParams[1]/param", ctxt, &nodes)) < 0) + return -1; + + if (!(params = qemuMigrationParamsNew())) + goto cleanup; + + for (i = 0; i < n; i++) { + if (!(name = virXMLPropString(nodes[i], "name"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing migration parameter name")); + goto cleanup; + } + + if ((param = qemuMigrationParamTypeFromString(name)) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("unknown migration parameter '%s'"), name); + goto cleanup; + } + pv = ¶ms->params[param]; + + if (!(value = virXMLPropString(nodes[i], "value"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("missing value for migration parameter '%s'"), + name); + goto cleanup; + } + + rc = 0; + switch (qemuMigrationParamTypes[param]) { + case QEMU_MIGRATION_PARAM_TYPE_INT: + rc = virStrToLong_i(value, NULL, 10, &pv->value.i); + break; + + case QEMU_MIGRATION_PARAM_TYPE_ULL: + rc = virStrToLong_ullp(value, NULL, 10, &pv->value.ull); + break; + + case QEMU_MIGRATION_PARAM_TYPE_BOOL: + if (STREQ(value, "yes")) + pv->value.b = true; + else if (STREQ(value, "no")) + pv->value.b = false; + else + rc = -1; + break; + + case QEMU_MIGRATION_PARAM_TYPE_STRING: + VIR_STEAL_PTR(pv->value.s, value); + break; + } + + if (rc < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("invalid value '%s' for migration parameter '%s'"), + value, name); + goto cleanup; + } + + pv->set = true; + VIR_FREE(name); + VIR_FREE(value); + } + + VIR_STEAL_PTR(*migParams, params); + ret = 0; + + cleanup: + qemuMigrationParamsFree(params); + VIR_FREE(nodes); + VIR_FREE(name); + VIR_FREE(value); + return ret; +} + + int qemuMigrationCapsCheck(virQEMUDriverPtr driver, virDomainObjPtr vm, diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index 6950eca8ef..99dde0ad3c 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -24,6 +24,8 @@ # include "internal.h" +# include "virbuffer.h" +# include "virxml.h" # include "qemu_monitor.h" # include "qemu_conf.h" @@ -133,6 +135,14 @@ qemuMigrationParamsReset(virQEMUDriverPtr driver, int asyncJob, qemuMigrationParamsPtr origParams); +void +qemuMigrationParamsFormat(virBufferPtr buf, + qemuMigrationParamsPtr migParams); + +int +qemuMigrationParamsParse(xmlXPathContextPtr ctxt, + qemuMigrationParamsPtr *migParams); + int qemuMigrationCapsCheck(virQEMUDriverPtr driver, virDomainObjPtr vm, -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:53PM +0200, Jiri Denemark wrote:
To be able to restore all migration parameters when libvirtd is restarting during an active migration job, we need to store the original values of all parameters (stored in priv->job.migParams) in the status XML.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_domain.c | 7 ++ src/qemu/qemu_migration_params.c | 145 +++++++++++++++++++++++++++++++ src/qemu/qemu_migration_params.h | 10 +++ 3 files changed, 162 insertions(+)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

This is an enhanced replacement for the original test from qemumonitorjsontest which was dropped earlier in this series. More data files with some real data will be added in the following patches. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- tests/Makefile.am | 12 ++ tests/qemumigparamsdata/unsupported.json | 3 + tests/qemumigparamsdata/unsupported.reply | 7 + tests/qemumigparamsdata/unsupported.xml | 4 + tests/qemumigparamstest.c | 237 ++++++++++++++++++++++ 5 files changed, 263 insertions(+) create mode 100644 tests/qemumigparamsdata/unsupported.json create mode 100644 tests/qemumigparamsdata/unsupported.reply create mode 100644 tests/qemumigparamsdata/unsupported.xml create mode 100644 tests/qemumigparamstest.c diff --git a/tests/Makefile.am b/tests/Makefile.am index a4f231d2a7..2c0d1311c2 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -124,6 +124,7 @@ EXTRA_DIST = \ qemuhotplugtestcpus \ qemuhotplugtestdevices \ qemuhotplugtestdomains \ + qemumigparamsdata \ qemumonitorjsondata \ qemuxml2argvdata \ qemuxml2startupxmloutdata \ @@ -284,6 +285,7 @@ test_programs += qemuxml2argvtest qemuxml2xmltest \ qemumemlocktest \ qemucommandutiltest \ qemublocktest \ + qemumigparamstest \ $(NULL) test_helpers += qemucapsprobe test_libraries += libqemumonitortestutils.la \ @@ -670,6 +672,15 @@ qemumemlocktest_SOURCES = \ testutilsqemu.c testutilsqemu.h \ testutils.c testutils.h qemumemlocktest_LDADD = $(qemu_LDADDS) $(LDADDS) + +qemumigparamstest_SOURCES = \ + qemumigparamstest.c \ + testutils.c testutils.h \ + testutilsqemu.c testutilsqemu.h \ + $(NULL) +qemumigparamstest_LDADD = libqemumonitortestutils.la \ + $(qemu_LDADDS) $(LDADDS) + else ! WITH_QEMU EXTRA_DIST += qemuxml2argvtest.c qemuxml2xmltest.c qemuargv2xmltest.c \ domainsnapshotxml2xmltest.c \ @@ -680,6 +691,7 @@ EXTRA_DIST += qemuxml2argvtest.c qemuxml2xmltest.c qemuargv2xmltest.c \ qemucaps2xmltest.c qemucommandutiltest.c \ qemumemlocktest.c qemucpumock.c testutilshostcpus.h \ qemublocktest.c \ + qemumigparamstest.c \ $(QEMUMONITORTESTUTILS_SOURCES) endif ! WITH_QEMU diff --git a/tests/qemumigparamsdata/unsupported.json b/tests/qemumigparamsdata/unsupported.json new file mode 100644 index 0000000000..0db3279e44 --- /dev/null +++ b/tests/qemumigparamsdata/unsupported.json @@ -0,0 +1,3 @@ +{ + +} diff --git a/tests/qemumigparamsdata/unsupported.reply b/tests/qemumigparamsdata/unsupported.reply new file mode 100644 index 0000000000..2b88ba10c3 --- /dev/null +++ b/tests/qemumigparamsdata/unsupported.reply @@ -0,0 +1,7 @@ +{ + "id": "libvirt-1", + "error": { + "class": "CommandNotFound", + "desc": "The command query-migrate-parameters has not been found" + } +} diff --git a/tests/qemumigparamsdata/unsupported.xml b/tests/qemumigparamsdata/unsupported.xml new file mode 100644 index 0000000000..8aa3abefc0 --- /dev/null +++ b/tests/qemumigparamsdata/unsupported.xml @@ -0,0 +1,4 @@ +<test> + <migParams> + </migParams> +</test> diff --git a/tests/qemumigparamstest.c b/tests/qemumigparamstest.c new file mode 100644 index 0000000000..4cc27bcf52 --- /dev/null +++ b/tests/qemumigparamstest.c @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2011-2013 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include <config.h> + +#include "virjson.h" +#include "virbuffer.h" +#include "virxml.h" +#include "testutils.h" +#include "testutilsqemu.h" +#include "qemumonitortestutils.h" +#include "qemu/qemu_migration_params.h" +#include "qemu/qemu_migration_paramspriv.h" +#include "qemu/qemu_monitor.h" + +#define VIR_FROM_THIS VIR_FROM_NONE + +typedef struct _qemuMigParamsData qemuMigParamsData; +struct _qemuMigParamsData { + virDomainXMLOptionPtr xmlopt; + const char *name; +}; + + +static void +qemuMigParamsTestFormatXML(virBufferPtr buf, + qemuMigrationParamsPtr migParams) +{ + virBufferAddLit(buf, "<test>\n"); + virBufferAdjustIndent(buf, 2); + + if (migParams) + qemuMigrationParamsFormat(buf, migParams); + + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</test>\n"); +} + + +static int +qemuMigParamsTestXML2XML(const void *opaque) +{ + const qemuMigParamsData *data = opaque; + virBuffer buf = VIR_BUFFER_INITIALIZER; + char *xmlFile = NULL; + xmlDocPtr doc = NULL; + xmlXPathContextPtr ctxt = NULL; + qemuMigrationParamsPtr migParams = NULL; + char *actualXML = NULL; + int ret = -1; + + if (virAsprintf(&xmlFile, "%s/qemumigparamsdata/%s.xml", + abs_srcdir, data->name) < 0) + goto cleanup; + + if (!(doc = virXMLParseFileCtxt(xmlFile, &ctxt))) + goto cleanup; + + if (qemuMigrationParamsParse(ctxt, &migParams) < 0) + goto cleanup; + + qemuMigParamsTestFormatXML(&buf, migParams); + + if (!(actualXML = virBufferContentAndReset(&buf))) + goto cleanup; + + if (virTestCompareToFile(actualXML, xmlFile) < 0) + goto cleanup; + + ret = 0; + + cleanup: + VIR_FREE(xmlFile); + VIR_FREE(actualXML); + qemuMigrationParamsFree(migParams); + virBufferFreeAndReset(&buf); + xmlXPathFreeContext(ctxt); + xmlFreeDoc(doc); + return ret; +} + + +static int +qemuMigParamsTestXML(const void *opaque) +{ + const qemuMigParamsData *data = opaque; + virBuffer buf = VIR_BUFFER_INITIALIZER; + char *replyFile = NULL; + char *xmlFile = NULL; + qemuMonitorTestPtr mon = NULL; + virJSONValuePtr params = NULL; + qemuMigrationParamsPtr migParams = NULL; + char *actualXML = NULL; + int ret = -1; + + if (virAsprintf(&replyFile, "%s/qemumigparamsdata/%s.reply", + abs_srcdir, data->name) < 0 || + virAsprintf(&xmlFile, "%s/qemumigparamsdata/%s.xml", + abs_srcdir, data->name) < 0) + goto cleanup; + + if (!(mon = qemuMonitorTestNewFromFile(replyFile, data->xmlopt, true))) + goto cleanup; + + if (qemuMonitorGetMigrationParams(qemuMonitorTestGetMonitor(mon), + ¶ms) < 0) + goto cleanup; + + if (!(migParams = qemuMigrationParamsFromJSON(params))) + goto cleanup; + + qemuMigParamsTestFormatXML(&buf, migParams); + + if (!(actualXML = virBufferContentAndReset(&buf))) + goto cleanup; + + if (virTestCompareToFile(actualXML, xmlFile) < 0) + goto cleanup; + + ret = 0; + + cleanup: + VIR_FREE(replyFile); + VIR_FREE(xmlFile); + VIR_FREE(actualXML); + virJSONValueFree(params); + qemuMigrationParamsFree(migParams); + virBufferFreeAndReset(&buf); + qemuMonitorTestFree(mon); + return ret; +} + + +static int +qemuMigParamsTestJSON(const void *opaque) +{ + const qemuMigParamsData *data = opaque; + char *replyFile = NULL; + char *jsonFile = NULL; + qemuMonitorTestPtr mon = NULL; + virJSONValuePtr paramsIn = NULL; + virJSONValuePtr paramsOut = NULL; + qemuMigrationParamsPtr migParams = NULL; + char *actualJSON = NULL; + int ret = -1; + + if (virAsprintf(&replyFile, "%s/qemumigparamsdata/%s.reply", + abs_srcdir, data->name) < 0 || + virAsprintf(&jsonFile, "%s/qemumigparamsdata/%s.json", + abs_srcdir, data->name) < 0) + goto cleanup; + + if (!(mon = qemuMonitorTestNewFromFile(replyFile, data->xmlopt, true))) + goto cleanup; + + if (qemuMonitorGetMigrationParams(qemuMonitorTestGetMonitor(mon), + ¶msIn) < 0) + goto cleanup; + + if (!(migParams = qemuMigrationParamsFromJSON(paramsIn))) + goto cleanup; + + if (!(paramsOut = qemuMigrationParamsToJSON(migParams)) || + !(actualJSON = virJSONValueToString(paramsOut, true))) + goto cleanup; + + if (virTestCompareToFile(actualJSON, jsonFile) < 0) + goto cleanup; + + ret = 0; + + cleanup: + VIR_FREE(replyFile); + VIR_FREE(jsonFile); + VIR_FREE(actualJSON); + virJSONValueFree(paramsIn); + virJSONValueFree(paramsOut); + qemuMigrationParamsFree(migParams); + qemuMonitorTestFree(mon); + return ret; +} + + +static int +mymain(void) +{ + virQEMUDriver driver; + int ret = 0; + +#if !WITH_YAJL + fputs("libvirt not compiled with yajl, skipping this test\n", stderr); + return EXIT_AM_SKIP; +#endif + + if (virThreadInitialize() < 0 || + qemuTestDriverInit(&driver) < 0) + return EXIT_FAILURE; + + virEventRegisterDefaultImpl(); + +#define DO_TEST(name) \ + do { \ + qemuMigParamsData data = { \ + driver.xmlopt, name \ + }; \ + if (virTestRun(name " (xml)", qemuMigParamsTestXML, &data) < 0) \ + ret = -1; \ + if (virTestRun(name " (json)", qemuMigParamsTestJSON, &data) < 0) \ + ret = -1; \ + if (virTestRun(name " (xml2xml)", qemuMigParamsTestXML2XML, &data) < 0) \ + ret = -1; \ + } while (0) + + DO_TEST("unsupported"); + + qemuTestDriverFree(&driver); + + return (ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} + +VIR_TEST_MAIN(mymain) -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:54PM +0200, Jiri Denemark wrote:
This is an enhanced replacement for the original test from qemumonitorjsontest which was dropped earlier in this series. More data files with some real data will be added in the following patches.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- tests/Makefile.am | 12 ++ tests/qemumigparamsdata/unsupported.json | 3 + tests/qemumigparamsdata/unsupported.reply | 7 + tests/qemumigparamsdata/unsupported.xml | 4 + tests/qemumigparamstest.c | 237 ++++++++++++++++++++++ 5 files changed, 263 insertions(+) create mode 100644 tests/qemumigparamsdata/unsupported.json create mode 100644 tests/qemumigparamsdata/unsupported.reply create mode 100644 tests/qemumigparamsdata/unsupported.xml create mode 100644 tests/qemumigparamstest.c
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- tests/qemumigparamsdata/basic.json | 9 +++++++++ tests/qemumigparamsdata/basic.reply | 12 ++++++++++++ tests/qemumigparamsdata/basic.xml | 11 +++++++++++ tests/qemumigparamsdata/empty.json | 3 +++ tests/qemumigparamsdata/empty.reply | 5 +++++ tests/qemumigparamsdata/empty.xml | 4 ++++ tests/qemumigparamstest.c | 2 ++ 7 files changed, 46 insertions(+) create mode 100644 tests/qemumigparamsdata/basic.json create mode 100644 tests/qemumigparamsdata/basic.reply create mode 100644 tests/qemumigparamsdata/basic.xml create mode 100644 tests/qemumigparamsdata/empty.json create mode 100644 tests/qemumigparamsdata/empty.reply create mode 100644 tests/qemumigparamsdata/empty.xml diff --git a/tests/qemumigparamsdata/basic.json b/tests/qemumigparamsdata/basic.json new file mode 100644 index 0000000000..b810d7cc87 --- /dev/null +++ b/tests/qemumigparamsdata/basic.json @@ -0,0 +1,9 @@ +{ + "compress-level": 1, + "compress-threads": 8, + "decompress-threads": 2, + "cpu-throttle-initial": 20, + "cpu-throttle-increment": 10, + "max-bandwidth": 33554432, + "downtime-limit": 300 +} diff --git a/tests/qemumigparamsdata/basic.reply b/tests/qemumigparamsdata/basic.reply new file mode 100644 index 0000000000..dd8c5287a5 --- /dev/null +++ b/tests/qemumigparamsdata/basic.reply @@ -0,0 +1,12 @@ +{ + "id": "libvirt-1", + "return": { + "decompress-threads": 2, + "cpu-throttle-increment": 10, + "compress-threads": 8, + "compress-level": 1, + "cpu-throttle-initial": 20, + "max-bandwidth": 33554432, + "downtime-limit": 300 + } +} diff --git a/tests/qemumigparamsdata/basic.xml b/tests/qemumigparamsdata/basic.xml new file mode 100644 index 0000000000..2ca532eff5 --- /dev/null +++ b/tests/qemumigparamsdata/basic.xml @@ -0,0 +1,11 @@ +<test> + <migParams> + <param name='compress-level' value='1'/> + <param name='compress-threads' value='8'/> + <param name='decompress-threads' value='2'/> + <param name='cpu-throttle-initial' value='20'/> + <param name='cpu-throttle-increment' value='10'/> + <param name='max-bandwidth' value='33554432'/> + <param name='downtime-limit' value='300'/> + </migParams> +</test> diff --git a/tests/qemumigparamsdata/empty.json b/tests/qemumigparamsdata/empty.json new file mode 100644 index 0000000000..0db3279e44 --- /dev/null +++ b/tests/qemumigparamsdata/empty.json @@ -0,0 +1,3 @@ +{ + +} diff --git a/tests/qemumigparamsdata/empty.reply b/tests/qemumigparamsdata/empty.reply new file mode 100644 index 0000000000..7aae399ede --- /dev/null +++ b/tests/qemumigparamsdata/empty.reply @@ -0,0 +1,5 @@ +{ + "id": "libvirt-1", + "return": { + } +} diff --git a/tests/qemumigparamsdata/empty.xml b/tests/qemumigparamsdata/empty.xml new file mode 100644 index 0000000000..8aa3abefc0 --- /dev/null +++ b/tests/qemumigparamsdata/empty.xml @@ -0,0 +1,4 @@ +<test> + <migParams> + </migParams> +</test> diff --git a/tests/qemumigparamstest.c b/tests/qemumigparamstest.c index 4cc27bcf52..6fb404c24d 100644 --- a/tests/qemumigparamstest.c +++ b/tests/qemumigparamstest.c @@ -228,6 +228,8 @@ mymain(void) } while (0) DO_TEST("unsupported"); + DO_TEST("empty"); + DO_TEST("basic"); qemuTestDriverFree(&driver); -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:55PM +0200, Jiri Denemark wrote:
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- tests/qemumigparamsdata/basic.json | 9 +++++++++ tests/qemumigparamsdata/basic.reply | 12 ++++++++++++ tests/qemumigparamsdata/basic.xml | 11 +++++++++++ tests/qemumigparamsdata/empty.json | 3 +++ tests/qemumigparamsdata/empty.reply | 5 +++++ tests/qemumigparamsdata/empty.xml | 4 ++++ tests/qemumigparamstest.c | 2 ++ 7 files changed, 46 insertions(+) create mode 100644 tests/qemumigparamsdata/basic.json create mode 100644 tests/qemumigparamsdata/basic.reply create mode 100644 tests/qemumigparamsdata/basic.xml create mode 100644 tests/qemumigparamsdata/empty.json create mode 100644 tests/qemumigparamsdata/empty.reply create mode 100644 tests/qemumigparamsdata/empty.xml
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- tests/qemumigparamsdata/tls-enabled.json | 11 +++++++++++ tests/qemumigparamsdata/tls-enabled.reply | 14 ++++++++++++++ tests/qemumigparamsdata/tls-enabled.xml | 13 +++++++++++++ tests/qemumigparamsdata/tls-hostname.json | 11 +++++++++++ tests/qemumigparamsdata/tls-hostname.reply | 14 ++++++++++++++ tests/qemumigparamsdata/tls-hostname.xml | 13 +++++++++++++ tests/qemumigparamsdata/tls.json | 11 +++++++++++ tests/qemumigparamsdata/tls.reply | 14 ++++++++++++++ tests/qemumigparamsdata/tls.xml | 13 +++++++++++++ tests/qemumigparamstest.c | 3 +++ 10 files changed, 117 insertions(+) create mode 100644 tests/qemumigparamsdata/tls-enabled.json create mode 100644 tests/qemumigparamsdata/tls-enabled.reply create mode 100644 tests/qemumigparamsdata/tls-enabled.xml create mode 100644 tests/qemumigparamsdata/tls-hostname.json create mode 100644 tests/qemumigparamsdata/tls-hostname.reply create mode 100644 tests/qemumigparamsdata/tls-hostname.xml create mode 100644 tests/qemumigparamsdata/tls.json create mode 100644 tests/qemumigparamsdata/tls.reply create mode 100644 tests/qemumigparamsdata/tls.xml diff --git a/tests/qemumigparamsdata/tls-enabled.json b/tests/qemumigparamsdata/tls-enabled.json new file mode 100644 index 0000000000..d42684a9de --- /dev/null +++ b/tests/qemumigparamsdata/tls-enabled.json @@ -0,0 +1,11 @@ +{ + "compress-level": 1, + "compress-threads": 8, + "decompress-threads": 2, + "cpu-throttle-initial": 20, + "cpu-throttle-increment": 10, + "tls-creds": "objlibvirt_migrate_tls0", + "tls-hostname": "", + "max-bandwidth": 33554432, + "downtime-limit": 300 +} diff --git a/tests/qemumigparamsdata/tls-enabled.reply b/tests/qemumigparamsdata/tls-enabled.reply new file mode 100644 index 0000000000..001241b075 --- /dev/null +++ b/tests/qemumigparamsdata/tls-enabled.reply @@ -0,0 +1,14 @@ +{ + "id": "libvirt-1", + "return": { + "decompress-threads": 2, + "cpu-throttle-increment": 10, + "compress-threads": 8, + "tls-hostname": "", + "compress-level": 1, + "cpu-throttle-initial": 20, + "tls-creds": "objlibvirt_migrate_tls0", + "max-bandwidth": 33554432, + "downtime-limit": 300 + } +} diff --git a/tests/qemumigparamsdata/tls-enabled.xml b/tests/qemumigparamsdata/tls-enabled.xml new file mode 100644 index 0000000000..3e60c4dec3 --- /dev/null +++ b/tests/qemumigparamsdata/tls-enabled.xml @@ -0,0 +1,13 @@ +<test> + <migParams> + <param name='compress-level' value='1'/> + <param name='compress-threads' value='8'/> + <param name='decompress-threads' value='2'/> + <param name='cpu-throttle-initial' value='20'/> + <param name='cpu-throttle-increment' value='10'/> + <param name='tls-creds' value='objlibvirt_migrate_tls0'/> + <param name='tls-hostname' value=''/> + <param name='max-bandwidth' value='33554432'/> + <param name='downtime-limit' value='300'/> + </migParams> +</test> diff --git a/tests/qemumigparamsdata/tls-hostname.json b/tests/qemumigparamsdata/tls-hostname.json new file mode 100644 index 0000000000..abbd9f124b --- /dev/null +++ b/tests/qemumigparamsdata/tls-hostname.json @@ -0,0 +1,11 @@ +{ + "compress-level": 1, + "compress-threads": 8, + "decompress-threads": 2, + "cpu-throttle-initial": 20, + "cpu-throttle-increment": 10, + "tls-creds": "objlibvirt_migrate_tls0", + "tls-hostname": "f27-1.virt", + "max-bandwidth": 33554432, + "downtime-limit": 300 +} diff --git a/tests/qemumigparamsdata/tls-hostname.reply b/tests/qemumigparamsdata/tls-hostname.reply new file mode 100644 index 0000000000..74f069f780 --- /dev/null +++ b/tests/qemumigparamsdata/tls-hostname.reply @@ -0,0 +1,14 @@ +{ + "id": "libvirt-1", + "return": { + "decompress-threads": 2, + "cpu-throttle-increment": 10, + "compress-threads": 8, + "tls-hostname": "f27-1.virt", + "compress-level": 1, + "cpu-throttle-initial": 20, + "tls-creds": "objlibvirt_migrate_tls0", + "max-bandwidth": 33554432, + "downtime-limit": 300 + } +} diff --git a/tests/qemumigparamsdata/tls-hostname.xml b/tests/qemumigparamsdata/tls-hostname.xml new file mode 100644 index 0000000000..4310e789a0 --- /dev/null +++ b/tests/qemumigparamsdata/tls-hostname.xml @@ -0,0 +1,13 @@ +<test> + <migParams> + <param name='compress-level' value='1'/> + <param name='compress-threads' value='8'/> + <param name='decompress-threads' value='2'/> + <param name='cpu-throttle-initial' value='20'/> + <param name='cpu-throttle-increment' value='10'/> + <param name='tls-creds' value='objlibvirt_migrate_tls0'/> + <param name='tls-hostname' value='f27-1.virt'/> + <param name='max-bandwidth' value='33554432'/> + <param name='downtime-limit' value='300'/> + </migParams> +</test> diff --git a/tests/qemumigparamsdata/tls.json b/tests/qemumigparamsdata/tls.json new file mode 100644 index 0000000000..02e90c60ea --- /dev/null +++ b/tests/qemumigparamsdata/tls.json @@ -0,0 +1,11 @@ +{ + "compress-level": 1, + "compress-threads": 8, + "decompress-threads": 2, + "cpu-throttle-initial": 20, + "cpu-throttle-increment": 10, + "tls-creds": "", + "tls-hostname": "", + "max-bandwidth": 33554432, + "downtime-limit": 300 +} diff --git a/tests/qemumigparamsdata/tls.reply b/tests/qemumigparamsdata/tls.reply new file mode 100644 index 0000000000..591eca6926 --- /dev/null +++ b/tests/qemumigparamsdata/tls.reply @@ -0,0 +1,14 @@ +{ + "id": "libvirt-1", + "return": { + "decompress-threads": 2, + "cpu-throttle-increment": 10, + "compress-threads": 8, + "tls-hostname": "", + "compress-level": 1, + "cpu-throttle-initial": 20, + "tls-creds": "", + "max-bandwidth": 33554432, + "downtime-limit": 300 + } +} diff --git a/tests/qemumigparamsdata/tls.xml b/tests/qemumigparamsdata/tls.xml new file mode 100644 index 0000000000..71e5bbb7cb --- /dev/null +++ b/tests/qemumigparamsdata/tls.xml @@ -0,0 +1,13 @@ +<test> + <migParams> + <param name='compress-level' value='1'/> + <param name='compress-threads' value='8'/> + <param name='decompress-threads' value='2'/> + <param name='cpu-throttle-initial' value='20'/> + <param name='cpu-throttle-increment' value='10'/> + <param name='tls-creds' value=''/> + <param name='tls-hostname' value=''/> + <param name='max-bandwidth' value='33554432'/> + <param name='downtime-limit' value='300'/> + </migParams> +</test> diff --git a/tests/qemumigparamstest.c b/tests/qemumigparamstest.c index 6fb404c24d..ba62aacc54 100644 --- a/tests/qemumigparamstest.c +++ b/tests/qemumigparamstest.c @@ -230,6 +230,9 @@ mymain(void) DO_TEST("unsupported"); DO_TEST("empty"); DO_TEST("basic"); + DO_TEST("tls"); + DO_TEST("tls-enabled"); + DO_TEST("tls-hostname"); qemuTestDriverFree(&driver); -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:56PM +0200, Jiri Denemark wrote:
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- tests/qemumigparamsdata/tls-enabled.json | 11 +++++++++++ tests/qemumigparamsdata/tls-enabled.reply | 14 ++++++++++++++ tests/qemumigparamsdata/tls-enabled.xml | 13 +++++++++++++ tests/qemumigparamsdata/tls-hostname.json | 11 +++++++++++ tests/qemumigparamsdata/tls-hostname.reply | 14 ++++++++++++++ tests/qemumigparamsdata/tls-hostname.xml | 13 +++++++++++++ tests/qemumigparamsdata/tls.json | 11 +++++++++++ tests/qemumigparamsdata/tls.reply | 14 ++++++++++++++ tests/qemumigparamsdata/tls.xml | 13 +++++++++++++ tests/qemumigparamstest.c | 3 +++ 10 files changed, 117 insertions(+) create mode 100644 tests/qemumigparamsdata/tls-enabled.json create mode 100644 tests/qemumigparamsdata/tls-enabled.reply create mode 100644 tests/qemumigparamsdata/tls-enabled.xml create mode 100644 tests/qemumigparamsdata/tls-hostname.json create mode 100644 tests/qemumigparamsdata/tls-hostname.reply create mode 100644 tests/qemumigparamsdata/tls-hostname.xml create mode 100644 tests/qemumigparamsdata/tls.json create mode 100644 tests/qemumigparamsdata/tls.reply create mode 100644 tests/qemumigparamsdata/tls.xml
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

When an async job is running, we sometimes need to know how it was started to distinguish between several types of the job, e.g., post-copy vs. normal migration. So far we added a specific bool item to qemuDomainJobObj for such cases, which doesn't scale very well and storing such bools in status XML would be painful so we didn't do it. A better approach is to store the flags passed to the API which started the async job, which can be easily stored in status XML. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_domain.c | 10 ++++++++-- src/qemu/qemu_domain.h | 4 +++- src/qemu/qemu_driver.c | 31 +++++++++++++++++++------------ src/qemu/qemu_migration.c | 20 +++++++++++++------- src/qemu/qemu_process.c | 5 +++-- src/qemu/qemu_process.h | 3 ++- 6 files changed, 48 insertions(+), 25 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index e3f58e45cb..bf04053607 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -339,6 +339,7 @@ qemuDomainObjResetAsyncJob(qemuDomainObjPrivatePtr priv) VIR_FREE(job->current); qemuMigrationParamsFree(job->migParams); job->migParams = NULL; + job->apiFlags = 0; } void @@ -354,6 +355,7 @@ qemuDomainObjRestoreJob(virDomainObjPtr obj, job->asyncOwner = priv->job.asyncOwner; job->phase = priv->job.phase; VIR_STEAL_PTR(job->migParams, priv->job.migParams); + job->apiFlags = priv->job.apiFlags; qemuDomainObjResetJob(priv); qemuDomainObjResetAsyncJob(priv); @@ -5805,7 +5807,8 @@ qemuDomainObjBeginJobInternal(virQEMUDriverPtr driver, asyncDuration = now - priv->job.asyncStarted; VIR_WARN("Cannot start job (%s, %s) for domain %s; " - "current job is (%s, %s) owned by (%llu %s, %llu %s) " + "current job is (%s, %s) " + "owned by (%llu %s, %llu %s (flags=0x%lx)) " "for (%llus, %llus)", qemuDomainJobTypeToString(job), qemuDomainAsyncJobTypeToString(asyncJob), @@ -5814,6 +5817,7 @@ qemuDomainObjBeginJobInternal(virQEMUDriverPtr driver, qemuDomainAsyncJobTypeToString(priv->job.asyncJob), priv->job.owner, NULLSTR(priv->job.ownerAPI), priv->job.asyncOwner, NULLSTR(priv->job.asyncOwnerAPI), + priv->job.apiFlags, duration / 1000, asyncDuration / 1000); if (nested || qemuDomainNestedJobAllowed(priv, job)) @@ -5877,7 +5881,8 @@ int qemuDomainObjBeginJob(virQEMUDriverPtr driver, int qemuDomainObjBeginAsyncJob(virQEMUDriverPtr driver, virDomainObjPtr obj, qemuDomainAsyncJob asyncJob, - virDomainJobOperation operation) + virDomainJobOperation operation, + unsigned long apiFlags) { qemuDomainObjPrivatePtr priv; @@ -5887,6 +5892,7 @@ int qemuDomainObjBeginAsyncJob(virQEMUDriverPtr driver, priv = obj->privateData; priv->job.current->operation = operation; + priv->job.apiFlags = apiFlags; return 0; } diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 2bb3e0a788..2146ff00a9 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -182,6 +182,7 @@ struct _qemuDomainJobObj { bool dumpCompleted; /* dump completed */ qemuMigrationParamsPtr migParams; + unsigned long apiFlags; /* flags passed to the API which started the async job */ }; typedef void (*qemuDomainCleanupCallback)(virQEMUDriverPtr driver, @@ -493,7 +494,8 @@ int qemuDomainObjBeginJob(virQEMUDriverPtr driver, int qemuDomainObjBeginAsyncJob(virQEMUDriverPtr driver, virDomainObjPtr obj, qemuDomainAsyncJob asyncJob, - virDomainJobOperation operation) + virDomainJobOperation operation, + unsigned long apiFlags) ATTRIBUTE_RETURN_CHECK; int qemuDomainObjBeginNestedJob(virQEMUDriverPtr driver, virDomainObjPtr obj, diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 8917beae35..198020a0e4 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -267,7 +267,7 @@ qemuAutostartDomain(virDomainObjPtr vm, if (vm->autostart && !virDomainObjIsActive(vm)) { if (qemuProcessBeginJob(driver, vm, - VIR_DOMAIN_JOB_OPERATION_START) < 0) { + VIR_DOMAIN_JOB_OPERATION_START, flags) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to start job on VM '%s': %s"), vm->def->name, virGetLastErrorMessage()); @@ -1779,7 +1779,8 @@ static virDomainPtr qemuDomainCreateXML(virConnectPtr conn, virObjectRef(vm); def = NULL; - if (qemuProcessBeginJob(driver, vm, VIR_DOMAIN_JOB_OPERATION_START) < 0) { + if (qemuProcessBeginJob(driver, vm, VIR_DOMAIN_JOB_OPERATION_START, + flags) < 0) { qemuDomainRemoveInactiveJob(driver, vm); goto cleanup; } @@ -3345,7 +3346,7 @@ qemuDomainSaveInternal(virQEMUDriverPtr driver, goto cleanup; if (qemuDomainObjBeginAsyncJob(driver, vm, QEMU_ASYNC_JOB_SAVE, - VIR_DOMAIN_JOB_OPERATION_SAVE) < 0) + VIR_DOMAIN_JOB_OPERATION_SAVE, flags) < 0) goto cleanup; if (!virDomainObjIsActive(vm)) { @@ -3953,7 +3954,8 @@ qemuDomainCoreDumpWithFormat(virDomainPtr dom, if (qemuDomainObjBeginAsyncJob(driver, vm, QEMU_ASYNC_JOB_DUMP, - VIR_DOMAIN_JOB_OPERATION_DUMP) < 0) + VIR_DOMAIN_JOB_OPERATION_DUMP, + flags) < 0) goto cleanup; if (!virDomainObjIsActive(vm)) { @@ -4178,7 +4180,8 @@ processWatchdogEvent(virQEMUDriverPtr driver, case VIR_DOMAIN_WATCHDOG_ACTION_DUMP: if (qemuDomainObjBeginAsyncJob(driver, vm, QEMU_ASYNC_JOB_DUMP, - VIR_DOMAIN_JOB_OPERATION_DUMP) < 0) { + VIR_DOMAIN_JOB_OPERATION_DUMP, + flags) < 0) { goto cleanup; } @@ -4264,9 +4267,10 @@ processGuestPanicEvent(virQEMUDriverPtr driver, virObjectEventPtr event = NULL; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); bool removeInactive = false; + unsigned long flags = VIR_DUMP_MEMORY_ONLY; if (qemuDomainObjBeginAsyncJob(driver, vm, QEMU_ASYNC_JOB_DUMP, - VIR_DOMAIN_JOB_OPERATION_DUMP) < 0) + VIR_DOMAIN_JOB_OPERATION_DUMP, flags) < 0) goto cleanup; if (!virDomainObjIsActive(vm)) { @@ -4297,7 +4301,7 @@ processGuestPanicEvent(virQEMUDriverPtr driver, switch (action) { case VIR_DOMAIN_LIFECYCLE_ACTION_COREDUMP_DESTROY: - if (doCoreDumpToAutoDumpPath(driver, vm, VIR_DUMP_MEMORY_ONLY) < 0) + if (doCoreDumpToAutoDumpPath(driver, vm, flags) < 0) goto endjob; ATTRIBUTE_FALLTHROUGH; @@ -4314,7 +4318,7 @@ processGuestPanicEvent(virQEMUDriverPtr driver, break; case VIR_DOMAIN_LIFECYCLE_ACTION_COREDUMP_RESTART: - if (doCoreDumpToAutoDumpPath(driver, vm, VIR_DUMP_MEMORY_ONLY) < 0) + if (doCoreDumpToAutoDumpPath(driver, vm, flags) < 0) goto endjob; ATTRIBUTE_FALLTHROUGH; @@ -6769,7 +6773,8 @@ qemuDomainRestoreFlags(virConnectPtr conn, priv->hookRun = true; } - if (qemuProcessBeginJob(driver, vm, VIR_DOMAIN_JOB_OPERATION_RESTORE) < 0) + if (qemuProcessBeginJob(driver, vm, VIR_DOMAIN_JOB_OPERATION_RESTORE, + flags) < 0) goto cleanup; ret = qemuDomainSaveImageStartVM(conn, driver, vm, &fd, data, path, @@ -7357,7 +7362,8 @@ qemuDomainCreateWithFlags(virDomainPtr dom, unsigned int flags) if (virDomainCreateWithFlagsEnsureACL(dom->conn, vm->def) < 0) goto cleanup; - if (qemuProcessBeginJob(driver, vm, VIR_DOMAIN_JOB_OPERATION_START) < 0) + if (qemuProcessBeginJob(driver, vm, VIR_DOMAIN_JOB_OPERATION_START, + flags) < 0) goto cleanup; if (virDomainObjIsActive(vm)) { @@ -15208,7 +15214,7 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain, * 'savevm' blocks the monitor. External snapshot will then modify the * job mask appropriately. */ if (qemuDomainObjBeginAsyncJob(driver, vm, QEMU_ASYNC_JOB_SNAPSHOT, - VIR_DOMAIN_JOB_OPERATION_SNAPSHOT) < 0) + VIR_DOMAIN_JOB_OPERATION_SNAPSHOT, flags) < 0) goto cleanup; qemuDomainObjSetAsyncJobMask(vm, QEMU_JOB_NONE); @@ -15807,7 +15813,8 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, } if (qemuProcessBeginJob(driver, vm, - VIR_DOMAIN_JOB_OPERATION_SNAPSHOT_REVERT) < 0) + VIR_DOMAIN_JOB_OPERATION_SNAPSHOT_REVERT, + flags) < 0) goto cleanup; if (!(snap = qemuSnapObjFromSnapshot(vm, snapshot))) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 42194c0ea8..431875c762 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -80,7 +80,8 @@ VIR_ENUM_IMPL(qemuMigrationJobPhase, QEMU_MIGRATION_PHASE_LAST, static int qemuMigrationJobStart(virQEMUDriverPtr driver, virDomainObjPtr vm, - qemuDomainAsyncJob job) + qemuDomainAsyncJob job, + unsigned long apiFlags) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; static void @@ -1985,7 +1986,8 @@ qemuMigrationSrcBegin(virConnectPtr conn, qemuDomainAsyncJob asyncJob; if ((flags & VIR_MIGRATE_CHANGE_PROTECTION)) { - if (qemuMigrationJobStart(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) + if (qemuMigrationJobStart(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, + flags) < 0) goto cleanup; asyncJob = QEMU_ASYNC_JOB_MIGRATION_OUT; } else { @@ -2320,7 +2322,8 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, !!(flags & VIR_MIGRATE_NON_SHARED_INC)) < 0) goto cleanup; - if (qemuMigrationJobStart(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN) < 0) + if (qemuMigrationJobStart(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN, + flags) < 0) goto cleanup; qemuMigrationJobSetPhase(driver, vm, QEMU_MIGRATION_PHASE_PREPARE); @@ -4440,7 +4443,8 @@ qemuMigrationSrcPerformJob(virQEMUDriverPtr driver, virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); qemuDomainObjPrivatePtr priv = vm->privateData; - if (qemuMigrationJobStart(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) + if (qemuMigrationJobStart(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, + flags) < 0) goto cleanup; if (!virDomainObjIsActive(vm) && !(flags & VIR_MIGRATE_OFFLINE)) { @@ -4552,7 +4556,8 @@ qemuMigrationSrcPerformPhase(virQEMUDriverPtr driver, /* If we didn't start the job in the begin phase, start it now. */ if (!(flags & VIR_MIGRATE_CHANGE_PROTECTION)) { - if (qemuMigrationJobStart(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) + if (qemuMigrationJobStart(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, + flags) < 0) goto cleanup; } else if (!qemuMigrationJobIsActive(vm, QEMU_ASYNC_JOB_MIGRATION_OUT)) { goto cleanup; @@ -5291,7 +5296,8 @@ qemuMigrationSrcCancel(virQEMUDriverPtr driver, static int qemuMigrationJobStart(virQEMUDriverPtr driver, virDomainObjPtr vm, - qemuDomainAsyncJob job) + qemuDomainAsyncJob job, + unsigned long apiFlags) { qemuDomainObjPrivatePtr priv = vm->privateData; virDomainJobOperation op; @@ -5307,7 +5313,7 @@ qemuMigrationJobStart(virQEMUDriverPtr driver, JOB_MASK(QEMU_JOB_MIGRATION_OP); } - if (qemuDomainObjBeginAsyncJob(driver, vm, job, op) < 0) + if (qemuDomainObjBeginAsyncJob(driver, vm, job, op, apiFlags) < 0) return -1; priv->job.current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_MIGRATION; diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 6aa4f4ed71..b4bb7eb8a5 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -4189,10 +4189,11 @@ qemuProcessIncomingDefNew(virQEMUCapsPtr qemuCaps, int qemuProcessBeginJob(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainJobOperation operation) + virDomainJobOperation operation, + unsigned long apiFlags) { if (qemuDomainObjBeginAsyncJob(driver, vm, QEMU_ASYNC_JOB_START, - operation) < 0) + operation, apiFlags) < 0) return -1; qemuDomainObjSetAsyncJobMask(vm, QEMU_JOB_NONE); diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h index 2741115673..9dd5c97642 100644 --- a/src/qemu/qemu_process.h +++ b/src/qemu/qemu_process.h @@ -68,7 +68,8 @@ void qemuProcessIncomingDefFree(qemuProcessIncomingDefPtr inc); int qemuProcessBeginJob(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainJobOperation operation); + virDomainJobOperation operation, + unsigned long apiFlags); void qemuProcessEndJob(virQEMUDriverPtr driver, virDomainObjPtr vm); -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:57PM +0200, Jiri Denemark wrote:
When an async job is running, we sometimes need to know how it was started to distinguish between several types of the job, e.g., post-copy vs. normal migration. So far we added a specific bool item to qemuDomainJobObj for such cases, which doesn't scale very well and storing such bools in status XML would be painful so we didn't do it.
A better approach is to store the flags passed to the API which started the async job, which can be easily stored in status XML.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_domain.c | 10 ++++++++-- src/qemu/qemu_domain.h | 4 +++- src/qemu/qemu_driver.c | 31 +++++++++++++++++++------------ src/qemu/qemu_migration.c | 20 +++++++++++++------- src/qemu/qemu_process.c | 5 +++-- src/qemu/qemu_process.h | 3 ++- 6 files changed, 48 insertions(+), 25 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

migrate_cancel QMP command cannot be used for cancelling memory-only dumps and priv->job.dump_memory_only is used for reporting an error if someone calls virDomainAbortJob when memory-only dump job is running. Since commit 150930e3098 the dump_memory_only flag is set only dump-guest-memory command was called without the detach parameter. This would incorrectly allow libvirt to send migrate_cancel while the detached memory-only dump is running. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_driver.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 198020a0e4..4af6d58fb1 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -3794,12 +3794,12 @@ qemuDumpToFd(virQEMUDriverPtr driver, if (qemuSecuritySetImageFDLabel(driver->securityManager, vm->def, fd) < 0) return -1; - if (detach) { + priv->job.dump_memory_only = true; + + if (detach) priv->job.current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_MEMDUMP; - } else { + else VIR_FREE(priv->job.current); - priv->job.dump_memory_only = true; - } if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) return -1; @@ -13472,7 +13472,7 @@ static int qemuDomainAbortJob(virDomainPtr dom) priv = vm->privateData; - if (!priv->job.asyncJob || priv->job.dump_memory_only) { + if (!priv->job.asyncJob) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("no job is active on the domain")); goto endjob; @@ -13485,6 +13485,13 @@ static int qemuDomainAbortJob(virDomainPtr dom) goto endjob; } + if (priv->job.asyncJob == QEMU_ASYNC_JOB_DUMP && + priv->job.dump_memory_only) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("cannot abort memory-only dump")); + goto endjob; + } + if (priv->job.asyncJob == QEMU_ASYNC_JOB_MIGRATION_OUT && (priv->job.current->status == QEMU_DOMAIN_JOB_STATUS_POSTCOPY || (virDomainObjGetState(vm, &reason) == VIR_DOMAIN_PAUSED && -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:58PM +0200, Jiri Denemark wrote:
migrate_cancel QMP command cannot be used for cancelling memory-only dumps and priv->job.dump_memory_only is used for reporting an error if someone calls virDomainAbortJob when memory-only dump job is running.
Since commit 150930e3098 the dump_memory_only flag is set only dump-guest-memory command was called without the detach parameter. This
s/only/only if/
would incorrectly allow libvirt to send migrate_cancel while the detached memory-only dump is running.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_driver.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

We store the flags passed to the API which started QEMU_ASYNC_JOB_DUMP and we can use them to check whether a memory-only dump is running. There's no need for a specific bool flag. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_domain.c | 1 - src/qemu/qemu_domain.h | 1 - src/qemu/qemu_driver.c | 4 +--- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index bf04053607..9343f41f57 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -329,7 +329,6 @@ qemuDomainObjResetAsyncJob(qemuDomainObjPrivatePtr priv) job->asyncStarted = 0; job->phase = 0; job->mask = QEMU_JOB_DEFAULT_MASK; - job->dump_memory_only = false; job->abortJob = false; job->spiceMigration = false; job->spiceMigrated = false; diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 2146ff00a9..8d608da121 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -170,7 +170,6 @@ struct _qemuDomainJobObj { unsigned long long asyncStarted; /* When the current async job started */ int phase; /* Job phase (mainly for migrations) */ unsigned long long mask; /* Jobs allowed during async job */ - bool dump_memory_only; /* use dump-guest-memory to do dump */ qemuDomainJobInfoPtr current; /* async job progress data */ qemuDomainJobInfoPtr completed; /* statistics data of a recently completed job */ bool abortJob; /* abort of the job requested */ diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 4af6d58fb1..3fac038583 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -3794,8 +3794,6 @@ qemuDumpToFd(virQEMUDriverPtr driver, if (qemuSecuritySetImageFDLabel(driver->securityManager, vm->def, fd) < 0) return -1; - priv->job.dump_memory_only = true; - if (detach) priv->job.current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_MEMDUMP; else @@ -13486,7 +13484,7 @@ static int qemuDomainAbortJob(virDomainPtr dom) } if (priv->job.asyncJob == QEMU_ASYNC_JOB_DUMP && - priv->job.dump_memory_only) { + priv->job.apiFlags & VIR_DUMP_MEMORY_ONLY) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("cannot abort memory-only dump")); goto endjob; -- 2.17.0

On Wed, Apr 11, 2018 at 04:41:59PM +0200, Jiri Denemark wrote:
We store the flags passed to the API which started QEMU_ASYNC_JOB_DUMP and we can use them to check whether a memory-only dump is running. There's no need for a specific bool flag.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_domain.c | 1 - src/qemu/qemu_domain.h | 1 - src/qemu/qemu_driver.c | 4 +--- 3 files changed, 1 insertion(+), 5 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

We store the flags passed to the API which started the migration. Let's use them instead of a separate bool to check if post-copy migration was requested. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_domain.c | 1 - src/qemu/qemu_domain.h | 1 - src/qemu/qemu_driver.c | 2 +- src/qemu/qemu_migration.c | 4 ---- 4 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 9343f41f57..71c3a917c1 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -332,7 +332,6 @@ qemuDomainObjResetAsyncJob(qemuDomainObjPrivatePtr priv) job->abortJob = false; job->spiceMigration = false; job->spiceMigrated = false; - job->postcopyEnabled = false; job->dumpCompleted = false; VIR_FREE(job->error); VIR_FREE(job->current); diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 8d608da121..91385da2a9 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -176,7 +176,6 @@ struct _qemuDomainJobObj { bool spiceMigration; /* we asked for spice migration and we * should wait for it to finish */ bool spiceMigrated; /* spice migration completed */ - bool postcopyEnabled; /* post-copy migration was enabled */ char *error; /* job event completion error */ bool dumpCompleted; /* dump completed */ diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 3fac038583..1b37c0b45a 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -13840,7 +13840,7 @@ qemuDomainMigrateStartPostCopy(virDomainPtr dom, goto endjob; } - if (!priv->job.postcopyEnabled) { + if (!(priv->job.apiFlags & VIR_MIGRATE_POSTCOPY)) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("switching to post-copy requires migration to be " "started with VIR_MIGRATE_POSTCOPY flag")); diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 431875c762..ad87aebd3b 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2406,8 +2406,6 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, migParams) < 0) goto stopjob; - priv->job.postcopyEnabled = flags & VIR_MIGRATE_POSTCOPY; - if (mig->nbd && flags & (VIR_MIGRATE_NON_SHARED_DISK | VIR_MIGRATE_NON_SHARED_INC) && virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NBD_SERVER)) { @@ -3346,8 +3344,6 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, migParams) < 0) goto error; - priv->job.postcopyEnabled = flags & VIR_MIGRATE_POSTCOPY; - if (migrate_flags & (QEMU_MONITOR_MIGRATE_NON_SHARED_DISK | QEMU_MONITOR_MIGRATE_NON_SHARED_INC)) { if (mig->nbd) { -- 2.17.0

On Wed, Apr 11, 2018 at 04:42:00PM +0200, Jiri Denemark wrote:
We store the flags passed to the API which started the migration. Let's use them instead of a separate bool to check if post-copy migration was requested.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_domain.c | 1 - src/qemu/qemu_domain.h | 1 - src/qemu/qemu_driver.c | 2 +- src/qemu/qemu_migration.c | 4 ---- 4 files changed, 1 insertion(+), 7 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

This will help us decide what to do when libvirtd is restarted while an async job is running. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_domain.c | 8 + .../migration-out-nbd-out.xml | 450 +++++++++++++++++- 2 files changed, 457 insertions(+), 1 deletion(-) mode change 120000 => 100644 tests/qemustatusxml2xmldata/migration-out-nbd-out.xml diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 71c3a917c1..8cd00576c8 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -2087,6 +2087,9 @@ qemuDomainObjPrivateXMLFormatJob(virBufferPtr buf, priv->job.phase)); } + if (priv->job.asyncJob != QEMU_ASYNC_JOB_NONE) + virBufferAsprintf(&attrBuf, " flags='0x%lx'", priv->job.apiFlags); + if (priv->job.asyncJob == QEMU_ASYNC_JOB_MIGRATION_OUT) { size_t i; virDomainDiskDefPtr disk; @@ -2382,6 +2385,11 @@ qemuDomainObjPrivateXMLParseJob(virDomainObjPtr vm, } } + if (virXPathULongHex("string(@flags)", ctxt, &priv->job.apiFlags) == -2) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid job flags")); + goto cleanup; + } + if ((n = virXPathNodeSet("./disk[@migrating='yes']", ctxt, &nodes)) < 0) goto cleanup; diff --git a/tests/qemustatusxml2xmldata/migration-out-nbd-out.xml b/tests/qemustatusxml2xmldata/migration-out-nbd-out.xml deleted file mode 120000 index a4830f04a8..0000000000 --- a/tests/qemustatusxml2xmldata/migration-out-nbd-out.xml +++ /dev/null @@ -1 +0,0 @@ -migration-out-nbd-in.xml \ No newline at end of file diff --git a/tests/qemustatusxml2xmldata/migration-out-nbd-out.xml b/tests/qemustatusxml2xmldata/migration-out-nbd-out.xml new file mode 100644 index 0000000000..05da1f81c6 --- /dev/null +++ b/tests/qemustatusxml2xmldata/migration-out-nbd-out.xml @@ -0,0 +1,449 @@ +<domstatus state='running' reason='booted' pid='15433'> + <taint flag='high-privileges'/> + <monitor path='/var/lib/libvirt/qemu/domain-4-upstream/monitor.sock' json='1' type='unix'/> + <vcpus> + <vcpu id='0' pid='15449'/> + <vcpu id='1' pid='15450'/> + </vcpus> + <qemuCaps> + <flag name='kvm'/> + <flag name='mem-path'/> + <flag name='drive-serial'/> + <flag name='monitor-json'/> + <flag name='sdl'/> + <flag name='netdev'/> + <flag name='rtc'/> + <flag name='vhost-net'/> + <flag name='no-hpet'/> + <flag name='no-kvm-pit'/> + <flag name='nodefconfig'/> + <flag name='boot-menu'/> + <flag name='fsdev'/> + <flag name='name-process'/> + <flag name='smbios-type'/> + <flag name='spice'/> + <flag name='vga-none'/> + <flag name='boot-index'/> + <flag name='hda-duplex'/> + <flag name='drive-aio'/> + <flag name='ccid-emulated'/> + <flag name='ccid-passthru'/> + <flag name='chardev-spicevmc'/> + <flag name='virtio-tx-alg'/> + <flag name='pci-multifunction'/> + <flag name='virtio-blk-pci.ioeventfd'/> + <flag name='sga'/> + <flag name='virtio-blk-pci.event_idx'/> + <flag name='virtio-net-pci.event_idx'/> + <flag name='cache-directsync'/> + <flag name='piix3-usb-uhci'/> + <flag name='piix4-usb-uhci'/> + <flag name='usb-ehci'/> + <flag name='ich9-usb-ehci1'/> + <flag name='vt82c686b-usb-uhci'/> + <flag name='pci-ohci'/> + <flag name='usb-redir'/> + <flag name='usb-hub'/> + <flag name='no-shutdown'/> + <flag name='cache-unsafe'/> + <flag name='ich9-ahci'/> + <flag name='no-acpi'/> + <flag name='fsdev-readonly'/> + <flag name='virtio-blk-pci.scsi'/> + <flag name='drive-copy-on-read'/> + <flag name='fsdev-writeout'/> + <flag name='drive-iotune'/> + <flag name='system_wakeup'/> + <flag name='scsi-disk.channel'/> + <flag name='scsi-block'/> + <flag name='transaction'/> + <flag name='block-job-async'/> + <flag name='scsi-cd'/> + <flag name='ide-cd'/> + <flag name='no-user-config'/> + <flag name='hda-micro'/> + <flag name='dump-guest-memory'/> + <flag name='nec-usb-xhci'/> + <flag name='balloon-event'/> + <flag name='bridge'/> + <flag name='lsi'/> + <flag name='virtio-scsi-pci'/> + <flag name='blockio'/> + <flag name='disable-s3'/> + <flag name='disable-s4'/> + <flag name='usb-redir.filter'/> + <flag name='ide-drive.wwn'/> + <flag name='scsi-disk.wwn'/> + <flag name='seccomp-sandbox'/> + <flag name='reboot-timeout'/> + <flag name='dump-guest-core'/> + <flag name='seamless-migration'/> + <flag name='block-commit'/> + <flag name='vnc'/> + <flag name='drive-mirror'/> + <flag name='usb-redir.bootindex'/> + <flag name='usb-host.bootindex'/> + <flag name='blockdev-snapshot-sync'/> + <flag name='qxl'/> + <flag name='VGA'/> + <flag name='cirrus-vga'/> + <flag name='vmware-svga'/> + <flag name='device-video-primary'/> + <flag name='usb-serial'/> + <flag name='usb-net'/> + <flag name='add-fd'/> + <flag name='nbd-server'/> + <flag name='virtio-rng'/> + <flag name='rng-random'/> + <flag name='rng-egd'/> + <flag name='dtb'/> + <flag name='megasas'/> + <flag name='ipv6-migration'/> + <flag name='machine-opt'/> + <flag name='machine-usb-opt'/> + <flag name='tpm-passthrough'/> + <flag name='tpm-tis'/> + <flag name='pci-bridge'/> + <flag name='vfio-pci'/> + <flag name='vfio-pci.bootindex'/> + <flag name='scsi-generic'/> + <flag name='scsi-generic.bootindex'/> + <flag name='mem-merge'/> + <flag name='vnc-websocket'/> + <flag name='drive-discard'/> + <flag name='mlock'/> + <flag name='vnc-share-policy'/> + <flag name='device-del-event'/> + <flag name='dmi-to-pci-bridge'/> + <flag name='i440fx-pci-hole64-size'/> + <flag name='q35-pci-hole64-size'/> + <flag name='usb-storage'/> + <flag name='usb-storage.removable'/> + <flag name='virtio-mmio'/> + <flag name='ich9-intel-hda'/> + <flag name='kvm-pit-lost-tick-policy'/> + <flag name='boot-strict'/> + <flag name='pvpanic'/> + <flag name='spice-file-xfer-disable'/> + <flag name='spiceport'/> + <flag name='usb-kbd'/> + <flag name='host-pci-multidomain'/> + <flag name='msg-timestamp'/> + <flag name='active-commit'/> + <flag name='change-backing-file'/> + <flag name='memory-backend-ram'/> + <flag name='numa'/> + <flag name='memory-backend-file'/> + <flag name='usb-audio'/> + <flag name='rtc-reset-reinjection'/> + <flag name='splash-timeout'/> + <flag name='iothread'/> + <flag name='migrate-rdma'/> + <flag name='ivshmem'/> + <flag name='drive-iotune-max'/> + <flag name='VGA.vgamem_mb'/> + <flag name='vmware-svga.vgamem_mb'/> + <flag name='qxl.vgamem_mb'/> + <flag name='pc-dimm'/> + <flag name='machine-vmport-opt'/> + <flag name='aes-key-wrap'/> + <flag name='dea-key-wrap'/> + <flag name='pci-serial'/> + <flag name='vhost-user-multiqueue'/> + <flag name='migration-event'/> + <flag name='ioh3420'/> + <flag name='x3130-upstream'/> + <flag name='xio3130-downstream'/> + <flag name='rtl8139'/> + <flag name='e1000'/> + <flag name='virtio-net'/> + <flag name='gic-version'/> + <flag name='incoming-defer'/> + <flag name='virtio-gpu'/> + <flag name='virtio-gpu.virgl'/> + <flag name='virtio-keyboard'/> + <flag name='virtio-mouse'/> + <flag name='virtio-tablet'/> + <flag name='virtio-input-host'/> + <flag name='chardev-file-append'/> + <flag name='ich9-disable-s3'/> + <flag name='ich9-disable-s4'/> + <flag name='vserport-change-event'/> + <flag name='virtio-balloon-pci.deflate-on-oom'/> + <flag name='mptsas1068'/> + <flag name='qxl.vram64_size_mb'/> + <flag name='chardev-logfile'/> + <flag name='debug-threads'/> + <flag name='secret'/> + <flag name='pxb'/> + <flag name='pxb-pcie'/> + <flag name='device-tray-moved-event'/> + <flag name='nec-usb-xhci-ports'/> + <flag name='virtio-scsi-pci.iothread'/> + <flag name='name-guest'/> + <flag name='qxl.max_outputs'/> + <flag name='spice-unix'/> + <flag name='drive-detect-zeroes'/> + <flag name='tls-creds-x509'/> + <flag name='display'/> + <flag name='intel-iommu'/> + <flag name='smm'/> + <flag name='virtio-pci-disable-legacy'/> + <flag name='query-hotpluggable-cpus'/> + <flag name='virtio-net.rx_queue_size'/> + <flag name='virtio-vga'/> + <flag name='drive-iotune-max-length'/> + <flag name='ivshmem-plain'/> + <flag name='ivshmem-doorbell'/> + <flag name='query-qmp-schema'/> + <flag name='gluster.debug_level'/> + <flag name='vhost-scsi'/> + <flag name='drive-iotune-group'/> + <flag name='query-cpu-model-expansion'/> + <flag name='virtio-net.host_mtu'/> + <flag name='nvdimm'/> + <flag name='pcie-root-port'/> + <flag name='query-cpu-definitions'/> + <flag name='block-write-threshold'/> + <flag name='query-named-block-nodes'/> + <flag name='cpu-cache'/> + <flag name='qemu-xhci'/> + <flag name='kernel-irqchip'/> + <flag name='kernel-irqchip.split'/> + <flag name='intel-iommu.intremap'/> + <flag name='intel-iommu.caching-mode'/> + <flag name='intel-iommu.eim'/> + <flag name='intel-iommu.device-iotlb'/> + <flag name='virtio.iommu_platform'/> + <flag name='virtio.ats'/> + <flag name='loadparm'/> + <flag name='vnc-multi-servers'/> + <flag name='virtio-net.tx_queue_size'/> + <flag name='chardev-reconnect'/> + <flag name='virtio-gpu.max_outputs'/> + <flag name='vxhs'/> + <flag name='virtio-blk.num-queues'/> + <flag name='vmcoreinfo'/> + <flag name='numa.dist'/> + <flag name='disk-share-rw'/> + <flag name='iscsi.password-secret'/> + <flag name='isa-serial'/> + <flag name='dump-completed'/> + </qemuCaps> + <job type='none' async='migration out' phase='perform3' flags='0x0'> + <disk dev='vdb' migrating='yes'/> + <disk dev='hda' migrating='no'/> + </job> + <devices> + <device alias='rng0'/> + <device alias='sound0-codec0'/> + <device alias='virtio-disk1'/> + <device alias='virtio-serial0'/> + <device alias='video0'/> + <device alias='serial0'/> + <device alias='sound0'/> + <device alias='balloon0'/> + <device alias='channel1'/> + <device alias='channel0'/> + <device alias='net0'/> + <device alias='input0'/> + <device alias='redir0'/> + <device alias='redir1'/> + <device alias='scsi0'/> + <device alias='usb'/> + <device alias='ide0-0-0'/> + </devices> + <numad nodeset='0' cpuset='0-7'/> + <libDir path='/var/lib/libvirt/qemu/domain-4-upstream'/> + <channelTargetDir path='/var/lib/libvirt/qemu/channel/target/domain-4-upstream'/> + <chardevStdioLogd/> + <allowReboot value='yes'/> + <blockjobs active='no'/> + <domain type='kvm' id='4'> + <name>upstream</name> + <uuid>dcf47dbd-46d1-4d5b-b442-262a806a333a</uuid> + <memory unit='KiB'>1024000</memory> + <currentMemory unit='KiB'>1024000</currentMemory> + <memoryBacking> + <access mode='shared'/> + </memoryBacking> + <vcpu placement='auto' current='2'>8</vcpu> + <numatune> + <memory mode='strict' placement='auto'/> + </numatune> + <resource> + <partition>/machine</partition> + </resource> + <os> + <type arch='x86_64' machine='pc-i440fx-2.9'>hvm</type> + <bootmenu enable='yes'/> + </os> + <features> + <acpi/> + <apic/> + <vmport state='off'/> + </features> + <cpu> + <numa> + <cell id='0' cpus='0,2,4,6' memory='512000' unit='KiB'/> + <cell id='1' cpus='1,3,5,7' memory='512000' unit='KiB'/> + </numa> + </cpu> + <clock offset='utc'> + <timer name='rtc' tickpolicy='catchup'/> + <timer name='pit' tickpolicy='delay'/> + <timer name='hpet' present='no'/> + </clock> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <pm> + <suspend-to-mem enabled='no'/> + <suspend-to-disk enabled='no'/> + </pm> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <disk type='file' device='disk'> + <driver name='qemu' type='qcow2' discard='unmap' detect_zeroes='on'/> + <source file='/var/lib/libvirt/images/a.qcow2'/> + <backingStore type='file' index='1'> + <format type='qcow2'/> + <source file='/var/lib/libvirt/images/base.qcow2'> + <privateData> + <relPath>base.qcow2</relPath> + </privateData> + </source> + <backingStore/> + </backingStore> + <target dev='vdb' bus='virtio'/> + <alias name='virtio-disk1'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x0b' function='0x0'/> + </disk> + <disk type='file' device='cdrom'> + <driver name='qemu' type='raw'/> + <source file='/var/lib/libvirt/images/systemrescuecd-x86-4.9.5.iso'/> + <backingStore/> + <target dev='hda' bus='ide'/> + <readonly/> + <boot order='1'/> + <alias name='ide0-0-0'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0' model='ich9-ehci1'> + <alias name='usb'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x7'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci1'> + <alias name='usb'/> + <master startport='0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0' multifunction='on'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci2'> + <alias name='usb'/> + <master startport='2'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x1'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci3'> + <alias name='usb'/> + <master startport='4'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pci-root'> + <alias name='pci.0'/> + </controller> + <controller type='virtio-serial' index='0'> + <alias name='virtio-serial0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> + </controller> + <controller type='ide' index='0'> + <alias name='ide'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='scsi' index='0' model='lsilogic'> + <alias name='scsi0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/> + </controller> + <controller type='fdc' index='0'> + <alias name='fdc0'/> + </controller> + <interface type='network'> + <mac address='52:54:00:36:bd:3b'/> + <source network='default'/> + <actual type='network'> + <source bridge='virbr0'/> + </actual> + <target dev='vnet0'/> + <model type='virtio'/> + <alias name='net0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </interface> + <serial type='pty'> + <source path='/dev/pts/49'/> + <target type='isa-serial' port='0'> + <model name='isa-serial'/> + </target> + <alias name='serial0'/> + </serial> + <console type='pty' tty='/dev/pts/49'> + <source path='/dev/pts/49'/> + <target type='serial' port='0'/> + <alias name='serial0'/> + </console> + <channel type='unix'> + <source mode='bind' path='/var/lib/libvirt/qemu/channel/target/domain-4-upstream/org.qemu.guest_agent.0'/> + <target type='virtio' name='org.qemu.guest_agent.0' state='disconnected'/> + <alias name='channel0'/> + <address type='virtio-serial' controller='0' bus='0' port='1'/> + </channel> + <channel type='spicevmc'> + <target type='virtio' name='com.redhat.spice.0' state='disconnected'/> + <alias name='channel1'/> + <address type='virtio-serial' controller='0' bus='0' port='2'/> + </channel> + <input type='tablet' bus='usb'> + <alias name='input0'/> + <address type='usb' bus='0' port='1'/> + </input> + <input type='mouse' bus='ps2'> + <alias name='input1'/> + </input> + <input type='keyboard' bus='ps2'> + <alias name='input2'/> + </input> + <graphics type='spice' port='5900' autoport='yes' listen='127.0.0.1'> + <listen type='address' address='127.0.0.1' fromConfig='1' autoGenerated='no'/> + <image compression='off'/> + </graphics> + <sound model='ich6'> + <alias name='sound0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> + </sound> + <video> + <model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/> + <alias name='video0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> + </video> + <redirdev bus='usb' type='spicevmc'> + <alias name='redir0'/> + <address type='usb' bus='0' port='2'/> + </redirdev> + <redirdev bus='usb' type='spicevmc'> + <alias name='redir1'/> + <address type='usb' bus='0' port='3'/> + </redirdev> + <memballoon model='virtio'> + <alias name='balloon0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/> + </memballoon> + <rng model='virtio'> + <backend model='random'>/dev/random</backend> + <alias name='rng0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> + </rng> + </devices> + <seclabel type='dynamic' model='dac' relabel='yes'> + <label>+0:+0</label> + <imagelabel>+0:+0</imagelabel> + </seclabel> + </domain> +</domstatus> -- 2.17.0

On Wed, Apr 11, 2018 at 04:42:01PM +0200, Jiri Denemark wrote:
This will help us decide what to do when libvirtd is restarted while an async job is running.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_domain.c | 8 + .../migration-out-nbd-out.xml | 450 +++++++++++++++++- 2 files changed, 457 insertions(+), 1 deletion(-) mode change 120000 => 100644 tests/qemustatusxml2xmldata/migration-out-nbd-out.xml
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Trying to delete the non-existent TLS objects results in ugly error messages in the log, which could easily confuse users. Let's avoid this confusion by not trying to delete the objects if we were not asked to enable TLS migration and thus we didn't created the objects anyway. This patch restores the behavior to the state before "qemu: Reset all migration parameters". Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 12 ++++++------ src/qemu/qemu_migration_params.c | 18 ++++++++++++------ src/qemu/qemu_migration_params.h | 3 ++- src/qemu/qemu_process.c | 6 ++++-- 4 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index ad87aebd3b..bee5fe983e 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -1771,7 +1771,7 @@ qemuMigrationSrcCleanup(virDomainObjPtr vm, " domain was successfully started on destination or not", vm->def->name); qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, - priv->job.migParams); + priv->job.migParams, priv->job.apiFlags); /* clear the job and let higher levels decide what to do */ qemuDomainObjDiscardAsyncJob(driver, vm); break; @@ -2500,7 +2500,7 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, stopjob: qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN, - priv->job.migParams); + priv->job.migParams, priv->job.apiFlags); if (stopProcess) { unsigned int stopFlags = VIR_QEMU_PROCESS_STOP_MIGRATED; @@ -2870,7 +2870,7 @@ qemuMigrationSrcConfirmPhase(virQEMUDriverPtr driver, } qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, - priv->job.migParams); + priv->job.migParams, priv->job.apiFlags); if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0) VIR_WARN("Failed to save status on vm %s", vm->def->name); @@ -4497,7 +4497,7 @@ qemuMigrationSrcPerformJob(virQEMUDriverPtr driver, */ if (!v3proto && ret < 0) qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, - priv->job.migParams); + priv->job.migParams, priv->job.apiFlags); if (qemuMigrationSrcRestoreDomainState(driver, vm)) { event = virDomainEventLifecycleNewFromObj(vm, @@ -4586,7 +4586,7 @@ qemuMigrationSrcPerformPhase(virQEMUDriverPtr driver, endjob: if (ret < 0) { qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, - priv->job.migParams); + priv->job.migParams, priv->job.apiFlags); qemuMigrationJobFinish(driver, vm); } else { qemuMigrationJobContinue(vm); @@ -5044,7 +5044,7 @@ qemuMigrationDstFinish(virQEMUDriverPtr driver, } qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN, - priv->job.migParams); + priv->job.migParams, priv->job.apiFlags); qemuMigrationJobFinish(driver, vm); if (!virDomainObjIsActive(vm)) diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 8af6d8ad0e..4f3b239637 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -899,6 +899,7 @@ qemuMigrationParamsDisableTLS(virDomainObjPtr vm, * @driver: pointer to qemu driver * @vm: domain object * @asyncJob: migration job to join + * @apiFlags: API flags used to start the migration * * Deconstruct all the setup possibly done for TLS - delete the TLS and * security objects, free the secinfo, and reset the migration params to "". @@ -907,13 +908,16 @@ static void qemuMigrationParamsResetTLS(virQEMUDriverPtr driver, virDomainObjPtr vm, int asyncJob, - qemuMigrationParamsPtr origParams) + qemuMigrationParamsPtr origParams, + unsigned long apiFlags) { char *tlsAlias = NULL; char *secAlias = NULL; - /* If QEMU does not support TLS migration we didn't set the aliases. */ - if (!origParams->params[QEMU_MIGRATION_PARAM_TLS_CREDS].set) + /* There's nothing to do if QEMU does not support TLS migration or we were + * not asked to enable it. */ + if (!origParams->params[QEMU_MIGRATION_PARAM_TLS_CREDS].set || + !(apiFlags & VIR_MIGRATE_TLS)) return; /* NB: If either or both fail to allocate memory we can still proceed @@ -1081,11 +1085,13 @@ void qemuMigrationParamsReset(virQEMUDriverPtr driver, virDomainObjPtr vm, int asyncJob, - qemuMigrationParamsPtr origParams) + qemuMigrationParamsPtr origParams, + unsigned long apiFlags) { virErrorPtr err = virSaveLastError(); - VIR_DEBUG("Resetting migration parameters %p", origParams); + VIR_DEBUG("Resetting migration parameters %p, flags 0x%lx", + origParams, apiFlags); if (!virDomainObjIsActive(vm) || !origParams) goto cleanup; @@ -1093,7 +1099,7 @@ qemuMigrationParamsReset(virQEMUDriverPtr driver, if (qemuMigrationParamsApply(driver, vm, asyncJob, origParams) < 0) goto cleanup; - qemuMigrationParamsResetTLS(driver, vm, asyncJob, origParams); + qemuMigrationParamsResetTLS(driver, vm, asyncJob, origParams, apiFlags); cleanup: if (err) { diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index 99dde0ad3c..c3484ed1c0 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -133,7 +133,8 @@ void qemuMigrationParamsReset(virQEMUDriverPtr driver, virDomainObjPtr vm, int asyncJob, - qemuMigrationParamsPtr origParams); + qemuMigrationParamsPtr origParams, + unsigned long apiFlags); void qemuMigrationParamsFormat(virBufferPtr buf, diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index b4bb7eb8a5..ab3580126a 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3085,7 +3085,8 @@ qemuProcessRecoverMigrationIn(virQEMUDriverPtr driver, break; } - qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_NONE, job->migParams); + qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_NONE, + job->migParams, job->apiFlags); return 0; } @@ -3179,7 +3180,8 @@ qemuProcessRecoverMigrationOut(virQEMUDriverPtr driver, } } - qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_NONE, job->migParams); + qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_NONE, + job->migParams, job->apiFlags); return 0; } -- 2.17.0

On Wed, Apr 11, 2018 at 04:42:02PM +0200, Jiri Denemark wrote:
Trying to delete the non-existent TLS objects results in ugly error messages in the log, which could easily confuse users. Let's avoid this confusion by not trying to delete the objects if we were not asked to enable TLS migration and thus we didn't created the objects anyway.
This patch restores the behavior to the state before "qemu: Reset all migration parameters".
Finally. The suspense was killing me.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 12 ++++++------ src/qemu/qemu_migration_params.c | 18 ++++++++++++------ src/qemu/qemu_migration_params.h | 3 ++- src/qemu/qemu_process.c | 6 ++++-- 4 files changed, 24 insertions(+), 15 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- .../migration-in-params-in.xml | 400 +++++++++++++++++ .../migration-in-params-out.xml | 1 + .../migration-out-params-in.xml | 414 ++++++++++++++++++ .../migration-out-params-out.xml | 1 + tests/qemuxml2xmltest.c | 2 + 5 files changed, 818 insertions(+) create mode 100644 tests/qemustatusxml2xmldata/migration-in-params-in.xml create mode 120000 tests/qemustatusxml2xmldata/migration-in-params-out.xml create mode 100644 tests/qemustatusxml2xmldata/migration-out-params-in.xml create mode 120000 tests/qemustatusxml2xmldata/migration-out-params-out.xml diff --git a/tests/qemustatusxml2xmldata/migration-in-params-in.xml b/tests/qemustatusxml2xmldata/migration-in-params-in.xml new file mode 100644 index 0000000000..b0caa34e61 --- /dev/null +++ b/tests/qemustatusxml2xmldata/migration-in-params-in.xml @@ -0,0 +1,400 @@ +<domstatus state='paused' reason='migration' pid='2296'> + <taint flag='high-privileges'/> + <taint flag='host-cpu'/> + <monitor path='/var/lib/libvirt/qemu/domain-1-nest/monitor.sock' json='1' type='unix'/> + <namespaces> + <mount/> + </namespaces> + <vcpus> + <vcpu id='0' pid='2329'/> + <vcpu id='1' pid='2330'/> + </vcpus> + <qemuCaps> + <flag name='kvm'/> + <flag name='mem-path'/> + <flag name='drive-serial'/> + <flag name='monitor-json'/> + <flag name='sdl'/> + <flag name='netdev'/> + <flag name='rtc'/> + <flag name='vhost-net'/> + <flag name='no-hpet'/> + <flag name='no-kvm-pit'/> + <flag name='pci-configfd'/> + <flag name='nodefconfig'/> + <flag name='boot-menu'/> + <flag name='fsdev'/> + <flag name='name-process'/> + <flag name='smbios-type'/> + <flag name='spice'/> + <flag name='vga-none'/> + <flag name='boot-index'/> + <flag name='hda-duplex'/> + <flag name='drive-aio'/> + <flag name='pci-bootindex'/> + <flag name='ccid-emulated'/> + <flag name='ccid-passthru'/> + <flag name='chardev-spicevmc'/> + <flag name='virtio-tx-alg'/> + <flag name='pci-multifunction'/> + <flag name='virtio-blk-pci.ioeventfd'/> + <flag name='sga'/> + <flag name='virtio-blk-pci.event_idx'/> + <flag name='virtio-net-pci.event_idx'/> + <flag name='cache-directsync'/> + <flag name='piix3-usb-uhci'/> + <flag name='piix4-usb-uhci'/> + <flag name='usb-ehci'/> + <flag name='ich9-usb-ehci1'/> + <flag name='vt82c686b-usb-uhci'/> + <flag name='pci-ohci'/> + <flag name='usb-redir'/> + <flag name='usb-hub'/> + <flag name='no-shutdown'/> + <flag name='cache-unsafe'/> + <flag name='ich9-ahci'/> + <flag name='no-acpi'/> + <flag name='fsdev-readonly'/> + <flag name='virtio-blk-pci.scsi'/> + <flag name='drive-copy-on-read'/> + <flag name='fsdev-writeout'/> + <flag name='drive-iotune'/> + <flag name='system_wakeup'/> + <flag name='scsi-disk.channel'/> + <flag name='scsi-block'/> + <flag name='transaction'/> + <flag name='block-job-async'/> + <flag name='scsi-cd'/> + <flag name='ide-cd'/> + <flag name='no-user-config'/> + <flag name='hda-micro'/> + <flag name='dump-guest-memory'/> + <flag name='nec-usb-xhci'/> + <flag name='balloon-event'/> + <flag name='bridge'/> + <flag name='lsi'/> + <flag name='virtio-scsi-pci'/> + <flag name='blockio'/> + <flag name='disable-s3'/> + <flag name='disable-s4'/> + <flag name='usb-redir.filter'/> + <flag name='ide-drive.wwn'/> + <flag name='scsi-disk.wwn'/> + <flag name='seccomp-sandbox'/> + <flag name='reboot-timeout'/> + <flag name='dump-guest-core'/> + <flag name='seamless-migration'/> + <flag name='block-commit'/> + <flag name='vnc'/> + <flag name='drive-mirror'/> + <flag name='usb-redir.bootindex'/> + <flag name='usb-host.bootindex'/> + <flag name='blockdev-snapshot-sync'/> + <flag name='qxl'/> + <flag name='VGA'/> + <flag name='cirrus-vga'/> + <flag name='vmware-svga'/> + <flag name='device-video-primary'/> + <flag name='usb-serial'/> + <flag name='usb-net'/> + <flag name='add-fd'/> + <flag name='nbd-server'/> + <flag name='virtio-rng'/> + <flag name='rng-random'/> + <flag name='rng-egd'/> + <flag name='dtb'/> + <flag name='megasas'/> + <flag name='ipv6-migration'/> + <flag name='machine-opt'/> + <flag name='machine-usb-opt'/> + <flag name='tpm-passthrough'/> + <flag name='tpm-tis'/> + <flag name='pci-bridge'/> + <flag name='vfio-pci'/> + <flag name='vfio-pci.bootindex'/> + <flag name='scsi-generic'/> + <flag name='scsi-generic.bootindex'/> + <flag name='mem-merge'/> + <flag name='vnc-websocket'/> + <flag name='drive-discard'/> + <flag name='mlock'/> + <flag name='vnc-share-policy'/> + <flag name='device-del-event'/> + <flag name='dmi-to-pci-bridge'/> + <flag name='i440fx-pci-hole64-size'/> + <flag name='q35-pci-hole64-size'/> + <flag name='usb-storage'/> + <flag name='usb-storage.removable'/> + <flag name='virtio-mmio'/> + <flag name='ich9-intel-hda'/> + <flag name='kvm-pit-lost-tick-policy'/> + <flag name='boot-strict'/> + <flag name='pvpanic'/> + <flag name='spice-file-xfer-disable'/> + <flag name='spiceport'/> + <flag name='usb-kbd'/> + <flag name='host-pci-multidomain'/> + <flag name='msg-timestamp'/> + <flag name='active-commit'/> + <flag name='change-backing-file'/> + <flag name='memory-backend-ram'/> + <flag name='numa'/> + <flag name='memory-backend-file'/> + <flag name='usb-audio'/> + <flag name='rtc-reset-reinjection'/> + <flag name='splash-timeout'/> + <flag name='iothread'/> + <flag name='migrate-rdma'/> + <flag name='ivshmem'/> + <flag name='drive-iotune-max'/> + <flag name='VGA.vgamem_mb'/> + <flag name='vmware-svga.vgamem_mb'/> + <flag name='qxl.vgamem_mb'/> + <flag name='pc-dimm'/> + <flag name='machine-vmport-opt'/> + <flag name='aes-key-wrap'/> + <flag name='dea-key-wrap'/> + <flag name='pci-serial'/> + <flag name='vhost-user-multiqueue'/> + <flag name='migration-event'/> + <flag name='ioh3420'/> + <flag name='x3130-upstream'/> + <flag name='xio3130-downstream'/> + <flag name='rtl8139'/> + <flag name='e1000'/> + <flag name='virtio-net'/> + <flag name='gic-version'/> + <flag name='incoming-defer'/> + <flag name='virtio-gpu'/> + <flag name='virtio-gpu.virgl'/> + <flag name='virtio-keyboard'/> + <flag name='virtio-mouse'/> + <flag name='virtio-tablet'/> + <flag name='virtio-input-host'/> + <flag name='chardev-file-append'/> + <flag name='ich9-disable-s3'/> + <flag name='ich9-disable-s4'/> + <flag name='vserport-change-event'/> + <flag name='virtio-balloon-pci.deflate-on-oom'/> + <flag name='mptsas1068'/> + <flag name='spice-gl'/> + <flag name='qxl.vram64_size_mb'/> + <flag name='chardev-logfile'/> + <flag name='debug-threads'/> + <flag name='secret'/> + <flag name='pxb'/> + <flag name='pxb-pcie'/> + <flag name='device-tray-moved-event'/> + <flag name='nec-usb-xhci-ports'/> + <flag name='virtio-scsi-pci.iothread'/> + <flag name='name-guest'/> + <flag name='qxl.max_outputs'/> + <flag name='spice-unix'/> + <flag name='drive-detect-zeroes'/> + <flag name='tls-creds-x509'/> + <flag name='display'/> + <flag name='intel-iommu'/> + <flag name='smm'/> + <flag name='virtio-pci-disable-legacy'/> + <flag name='query-hotpluggable-cpus'/> + <flag name='virtio-net.rx_queue_size'/> + <flag name='virtio-vga'/> + <flag name='drive-iotune-max-length'/> + <flag name='ivshmem-plain'/> + <flag name='ivshmem-doorbell'/> + <flag name='query-qmp-schema'/> + <flag name='gluster.debug_level'/> + <flag name='vhost-scsi'/> + <flag name='drive-iotune-group'/> + <flag name='query-cpu-model-expansion'/> + <flag name='virtio-net.host_mtu'/> + <flag name='spice-rendernode'/> + <flag name='nvdimm'/> + <flag name='pcie-root-port'/> + <flag name='query-cpu-definitions'/> + <flag name='block-write-threshold'/> + <flag name='query-named-block-nodes'/> + <flag name='cpu-cache'/> + <flag name='qemu-xhci'/> + <flag name='kernel-irqchip'/> + <flag name='kernel-irqchip.split'/> + <flag name='intel-iommu.intremap'/> + <flag name='intel-iommu.caching-mode'/> + <flag name='intel-iommu.eim'/> + <flag name='intel-iommu.device-iotlb'/> + <flag name='virtio.iommu_platform'/> + <flag name='virtio.ats'/> + <flag name='loadparm'/> + <flag name='vnc-multi-servers'/> + <flag name='virtio-net.tx_queue_size'/> + <flag name='chardev-reconnect'/> + <flag name='virtio-gpu.max_outputs'/> + <flag name='vxhs'/> + <flag name='virtio-blk.num-queues'/> + <flag name='numa.dist'/> + <flag name='disk-share-rw'/> + <flag name='iscsi.password-secret'/> + <flag name='isa-serial'/> + <flag name='dump-completed'/> + </qemuCaps> + <job type='none' async='migration in' phase='prepare' flags='0x900'> + <migParams> + <param name='compress-level' value='1'/> + <param name='compress-threads' value='8'/> + <param name='decompress-threads' value='2'/> + <param name='cpu-throttle-initial' value='20'/> + <param name='cpu-throttle-increment' value='10'/> + <param name='tls-creds' value=''/> + <param name='tls-hostname' value=''/> + <param name='max-bandwidth' value='33554432'/> + <param name='downtime-limit' value='300'/> + <param name='block-incremental' value='no'/> + </migParams> + </job> + <libDir path='/var/lib/libvirt/qemu/domain-1-nest'/> + <channelTargetDir path='/var/lib/libvirt/qemu/channel/target/domain-1-nest'/> + <chardevStdioLogd/> + <allowReboot value='yes'/> + <blockjobs active='no'/> + <domain type='kvm' id='1'> + <name>nest</name> + <uuid>994cee0d-2a70-4937-9693-0431e39d20f7</uuid> + <description>virt-builder</description> + <memory unit='KiB'>524288</memory> + <currentMemory unit='KiB'>524288</currentMemory> + <vcpu placement='static'>2</vcpu> + <resource> + <partition>/machine</partition> + </resource> + <os> + <type arch='x86_64' machine='pc-i440fx-2.10'>hvm</type> + <bios useserial='yes'/> + </os> + <features> + <acpi/> + <apic/> + <vmport state='off'/> + </features> + <cpu mode='host-passthrough' check='none'/> + <clock offset='utc'> + <timer name='rtc' tickpolicy='catchup'/> + <timer name='pit' tickpolicy='delay'/> + <timer name='hpet' present='no'/> + </clock> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <pm> + <suspend-to-mem enabled='no'/> + <suspend-to-disk enabled='no'/> + </pm> + <devices> + <emulator>/usr/bin/qemu-kvm</emulator> + <disk type='file' device='disk'> + <driver name='qemu' type='qcow2' cache='none' io='native'/> + <source file='/vm/nest.qcow'/> + <backingStore/> + <target dev='vda' bus='virtio'/> + <boot order='1'/> + <alias name='virtio-disk0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> + </disk> + <controller type='usb' index='0' model='ich9-ehci1'> + <alias name='usb'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x7'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci1'> + <alias name='usb'/> + <master startport='0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0' multifunction='on'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci2'> + <alias name='usb'/> + <master startport='2'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x1'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci3'> + <alias name='usb'/> + <master startport='4'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x2'/> + </controller> + <controller type='virtio-serial' index='0'> + <alias name='virtio-serial0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> + </controller> + <controller type='pci' index='0' model='pci-root'> + <alias name='pci.0'/> + </controller> + <interface type='network'> + <mac address='52:54:00:59:59:91'/> + <source network='default'/> + <actual type='network'> + <source bridge='virbr0'/> + </actual> + <target dev='vnet0'/> + <model type='virtio'/> + <alias name='net0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </interface> + <serial type='pty'> + <source path='/dev/pts/1'/> + <target type='isa-serial' port='0'> + <model name='isa-serial'/> + </target> + <alias name='serial0'/> + </serial> + <console type='pty' tty='/dev/pts/1'> + <source path='/dev/pts/1'/> + <target type='serial' port='0'/> + <alias name='serial0'/> + </console> + <channel type='unix'> + <source mode='bind' path='/var/lib/libvirt/qemu/channel/target/domain-1-nest/org.qemu.guest_agent.0'/> + <target type='virtio' name='org.qemu.guest_agent.0' state='disconnected'/> + <alias name='channel0'/> + <address type='virtio-serial' controller='0' bus='0' port='1'/> + </channel> + <channel type='spicevmc'> + <target type='virtio' name='com.redhat.spice.0' state='disconnected'/> + <alias name='channel1'/> + <address type='virtio-serial' controller='0' bus='0' port='2'/> + </channel> + <input type='tablet' bus='usb'> + <alias name='input0'/> + <address type='usb' bus='0' port='1'/> + </input> + <input type='mouse' bus='ps2'> + <alias name='input1'/> + </input> + <input type='keyboard' bus='ps2'> + <alias name='input2'/> + </input> + <graphics type='spice' port='5900' autoport='yes' listen='0.0.0.0'> + <listen type='address' address='0.0.0.0' fromConfig='1' autoGenerated='no'/> + <image compression='off'/> + </graphics> + <video> + <model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/> + <alias name='video0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> + </video> + <redirdev bus='usb' type='spicevmc'> + <alias name='redir0'/> + <address type='usb' bus='0' port='2'/> + </redirdev> + <redirdev bus='usb' type='spicevmc'> + <alias name='redir1'/> + <address type='usb' bus='0' port='3'/> + </redirdev> + <memballoon model='none'/> + </devices> + <seclabel type='dynamic' model='selinux' relabel='yes'> + <label>unconfined_u:unconfined_r:svirt_t:s0:c708,c793</label> + <imagelabel>unconfined_u:object_r:svirt_image_t:s0:c708,c793</imagelabel> + </seclabel> + <seclabel type='dynamic' model='dac' relabel='yes'> + <label>+0:+0</label> + <imagelabel>+0:+0</imagelabel> + </seclabel> + </domain> +</domstatus> diff --git a/tests/qemustatusxml2xmldata/migration-in-params-out.xml b/tests/qemustatusxml2xmldata/migration-in-params-out.xml new file mode 120000 index 0000000000..384747c5b1 --- /dev/null +++ b/tests/qemustatusxml2xmldata/migration-in-params-out.xml @@ -0,0 +1 @@ +migration-in-params-in.xml \ No newline at end of file diff --git a/tests/qemustatusxml2xmldata/migration-out-params-in.xml b/tests/qemustatusxml2xmldata/migration-out-params-in.xml new file mode 100644 index 0000000000..17649796ff --- /dev/null +++ b/tests/qemustatusxml2xmldata/migration-out-params-in.xml @@ -0,0 +1,414 @@ +<domstatus state='paused' reason='migration' pid='21586'> + <taint flag='high-privileges'/> + <taint flag='host-cpu'/> + <monitor path='/var/lib/libvirt/qemu/domain-7-nest/monitor.sock' json='1' type='unix'/> + <namespaces> + <mount/> + </namespaces> + <vcpus> + <vcpu id='0' pid='21616'/> + <vcpu id='1' pid='21617'/> + </vcpus> + <qemuCaps> + <flag name='kvm'/> + <flag name='mem-path'/> + <flag name='drive-serial'/> + <flag name='monitor-json'/> + <flag name='sdl'/> + <flag name='netdev'/> + <flag name='rtc'/> + <flag name='vhost-net'/> + <flag name='no-hpet'/> + <flag name='no-kvm-pit'/> + <flag name='pci-configfd'/> + <flag name='nodefconfig'/> + <flag name='boot-menu'/> + <flag name='fsdev'/> + <flag name='name-process'/> + <flag name='smbios-type'/> + <flag name='spice'/> + <flag name='vga-none'/> + <flag name='boot-index'/> + <flag name='hda-duplex'/> + <flag name='drive-aio'/> + <flag name='pci-bootindex'/> + <flag name='ccid-emulated'/> + <flag name='ccid-passthru'/> + <flag name='chardev-spicevmc'/> + <flag name='virtio-tx-alg'/> + <flag name='pci-multifunction'/> + <flag name='virtio-blk-pci.ioeventfd'/> + <flag name='sga'/> + <flag name='virtio-blk-pci.event_idx'/> + <flag name='virtio-net-pci.event_idx'/> + <flag name='cache-directsync'/> + <flag name='piix3-usb-uhci'/> + <flag name='piix4-usb-uhci'/> + <flag name='usb-ehci'/> + <flag name='ich9-usb-ehci1'/> + <flag name='vt82c686b-usb-uhci'/> + <flag name='pci-ohci'/> + <flag name='usb-redir'/> + <flag name='usb-hub'/> + <flag name='no-shutdown'/> + <flag name='cache-unsafe'/> + <flag name='ich9-ahci'/> + <flag name='no-acpi'/> + <flag name='fsdev-readonly'/> + <flag name='virtio-blk-pci.scsi'/> + <flag name='drive-copy-on-read'/> + <flag name='fsdev-writeout'/> + <flag name='drive-iotune'/> + <flag name='system_wakeup'/> + <flag name='scsi-disk.channel'/> + <flag name='scsi-block'/> + <flag name='transaction'/> + <flag name='block-job-async'/> + <flag name='scsi-cd'/> + <flag name='ide-cd'/> + <flag name='no-user-config'/> + <flag name='hda-micro'/> + <flag name='dump-guest-memory'/> + <flag name='nec-usb-xhci'/> + <flag name='balloon-event'/> + <flag name='bridge'/> + <flag name='lsi'/> + <flag name='virtio-scsi-pci'/> + <flag name='blockio'/> + <flag name='disable-s3'/> + <flag name='disable-s4'/> + <flag name='usb-redir.filter'/> + <flag name='ide-drive.wwn'/> + <flag name='scsi-disk.wwn'/> + <flag name='seccomp-sandbox'/> + <flag name='reboot-timeout'/> + <flag name='dump-guest-core'/> + <flag name='seamless-migration'/> + <flag name='block-commit'/> + <flag name='vnc'/> + <flag name='drive-mirror'/> + <flag name='usb-redir.bootindex'/> + <flag name='usb-host.bootindex'/> + <flag name='blockdev-snapshot-sync'/> + <flag name='qxl'/> + <flag name='VGA'/> + <flag name='cirrus-vga'/> + <flag name='vmware-svga'/> + <flag name='device-video-primary'/> + <flag name='usb-serial'/> + <flag name='usb-net'/> + <flag name='add-fd'/> + <flag name='nbd-server'/> + <flag name='virtio-rng'/> + <flag name='rng-random'/> + <flag name='rng-egd'/> + <flag name='dtb'/> + <flag name='megasas'/> + <flag name='ipv6-migration'/> + <flag name='machine-opt'/> + <flag name='machine-usb-opt'/> + <flag name='tpm-passthrough'/> + <flag name='tpm-tis'/> + <flag name='pci-bridge'/> + <flag name='vfio-pci'/> + <flag name='vfio-pci.bootindex'/> + <flag name='scsi-generic'/> + <flag name='scsi-generic.bootindex'/> + <flag name='mem-merge'/> + <flag name='vnc-websocket'/> + <flag name='drive-discard'/> + <flag name='mlock'/> + <flag name='vnc-share-policy'/> + <flag name='device-del-event'/> + <flag name='dmi-to-pci-bridge'/> + <flag name='i440fx-pci-hole64-size'/> + <flag name='q35-pci-hole64-size'/> + <flag name='usb-storage'/> + <flag name='usb-storage.removable'/> + <flag name='virtio-mmio'/> + <flag name='ich9-intel-hda'/> + <flag name='kvm-pit-lost-tick-policy'/> + <flag name='boot-strict'/> + <flag name='pvpanic'/> + <flag name='spice-file-xfer-disable'/> + <flag name='spiceport'/> + <flag name='usb-kbd'/> + <flag name='host-pci-multidomain'/> + <flag name='msg-timestamp'/> + <flag name='active-commit'/> + <flag name='change-backing-file'/> + <flag name='memory-backend-ram'/> + <flag name='numa'/> + <flag name='memory-backend-file'/> + <flag name='usb-audio'/> + <flag name='rtc-reset-reinjection'/> + <flag name='splash-timeout'/> + <flag name='iothread'/> + <flag name='migrate-rdma'/> + <flag name='ivshmem'/> + <flag name='drive-iotune-max'/> + <flag name='VGA.vgamem_mb'/> + <flag name='vmware-svga.vgamem_mb'/> + <flag name='qxl.vgamem_mb'/> + <flag name='pc-dimm'/> + <flag name='machine-vmport-opt'/> + <flag name='aes-key-wrap'/> + <flag name='dea-key-wrap'/> + <flag name='pci-serial'/> + <flag name='vhost-user-multiqueue'/> + <flag name='migration-event'/> + <flag name='ioh3420'/> + <flag name='x3130-upstream'/> + <flag name='xio3130-downstream'/> + <flag name='rtl8139'/> + <flag name='e1000'/> + <flag name='virtio-net'/> + <flag name='gic-version'/> + <flag name='incoming-defer'/> + <flag name='virtio-gpu'/> + <flag name='virtio-gpu.virgl'/> + <flag name='virtio-keyboard'/> + <flag name='virtio-mouse'/> + <flag name='virtio-tablet'/> + <flag name='virtio-input-host'/> + <flag name='chardev-file-append'/> + <flag name='ich9-disable-s3'/> + <flag name='ich9-disable-s4'/> + <flag name='vserport-change-event'/> + <flag name='virtio-balloon-pci.deflate-on-oom'/> + <flag name='mptsas1068'/> + <flag name='spice-gl'/> + <flag name='qxl.vram64_size_mb'/> + <flag name='chardev-logfile'/> + <flag name='debug-threads'/> + <flag name='secret'/> + <flag name='pxb'/> + <flag name='pxb-pcie'/> + <flag name='device-tray-moved-event'/> + <flag name='nec-usb-xhci-ports'/> + <flag name='virtio-scsi-pci.iothread'/> + <flag name='name-guest'/> + <flag name='qxl.max_outputs'/> + <flag name='spice-unix'/> + <flag name='drive-detect-zeroes'/> + <flag name='tls-creds-x509'/> + <flag name='display'/> + <flag name='intel-iommu'/> + <flag name='smm'/> + <flag name='virtio-pci-disable-legacy'/> + <flag name='query-hotpluggable-cpus'/> + <flag name='virtio-net.rx_queue_size'/> + <flag name='virtio-vga'/> + <flag name='drive-iotune-max-length'/> + <flag name='ivshmem-plain'/> + <flag name='ivshmem-doorbell'/> + <flag name='query-qmp-schema'/> + <flag name='gluster.debug_level'/> + <flag name='vhost-scsi'/> + <flag name='drive-iotune-group'/> + <flag name='query-cpu-model-expansion'/> + <flag name='virtio-net.host_mtu'/> + <flag name='spice-rendernode'/> + <flag name='nvdimm'/> + <flag name='pcie-root-port'/> + <flag name='query-cpu-definitions'/> + <flag name='block-write-threshold'/> + <flag name='query-named-block-nodes'/> + <flag name='cpu-cache'/> + <flag name='qemu-xhci'/> + <flag name='kernel-irqchip'/> + <flag name='kernel-irqchip.split'/> + <flag name='intel-iommu.intremap'/> + <flag name='intel-iommu.caching-mode'/> + <flag name='intel-iommu.eim'/> + <flag name='intel-iommu.device-iotlb'/> + <flag name='virtio.iommu_platform'/> + <flag name='virtio.ats'/> + <flag name='loadparm'/> + <flag name='vnc-multi-servers'/> + <flag name='virtio-net.tx_queue_size'/> + <flag name='chardev-reconnect'/> + <flag name='virtio-gpu.max_outputs'/> + <flag name='vxhs'/> + <flag name='virtio-blk.num-queues'/> + <flag name='numa.dist'/> + <flag name='disk-share-rw'/> + <flag name='iscsi.password-secret'/> + <flag name='isa-serial'/> + <flag name='dump-completed'/> + </qemuCaps> + <job type='none' async='migration out' phase='perform3' flags='0x802'> + <disk dev='vda' migrating='no'/> + <migParams> + <param name='compress-level' value='1'/> + <param name='compress-threads' value='8'/> + <param name='decompress-threads' value='2'/> + <param name='cpu-throttle-initial' value='20'/> + <param name='cpu-throttle-increment' value='10'/> + <param name='tls-creds' value=''/> + <param name='tls-hostname' value=''/> + <param name='max-bandwidth' value='33554432'/> + <param name='downtime-limit' value='300'/> + <param name='block-incremental' value='no'/> + </migParams> + </job> + <devices> + <device alias='virtio-disk0'/> + <device alias='virtio-serial0'/> + <device alias='video0'/> + <device alias='serial0'/> + <device alias='channel1'/> + <device alias='channel0'/> + <device alias='net0'/> + <device alias='input0'/> + <device alias='redir1'/> + <device alias='redir0'/> + <device alias='usb'/> + </devices> + <libDir path='/var/lib/libvirt/qemu/domain-7-nest'/> + <channelTargetDir path='/var/lib/libvirt/qemu/channel/target/domain-7-nest'/> + <chardevStdioLogd/> + <allowReboot value='yes'/> + <blockjobs active='no'/> + <domain type='kvm' id='7'> + <name>nest</name> + <uuid>994cee0d-2a70-4937-9693-0431e39d20f7</uuid> + <description>virt-builder</description> + <memory unit='KiB'>524288</memory> + <currentMemory unit='KiB'>524288</currentMemory> + <vcpu placement='static'>2</vcpu> + <resource> + <partition>/machine</partition> + </resource> + <os> + <type arch='x86_64' machine='pc-i440fx-2.10'>hvm</type> + <bios useserial='yes'/> + </os> + <features> + <acpi/> + <apic/> + <vmport state='off'/> + </features> + <cpu mode='host-passthrough' check='none'/> + <clock offset='utc'> + <timer name='rtc' tickpolicy='catchup'/> + <timer name='pit' tickpolicy='delay'/> + <timer name='hpet' present='no'/> + </clock> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>restart</on_crash> + <pm> + <suspend-to-mem enabled='no'/> + <suspend-to-disk enabled='no'/> + </pm> + <devices> + <emulator>/usr/bin/qemu-kvm</emulator> + <disk type='file' device='disk'> + <driver name='qemu' type='qcow2' cache='none' io='native'/> + <source file='/vm/nest.qcow'/> + <backingStore/> + <target dev='vda' bus='virtio'/> + <boot order='1'/> + <alias name='virtio-disk0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> + </disk> + <controller type='usb' index='0' model='ich9-ehci1'> + <alias name='usb'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x7'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci1'> + <alias name='usb'/> + <master startport='0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0' multifunction='on'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci2'> + <alias name='usb'/> + <master startport='2'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x1'/> + </controller> + <controller type='usb' index='0' model='ich9-uhci3'> + <alias name='usb'/> + <master startport='4'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x2'/> + </controller> + <controller type='virtio-serial' index='0'> + <alias name='virtio-serial0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> + </controller> + <controller type='pci' index='0' model='pci-root'> + <alias name='pci.0'/> + </controller> + <interface type='network'> + <mac address='52:54:00:59:59:91'/> + <source network='default'/> + <actual type='network'> + <source bridge='virbr0'/> + </actual> + <target dev='vnet0'/> + <model type='virtio'/> + <alias name='net0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </interface> + <serial type='pty'> + <source path='/dev/pts/2'/> + <target type='isa-serial' port='0'> + <model name='isa-serial'/> + </target> + <alias name='serial0'/> + </serial> + <console type='pty' tty='/dev/pts/2'> + <source path='/dev/pts/2'/> + <target type='serial' port='0'/> + <alias name='serial0'/> + </console> + <channel type='unix'> + <source mode='bind' path='/var/lib/libvirt/qemu/channel/target/domain-7-nest/org.qemu.guest_agent.0'/> + <target type='virtio' name='org.qemu.guest_agent.0' state='disconnected'/> + <alias name='channel0'/> + <address type='virtio-serial' controller='0' bus='0' port='1'/> + </channel> + <channel type='spicevmc'> + <target type='virtio' name='com.redhat.spice.0' state='disconnected'/> + <alias name='channel1'/> + <address type='virtio-serial' controller='0' bus='0' port='2'/> + </channel> + <input type='tablet' bus='usb'> + <alias name='input0'/> + <address type='usb' bus='0' port='1'/> + </input> + <input type='mouse' bus='ps2'> + <alias name='input1'/> + </input> + <input type='keyboard' bus='ps2'> + <alias name='input2'/> + </input> + <graphics type='spice' port='5900' autoport='yes' listen='0.0.0.0'> + <listen type='address' address='0.0.0.0' fromConfig='1' autoGenerated='no'/> + <image compression='off'/> + </graphics> + <video> + <model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/> + <alias name='video0'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> + </video> + <redirdev bus='usb' type='spicevmc'> + <alias name='redir0'/> + <address type='usb' bus='0' port='2'/> + </redirdev> + <redirdev bus='usb' type='spicevmc'> + <alias name='redir1'/> + <address type='usb' bus='0' port='3'/> + </redirdev> + <memballoon model='none'/> + </devices> + <seclabel type='dynamic' model='selinux' relabel='yes'> + <label>unconfined_u:unconfined_r:svirt_t:s0:c50,c823</label> + <imagelabel>unconfined_u:object_r:svirt_image_t:s0:c50,c823</imagelabel> + </seclabel> + <seclabel type='dynamic' model='dac' relabel='yes'> + <label>+0:+0</label> + <imagelabel>+0:+0</imagelabel> + </seclabel> + </domain> +</domstatus> diff --git a/tests/qemustatusxml2xmldata/migration-out-params-out.xml b/tests/qemustatusxml2xmldata/migration-out-params-out.xml new file mode 120000 index 0000000000..dcf0ef27ba --- /dev/null +++ b/tests/qemustatusxml2xmldata/migration-out-params-out.xml @@ -0,0 +1 @@ +migration-out-params-in.xml \ No newline at end of file diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index d123180e79..0b46997b20 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -1273,6 +1273,8 @@ mymain(void) DO_TEST_STATUS("vcpus-multi"); DO_TEST_STATUS("modern"); DO_TEST_STATUS("migration-out-nbd"); + DO_TEST_STATUS("migration-in-params"); + DO_TEST_STATUS("migration-out-params"); if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL) virFileDeleteTree(fakerootdir); -- 2.17.0

On Wed, Apr 11, 2018 at 04:42:03PM +0200, Jiri Denemark wrote:
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- .../migration-in-params-in.xml | 400 +++++++++++++++++ .../migration-in-params-out.xml | 1 + .../migration-out-params-in.xml | 414 ++++++++++++++++++ .../migration-out-params-out.xml | 1 + tests/qemuxml2xmltest.c | 2 + 5 files changed, 818 insertions(+) create mode 100644 tests/qemustatusxml2xmldata/migration-in-params-in.xml create mode 120000 tests/qemustatusxml2xmldata/migration-in-params-out.xml create mode 100644 tests/qemustatusxml2xmldata/migration-out-params-in.xml create mode 120000 tests/qemustatusxml2xmldata/migration-out-params-out.xml
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

On Mon, Apr 16, 2018 at 20:59:04 +0200, Ján Tomko wrote:
On Wed, Apr 11, 2018 at 04:42:03PM +0200, Jiri Denemark wrote:
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- .../migration-in-params-in.xml | 400 +++++++++++++++++ .../migration-in-params-out.xml | 1 + .../migration-out-params-in.xml | 414 ++++++++++++++++++ .../migration-out-params-out.xml | 1 + tests/qemuxml2xmltest.c | 2 + 5 files changed, 818 insertions(+) create mode 100644 tests/qemustatusxml2xmldata/migration-in-params-in.xml create mode 120000 tests/qemustatusxml2xmldata/migration-in-params-out.xml create mode 100644 tests/qemustatusxml2xmldata/migration-out-params-in.xml create mode 120000 tests/qemustatusxml2xmldata/migration-out-params-out.xml
Reviewed-by: Ján Tomko <jtomko@redhat.com>
I just pushed this series, thanks for the giant portion of reviews. Jirka

On 04/11/2018 04:40 PM, Jiri Denemark wrote:
This series changes the way we handle migration parameters and capabilities with several goals:
- make it all consistent and avoid storing the same parameters in several structs - reduce the number of QMP commands we use for setting migration capabilities - concentrate the logic in a separate file and make the code for migration parameters and capabilities in qemu_migration.c less complicated - reset all parameters and capabilities at the end of migration - make adding new parameters and capabilities easier
This perhaps deserves news.xml entry? Michal

On Tue, Apr 17, 2018 at 11:34:25 +0200, Michal Privoznik wrote:
On 04/11/2018 04:40 PM, Jiri Denemark wrote:
This series changes the way we handle migration parameters and capabilities with several goals:
- make it all consistent and avoid storing the same parameters in several structs - reduce the number of QMP commands we use for setting migration capabilities - concentrate the logic in a separate file and make the code for migration parameters and capabilities in qemu_migration.c less complicated - reset all parameters and capabilities at the end of migration - make adding new parameters and capabilities easier
This perhaps deserves news.xml entry?
It doesn't. The changes which are visible to libvirt users are very small and only relevant to some corner cases. Jirka
participants (3)
-
Jiri Denemark
-
Ján Tomko
-
Michal Privoznik