[libvirt] [PATCH 00/68] 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 Jiri Denemark (68): qemu: Move qemuDomainCheckMigrationCapabilities qemu: Rename qemuMigrationAnyCapsGet as qemuMigrationCapsGet qemu: Rename qemuMigrationParams qemu: New file for all APIs related to migration parameters 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: Move qemuMonitorMigrationParams structure qemu: Refactor qemuMigrationParams qemu: Generalize qemuMigrationParamsGetDowntimeLimit qemu: Set migration parameters automatically qemu: Properly reset migration params when libvirtd restarts qemu: Export qemuMigrationParams{To,From}JSON for tests 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 | 965 +++----------- src/qemu/qemu_migration.h | 72 +- src/qemu/qemu_migration_params.c | 1139 +++++++++++++++++ src/qemu/qemu_migration_params.h | 130 ++ src/qemu/qemu_migration_paramspriv.h | 31 + src/qemu/qemu_monitor.c | 64 +- src/qemu/qemu_monitor.h | 43 +- src/qemu/qemu_monitor_json.c | 153 +-- src/qemu/qemu_monitor_json.h | 10 +- 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 | 113 +- .../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 + 46 files changed, 3456 insertions(+), 1316 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

Since the function is tightly connected to migration, it was renamed as qemuMigrationCapsCheck and moved to qemu_migration.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.c | 72 +++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_migration.h | 6 ++++ src/qemu/qemu_process.c | 2 +- 5 files changed, 79 insertions(+), 77 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 9d1c33b54a..a1bbe256f5 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -11781,78 +11781,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.c b/src/qemu/qemu_migration.c index e5231555de..a2a6616862 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -6162,6 +6162,78 @@ qemuMigrationSrcFetchMirrorStats(virQEMUDriverPtr driver, } +int +qemuMigrationCapsCheck(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; +} + + bool qemuMigrationAnyCapsGet(virDomainObjPtr vm, qemuMonitorMigrationCaps cap) diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h index a075aec124..3dca8a1889 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -37,6 +37,7 @@ * - qemuMigrationParamsXXX - runs on source or dest host * - qemuMigrationOptionXXX - runs on source or dest host * - qemuMigrationJobXXX - runs on source or dest host + * - qemuMigrationCapsXXX - runs on source or dest host */ typedef struct _qemuMigrationCompression qemuMigrationCompression; @@ -308,6 +309,11 @@ qemuMigrationSrcFetchMirrorStats(virQEMUDriverPtr driver, qemuDomainAsyncJob asyncJob, qemuDomainJobInfoPtr jobInfo); +int +qemuMigrationCapsCheck(virQEMUDriverPtr driver, + virDomainObjPtr vm, + qemuDomainAsyncJob asyncJob); + bool qemuMigrationAnyCapsGet(virDomainObjPtr vm, qemuMonitorMigrationCaps cap); diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index c0105c8b84..df2db53a97 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -1835,7 +1835,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 04, 2018 at 04:40:50PM +0200, Jiri Denemark wrote:
Since the function is tightly connected to migration, it was renamed as qemuMigrationCapsCheck and moved to qemu_migration.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.c | 72 +++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_migration.h | 6 ++++ src/qemu/qemu_process.c | 2 +- 5 files changed, 79 insertions(+), 77 deletions(-)
ACK Jano

Signed-off-by: Jiri Denemark <jdenemar@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 a2a6616862..cc664c20d6 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; @@ -3872,7 +3872,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) @@ -6098,7 +6098,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; } @@ -6235,8 +6235,8 @@ qemuMigrationCapsCheck(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 3dca8a1889..cccbf12652 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -315,7 +315,7 @@ qemuMigrationCapsCheck(virQEMUDriverPtr driver, qemuDomainAsyncJob asyncJob); bool -qemuMigrationAnyCapsGet(virDomainObjPtr vm, - qemuMonitorMigrationCaps cap); +qemuMigrationCapsGet(virDomainObjPtr vm, + qemuMonitorMigrationCaps cap); #endif /* __QEMU_MIGRATION_H__ */ -- 2.17.0

On Wed, Apr 04, 2018 at 04:40:51PM +0200, Jiri Denemark wrote:
Signed-off-by: Jiri Denemark <jdenemar@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
ACK Jano

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> --- 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 cc664c20d6..f88ac02f2f 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2474,9 +2474,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 cccbf12652..b9f7369784 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -144,9 +144,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

On Wed, Apr 04, 2018 at 04:40:52PM +0200, Jiri Denemark wrote:
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> --- 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(-)
ACK Jano

In the end, this will allow us to have most of the logic around migration parameters 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 d84859a4e3..0b62126a19 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 f88ac02f2f..4bdaa67ea1 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, @@ -2366,238 +2215,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, @@ -6077,40 +5694,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 b9f7369784..7342517ca6 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 * - qemuMigrationCapsXXX - runs on source or dest host @@ -137,17 +136,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); @@ -298,11 +286,6 @@ void qemuMigrationAnyPostcopyFailed(virQEMUDriverPtr driver, virDomainObjPtr vm); -void -qemuMigrationParamsReset(virQEMUDriverPtr driver, - virDomainObjPtr vm, - qemuDomainAsyncJob job); - int qemuMigrationSrcFetchMirrorStats(virQEMUDriverPtr driver, virDomainObjPtr vm, @@ -318,4 +301,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 df2db53a97..3a7f8ed105 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

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 72ecafd057..69fbeaefa9 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

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 69fbeaefa9..867fe82b92 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 33b3c27e51..d3e7fe9d7a 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

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 4bdaa67ea1..ffdf0ba2e5 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2254,7 +2254,7 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, int rv; char *tlsAlias = NULL; char *secAlias = NULL; - qemuMonitorMigrationParams migParams = { 0 }; + qemuMonitorMigrationParamsPtr migParams = NULL; virNWFilterReadLockFilterUpdates(); @@ -2304,6 +2304,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; @@ -2448,7 +2451,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 @@ -2461,17 +2464,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; } @@ -2492,7 +2495,7 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, goto stopjob; if (qemuMigrationParamsSet(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN, - &migParams) < 0) + migParams) < 0) goto stopjob; if (mig->nbd && @@ -2580,7 +2583,7 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, virDomainObjRemoveTransientDef(vm); qemuDomainRemoveInactiveJob(driver, vm); } - qemuMigrationParamsClear(&migParams); + qemuMigrationParamsFree(migParams); virDomainObjEndAPI(&vm); qemuDomainEventQueue(driver, event); qemuMigrationCookieFree(mig); @@ -3884,7 +3887,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", @@ -3906,6 +3909,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; @@ -3961,13 +3967,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) @@ -4007,7 +4013,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 867fe82b92..1b4aa46854 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 d3e7fe9d7a..bc608905cc 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

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 1b4aa46854..c91216a2a4 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 bc608905cc..18802ac3e4 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

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 7342517ca6..32028845a7 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: @@ -39,9 +40,6 @@ * - qemuMigrationCapsXXX - 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 | \ @@ -109,22 +107,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 18802ac3e4..247455b1cd 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

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 ffdf0ba2e5..a6f8e66891 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2254,7 +2254,7 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, int rv; char *tlsAlias = NULL; char *secAlias = NULL; - qemuMonitorMigrationParamsPtr migParams = NULL; + qemuMigrationParamsPtr migParams = NULL; virNWFilterReadLockFilterUpdates(); @@ -2468,7 +2468,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 { @@ -3340,7 +3340,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; @@ -3429,11 +3429,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 { @@ -3736,7 +3736,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; @@ -3815,7 +3815,7 @@ qemuMigrationSrcPerformTunnel(virQEMUDriverPtr driver, size_t nmigrate_disks, const char **migrate_disks, qemuMigrationCompressionPtr compression, - qemuMonitorMigrationParamsPtr migParams) + qemuMigrationParamsPtr migParams) { int ret = -1; qemuMigrationSpec spec; @@ -3887,7 +3887,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", @@ -4042,7 +4042,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) @@ -4401,7 +4401,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, @@ -4566,7 +4566,7 @@ qemuMigrationSrcPerformJob(virQEMUDriverPtr driver, const char **migrate_disks, int nbdPort, qemuMigrationCompressionPtr compression, - qemuMonitorMigrationParamsPtr migParams, + qemuMigrationParamsPtr migParams, const char *cookiein, int cookieinlen, char **cookieout, @@ -4679,7 +4679,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, @@ -4753,7 +4753,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 32028845a7..b15eca9e51 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -183,7 +183,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 c91216a2a4..187c0c2258 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 247455b1cd..f5e64dcc1d 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

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 a6f8e66891..73024d66c0 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

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 a1bbe256f5..e44073f441 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 73024d66c0..7fd85bc6c5 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2451,6 +2451,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; @@ -4600,6 +4603,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, @@ -4703,6 +4709,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 187c0c2258..4defc62ae5 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 f5e64dcc1d..a6125a6f3d 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

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 e44073f441..7528ec9dc8 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 3a7f8ed105..31aba16b31 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3182,7 +3182,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; @@ -7264,7 +7264,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

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 31aba16b31..871f1143f2 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3030,7 +3030,7 @@ qemuProcessUpdateState(virQEMUDriverPtr driver, virDomainObjPtr vm) static int qemuProcessRecoverMigrationIn(virQEMUDriverPtr driver, virDomainObjPtr vm, - qemuMigrationJobPhase phase, + const qemuDomainJobObj *job, virDomainState state, int reason) { @@ -3039,7 +3039,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: @@ -3088,7 +3088,7 @@ qemuProcessRecoverMigrationIn(virQEMUDriverPtr driver, static int qemuProcessRecoverMigrationOut(virQEMUDriverPtr driver, virDomainObjPtr vm, - qemuMigrationJobPhase phase, + const qemuDomainJobObj *job, virDomainState state, int reason, unsigned int *stopFlags) @@ -3098,7 +3098,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: @@ -3193,13 +3193,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

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 7fd85bc6c5..3c25e0e27f 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; @@ -2596,7 +2597,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; @@ -2972,7 +2974,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); @@ -4584,6 +4587,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; @@ -4644,7 +4648,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, @@ -4694,6 +4699,7 @@ qemuMigrationSrcPerformPhase(virQEMUDriverPtr driver, unsigned long flags, unsigned long resource) { + qemuDomainObjPrivatePtr priv = vm->privateData; virObjectEventPtr event = NULL; int ret = -1; @@ -4734,7 +4740,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); @@ -5190,7 +5197,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 4defc62ae5..43098de904 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 a6125a6f3d..5e5e81ee07 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -108,6 +108,7 @@ qemuMigrationParamsCheck(virQEMUDriverPtr driver, void qemuMigrationParamsReset(virQEMUDriverPtr driver, virDomainObjPtr vm, - int asyncJob); + int asyncJob, + qemuMigrationParamsPtr origParams); #endif /* __QEMU_MIGRATION_PARAMS_H__ */ diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 871f1143f2..c4d3f67d19 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3081,7 +3081,7 @@ qemuProcessRecoverMigrationIn(virQEMUDriverPtr driver, break; } - qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_NONE); + qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_NONE, job->migParams); return 0; } @@ -3175,7 +3175,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

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 3c25e0e27f..072a5c95ae 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2045,7 +2045,6 @@ qemuMigrationSrcBegin(virConnectPtr conn, unsigned long flags) { virQEMUDriverPtr driver = conn->privateData; - virQEMUDriverConfigPtr cfg = NULL; char *xml = NULL; qemuDomainAsyncJob asyncJob; @@ -2079,12 +2078,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 @@ -2101,7 +2094,6 @@ qemuMigrationSrcBegin(virConnectPtr conn, } cleanup: - virObjectUnref(cfg); virDomainObjEndAPI(&vm); return xml; @@ -2463,10 +2455,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) @@ -3424,9 +3412,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 43098de904..bee7d9796f 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 5e5e81ee07..1c41a5620f 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

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 7528ec9dc8..55b88e35e0 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 072a5c95ae..8cd5426ed9 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2465,9 +2465,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; } @@ -3429,9 +3427,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 bee7d9796f..fd4fc6c6a8 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 1c41a5620f..b8c29cddd8 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

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 8cd5426ed9..f007f7e05a 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2465,7 +2465,7 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, goto stopjob; } else { - if (qemuMigrationParamsSetEmptyTLS(vm, migParams) < 0) + if (qemuMigrationParamsDisableTLS(vm, migParams) < 0) goto stopjob; } @@ -3427,7 +3427,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 fd4fc6c6a8..26f3f29d16 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 b8c29cddd8..281c2ae687 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

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 f007f7e05a..254239b18b 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2455,9 +2455,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 */ @@ -3410,9 +3410,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 26f3f29d16..a03239e2a2 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 281c2ae687..8aa6136508 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

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 254239b18b..fe2fae8fba 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2457,13 +2457,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; @@ -3409,23 +3405,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 a03239e2a2..812c35e13e 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 8aa6136508..2955bf7436 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

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 fe2fae8fba..d07a12cdec 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2231,7 +2231,6 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, { virDomainObjPtr vm = NULL; virObjectEventPtr event = NULL; - virQEMUDriverConfigPtr cfg = NULL; int ret = -1; int dataFD[2] = { -1, -1 }; qemuDomainObjPrivatePtr priv = NULL; @@ -2454,8 +2453,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) @@ -2552,7 +2550,6 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, cleanup: VIR_FREE(tlsAlias); VIR_FREE(secAlias); - virObjectUnref(cfg); qemuProcessIncomingDefFree(incoming); VIR_FREE(xmlout); VIR_FORCE_CLOSE(dataFD[0]); @@ -3333,7 +3330,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; @@ -3413,8 +3409,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) @@ -3652,7 +3647,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 812c35e13e..7b5a7c108f 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 2955bf7436..45834e5b48 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

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 d07a12cdec..3e775ea56b 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2479,8 +2479,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 && @@ -3474,8 +3474,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 7b5a7c108f..733df86687 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 45834e5b48..e06aaa74eb 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

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 733df86687..42c7c6a3ec 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 e06aaa74eb..0f7cb55878 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

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

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 3e775ea56b..3240e7d67b 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) { @@ -2468,15 +2408,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, @@ -3451,27 +3390,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 b15eca9e51..c753a57028 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -283,11 +283,4 @@ 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 index 42c7c6a3ec..83d3247017 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 0f7cb55878..e881ee202d 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

Rework all remaining callers of qemuMonitorSetMigrationCapability to use the new qemuMonitorSetMigrationCapabilities API. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration.c | 11 ++++++++--- tests/qemumonitorjsontest.c | 16 +++++++++++----- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 3240e7d67b..6b0c7545a1 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -5681,6 +5681,7 @@ qemuMigrationCapsCheck(virQEMUDriverPtr driver, qemuDomainAsyncJob asyncJob) { qemuDomainObjPrivatePtr priv = vm->privateData; + virBitmapPtr migEvent = NULL; char **caps = NULL; char **capStr; int ret = -1; @@ -5715,12 +5716,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

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

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

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 6b0c7545a1..9758d20d99 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2386,8 +2386,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 @@ -3386,8 +3385,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 83d3247017..ec1d2be6a0 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 e881ee202d..6cfac1f78f 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

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 9758d20d99..5f50795c16 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2383,25 +2383,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; @@ -2417,6 +2401,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

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 5f50795c16..6c736796b4 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -3338,6 +3338,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; @@ -3357,6 +3385,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) { @@ -3385,35 +3417,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; @@ -4511,9 +4514,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, @@ -4619,9 +4619,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

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 6c736796b4..a6b2597461 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2401,7 +2401,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 @@ -3363,7 +3364,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 ec1d2be6a0..862bab1af9 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 6cfac1f78f..292b30b8e7 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

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 862bab1af9..72e4e660b7 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 292b30b8e7..062e6f37a9 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

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 a6b2597461..ceab035acf 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2167,6 +2167,7 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, const char **migrate_disks, int nbdPort, qemuMigrationCompressionPtr compression, + qemuMigrationParamsPtr migParams, unsigned long flags) { virDomainObjPtr vm = NULL; @@ -2187,7 +2188,6 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, int rv; char *tlsAlias = NULL; char *secAlias = NULL; - qemuMigrationParamsPtr migParams = NULL; virNWFilterReadLockFilterUpdates(); @@ -2237,9 +2237,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; @@ -2506,7 +2503,6 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, virDomainObjRemoveTransientDef(vm); qemuDomainRemoveInactiveJob(driver, vm); } - qemuMigrationParamsFree(migParams); virDomainObjEndAPI(&vm); qemuDomainEventQueue(driver, event); qemuMigrationCookieFree(mig); @@ -2546,6 +2542,7 @@ qemuMigrationDstPrepareTunnel(virQEMUDriverPtr driver, virStreamPtr st, virDomainDefPtr *def, const char *origname, + qemuMigrationParamsPtr migParams, unsigned long flags) { qemuMigrationCompressionPtr compression = NULL; @@ -2569,7 +2566,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; } @@ -2614,6 +2611,7 @@ qemuMigrationDstPrepareDirect(virQEMUDriverPtr driver, const char **migrate_disks, int nbdPort, qemuMigrationCompressionPtr compression, + qemuMigrationParamsPtr migParams, unsigned long flags) { unsigned short port = 0; @@ -2737,7 +2735,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); @@ -3791,7 +3789,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; @@ -3803,7 +3802,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", @@ -3825,9 +3823,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; @@ -3929,7 +3924,6 @@ qemuMigrationSrcPerformPeer2Peer2(virQEMUDriverPtr driver, virSetError(orig_err); virFreeError(orig_err); } - qemuMigrationParamsFree(migParams); VIR_FREE(uri_out); VIR_FREE(cookie); VIR_FREE(compression); @@ -4445,7 +4439,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 c753a57028..af8f2cfeb4 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -149,6 +149,7 @@ qemuMigrationDstPrepareTunnel(virQEMUDriverPtr driver, virStreamPtr st, virDomainDefPtr *def, const char *origname, + qemuMigrationParamsPtr migParams, unsigned long flags); int @@ -167,6 +168,7 @@ qemuMigrationDstPrepareDirect(virQEMUDriverPtr driver, const char **migrate_disks, int nbdPort, qemuMigrationCompressionPtr compression, + qemuMigrationParamsPtr migParams, unsigned long flags); int -- 2.17.0

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 72e4e660b7..c79ea4fa91 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 062e6f37a9..3620a4e36e 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

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 ceab035acf..f3006d8aa4 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2394,8 +2394,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, @@ -2419,6 +2421,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)) { @@ -3352,8 +3356,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) && @@ -3389,6 +3395,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 c79ea4fa91..ac99fa29e1 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 3620a4e36e..a483211bdd 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

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 | 28 ++++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index f3006d8aa4..bb8f506659 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -3362,12 +3362,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 ac99fa29e1..3837bf5b68 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,14 @@ qemuMigrationParamsCheck(virQEMUDriverPtr driver, } } + for (i = 0; i < ARRAY_CARDINALITY(qemuMigrationParamsAlwaysOn); i++) { + if (qemuMigrationParamsAlwaysOn[i].party & party && + qemuMigrationCapsGet(vm, qemuMigrationParamsAlwaysOn[i].cap)) { + ignore_value(virBitmapSetBit(migParams->caps, + qemuMigrationParamsAlwaysOn[i].cap)); + } + } + if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) return -1; -- 2.17.0

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 | 42 +++++++++++++++++++++++++++----- src/qemu/qemu_migration_params.h | 6 ----- 3 files changed, 36 insertions(+), 42 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index bb8f506659..1c614f8c0d 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2388,18 +2388,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; @@ -3344,24 +3332,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 3837bf5b68..9d2ac6bee5 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,18 @@ 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++) { + if (qemuMigrationParamsFlagMap[i].party & party && + flags & qemuMigrationParamsFlagMap[i].flag) { + ignore_value(virBitmapSetBit(migParams->caps, + qemuMigrationParamsFlagMap[i].cap)); + } + } #define GET(PARAM, VAR) \ do { \ @@ -116,9 +144,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 +227,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 a483211bdd..a734455b36 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

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 1c614f8c0d..fa220d6ce4 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2534,12 +2534,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", @@ -2552,15 +2550,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); } @@ -3762,6 +3755,7 @@ qemuMigrationSrcPerformPeer2Peer2(virQEMUDriverPtr driver, unsigned long flags, const char *dname, unsigned long resource, + qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams) { virDomainPtr ddomain = NULL; @@ -3773,7 +3767,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", @@ -3795,9 +3788,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) { /* @@ -3898,7 +3888,6 @@ qemuMigrationSrcPerformPeer2Peer2(virQEMUDriverPtr driver, } VIR_FREE(uri_out); VIR_FREE(cookie); - VIR_FREE(compression); return ret; } @@ -4412,7 +4401,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 af8f2cfeb4..2d67da8435 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -149,6 +149,7 @@ qemuMigrationDstPrepareTunnel(virQEMUDriverPtr driver, virStreamPtr st, virDomainDefPtr *def, const char *origname, + qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams, unsigned long flags); -- 2.17.0

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 9d2ac6bee5..2caf4dd1c9 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, @@ -132,27 +143,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)) { @@ -168,6 +165,8 @@ qemuMigrationParamsFromFlags(virTypedParameterPtr params, return NULL; } +#undef GET + /** * qemuMigrationParamsApply -- 2.17.0

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 2caf4dd1c9..b70229a156 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -226,21 +226,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 @@ -355,23 +340,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

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 b70229a156..dfa534bfd9 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, @@ -339,35 +369,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

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 fa220d6ce4..e338bd05f6 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, @@ -5442,141 +5437,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 2d67da8435..02b33d4a5d 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -99,25 +99,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 dfa534bfd9..1795bafe24 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; @@ -198,6 +211,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 a734455b36..b00075794a 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

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 e338bd05f6..304eaf52c5 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2161,7 +2161,6 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver, size_t nmigrate_disks, const char **migrate_disks, int nbdPort, - qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams, unsigned long flags) { @@ -2375,9 +2374,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; @@ -2529,7 +2525,6 @@ qemuMigrationDstPrepareTunnel(virQEMUDriverPtr driver, virStreamPtr st, virDomainDefPtr *def, const char *origname, - qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams, unsigned long flags) { @@ -2548,7 +2543,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); } @@ -2590,7 +2585,6 @@ qemuMigrationDstPrepareDirect(virQEMUDriverPtr driver, size_t nmigrate_disks, const char **migrate_disks, int nbdPort, - qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams, unsigned long flags) { @@ -2715,7 +2709,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); @@ -3242,7 +3236,6 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver, const char *graphicsuri, size_t nmigrate_disks, const char **migrate_disks, - qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams) { int ret = -1; @@ -3317,9 +3310,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; @@ -3609,7 +3599,6 @@ qemuMigrationSrcPerformNative(virQEMUDriverPtr driver, const char *graphicsuri, size_t nmigrate_disks, const char **migrate_disks, - qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams) { qemuDomainObjPrivatePtr priv = vm->privateData; @@ -3661,7 +3650,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); @@ -3688,7 +3677,6 @@ qemuMigrationSrcPerformTunnel(virQEMUDriverPtr driver, const char *graphicsuri, size_t nmigrate_disks, const char **migrate_disks, - qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams) { int ret = -1; @@ -3726,7 +3714,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); @@ -3750,7 +3738,6 @@ qemuMigrationSrcPerformPeer2Peer2(virQEMUDriverPtr driver, unsigned long flags, const char *dname, unsigned long resource, - qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams) { virDomainPtr ddomain = NULL; @@ -3835,13 +3822,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) @@ -4080,14 +4067,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); } @@ -4396,7 +4383,7 @@ qemuMigrationSrcPerformPeer2Peer(virQEMUDriverPtr driver, } else { ret = qemuMigrationSrcPerformPeer2Peer2(driver, sconn, dconn, vm, dconnuri, flags, dname, resource, - compression, migParams); + migParams); } cleanup: @@ -4478,7 +4465,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; @@ -4547,7 +4534,6 @@ qemuMigrationSrcPerformPhase(virQEMUDriverPtr driver, const char *graphicsuri, size_t nmigrate_disks, const char **migrate_disks, - qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams, const char *cookiein, int cookieinlen, @@ -4575,7 +4561,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)) { @@ -4670,7 +4656,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 02b33d4a5d..b67184874b 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -130,7 +130,6 @@ qemuMigrationDstPrepareTunnel(virQEMUDriverPtr driver, virStreamPtr st, virDomainDefPtr *def, const char *origname, - qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams, unsigned long flags); @@ -149,7 +148,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 1795bafe24..4f76cc6683 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; @@ -201,6 +201,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 b00075794a..399b5cde77 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

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 304eaf52c5..2a0431ea6f 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -3894,7 +3894,6 @@ qemuMigrationSrcPerformPeer2Peer3(virQEMUDriverPtr driver, size_t nmigrate_disks, const char **migrate_disks, int nbdPort, - qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams, unsigned long long bandwidth, bool useParams, @@ -3979,8 +3978,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; } @@ -4253,7 +4252,6 @@ qemuMigrationSrcPerformPeer2Peer(virQEMUDriverPtr driver, size_t nmigrate_disks, const char **migrate_disks, int nbdPort, - qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams, unsigned long flags, const char *dname, @@ -4378,7 +4376,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, @@ -4419,7 +4417,6 @@ qemuMigrationSrcPerformJob(virQEMUDriverPtr driver, size_t nmigrate_disks, const char **migrate_disks, int nbdPort, - qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams, const char *cookiein, int cookieinlen, @@ -4458,7 +4455,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); @@ -4609,7 +4606,6 @@ qemuMigrationSrcPerform(virQEMUDriverPtr driver, size_t nmigrate_disks, const char **migrate_disks, int nbdPort, - qemuMigrationCompressionPtr compression, qemuMigrationParamsPtr migParams, const char *cookiein, int cookieinlen, @@ -4641,7 +4637,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); @@ -4664,7 +4660,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 b67184874b..096c449bcc 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -164,7 +164,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 4f76cc6683..299920fc1a 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; @@ -298,51 +301,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 399b5cde77..3793b3bd17 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

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 299920fc1a..f3cfb41952 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; @@ -204,7 +256,7 @@ qemuMigrationParamsFromFlags(virTypedParameterPtr params, goto error; } - if (qemuMigrationParamsSetCompression(compression, migParams) < 0) + if (qemuMigrationParamsSetCompression(params, nparams, flags, migParams) < 0) goto error; return migParams; @@ -217,89 +269,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 3793b3bd17..91863e0991 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

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 f3cfb41952..642e4f314c 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -517,6 +517,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: * @@ -532,11 +565,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; @@ -564,31 +595,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 91863e0991..cabf4cebe6 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

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 642e4f314c..fd93d9cb39 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -550,6 +550,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 cabf4cebe6..9fcd9825c8 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

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

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 f6897915ce..9d98ee54df 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2093,6 +2093,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

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 fd93d9cb39..6908aef24d 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -311,6 +311,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 @@ -524,28 +585,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

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, 89 insertions(+), 74 deletions(-) diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 6908aef24d..0c8e44f644 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -372,6 +372,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 @@ -391,6 +446,7 @@ qemuMigrationParamsApply(virQEMUDriverPtr driver, { qemuDomainObjPrivatePtr priv = vm->privateData; bool xbzrleCacheSize_old = false; + virJSONValuePtr params = NULL; int ret = -1; if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) @@ -414,10 +470,16 @@ qemuMigrationParamsApply(virQEMUDriverPtr driver, migParams->params.xbzrleCacheSize_set = false; } - if (qemuMonitorSetMigrationParams(priv->mon, &migParams->params) < 0) + if (!(params = qemuMigrationParamsToJSON(migParams))) goto cleanup; - ret = 0; + if (virJSONValueObjectKeysNumber(params) == 0) { + ret = 0; + goto cleanup; + } + + ret = qemuMonitorSetMigrationParams(priv->mon, params); + params = NULL; cleanup: if (qemuDomainObjExitMonitor(driver, vm) < 0) @@ -426,6 +488,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

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 0c8e44f644..9f091ec693 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -38,6 +38,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

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 | 469 ++++++++++++++++++++----------- src/qemu/qemu_migration_params.h | 20 ++ 2 files changed, 327 insertions(+), 162 deletions(-) diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 9f091ec693..50f69ee571 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -38,46 +38,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 { @@ -92,6 +75,19 @@ 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 { @@ -128,6 +124,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) @@ -152,26 +163,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 @@ -221,23 +326,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")); @@ -277,15 +399,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")); @@ -302,8 +431,6 @@ qemuMigrationParamsFromFlags(virTypedParameterPtr params, return NULL; } -#undef GET - int qemuMigrationParamsDump(qemuMigrationParamsPtr migParams, @@ -315,7 +442,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; } @@ -328,20 +455,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; } @@ -350,7 +486,11 @@ qemuMigrationParamsDump(qemuMigrationParamsPtr migParams, static 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; @@ -358,47 +498,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 = qemuMigrationParamTypeList[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; @@ -412,48 +540,43 @@ static 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 = qemuMigrationParamTypeList[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; @@ -483,6 +606,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; if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) @@ -496,14 +620,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))) @@ -522,7 +646,7 @@ qemuMigrationParamsApply(virQEMUDriverPtr driver, ret = -1; if (xbzrleCacheSize_old) - migParams->params.xbzrleCacheSize_set = true; + migParams->params[xbzrle].set = true; virJSONValueFree(params); @@ -568,7 +692,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")); @@ -599,8 +723,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; @@ -632,11 +760,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; @@ -661,7 +791,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 @@ -710,6 +840,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. @@ -718,10 +863,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 9fcd9825c8..c354c35d29 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

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 761f84ee7f..93dec7c2ce 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 50f69ee571..82e8aeedc6 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -856,17 +856,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 c354c35d29..1540d72acb 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -100,8 +100,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

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 | 135 ++++++++++++++++++------------- 1 file changed, 80 insertions(+), 55 deletions(-) diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index 82e8aeedc6..6f3555bc63 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -102,6 +102,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. */ static const qemuMigrationParamsAlwaysOnItem qemuMigrationParamsAlwaysOn[] = { @@ -124,6 +131,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, @@ -326,30 +361,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) && @@ -399,18 +410,29 @@ 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; + + 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 || @@ -455,29 +477,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

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 55b88e35e0..cef08343ea 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 6f3555bc63..dd2a91cac3 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -985,3 +985,148 @@ qemuMigrationParamsReset(virQEMUDriverPtr driver, virFreeError(err); } } + + +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' ", + qemuMigrationParamTypeList[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; +} diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_params.h index 1540d72acb..8116f3f59f 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" @@ -116,4 +118,12 @@ qemuMigrationParamsReset(virQEMUDriverPtr driver, int asyncJob, qemuMigrationParamsPtr origParams); +void +qemuMigrationParamsFormat(virBufferPtr buf, + qemuMigrationParamsPtr migParams); + +int +qemuMigrationParamsParse(xmlXPathContextPtr ctxt, + qemuMigrationParamsPtr *migParams); + #endif /* __QEMU_MIGRATION_PARAMS_H__ */ -- 2.17.0

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 dd2a91cac3..6634fae4f6 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 @@ -508,7 +509,7 @@ qemuMigrationParamsDump(qemuMigrationParamsPtr migParams, } -static qemuMigrationParamsPtr +qemuMigrationParamsPtr qemuMigrationParamsFromJSON(virJSONValuePtr params) { qemuMigrationParamsPtr migParams; @@ -561,7 +562,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

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 f2f5caed4f..2948ff7c87 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -125,6 +125,7 @@ EXTRA_DIST = \ qemuhotplugtestcpus \ qemuhotplugtestdevices \ qemuhotplugtestdomains \ + qemumigparamsdata \ qemumonitorjsondata \ qemuxml2argvdata \ qemuxml2startupxmloutdata \ @@ -290,6 +291,7 @@ test_programs += qemuxml2argvtest qemuxml2xmltest \ qemumemlocktest \ qemucommandutiltest \ qemublocktest \ + qemumigparamstest \ $(NULL) test_helpers += qemucapsprobe test_libraries += libqemumonitortestutils.la \ @@ -692,6 +694,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 \ qemuhelptest.c domainsnapshotxml2xmltest.c \ @@ -702,6 +713,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

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

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

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 cef08343ea..3f3a49f064 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); @@ -5788,7 +5790,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), @@ -5797,6 +5800,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)) @@ -5860,7 +5864,8 @@ int qemuDomainObjBeginJob(virQEMUDriverPtr driver, int qemuDomainObjBeginAsyncJob(virQEMUDriverPtr driver, virDomainObjPtr obj, qemuDomainAsyncJob asyncJob, - virDomainJobOperation operation) + virDomainJobOperation operation, + unsigned long apiFlags) { qemuDomainObjPrivatePtr priv; @@ -5870,6 +5875,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 93dec7c2ce..e15eb49a5c 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 2a0431ea6f..3ce180dd39 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 @@ -1984,7 +1985,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 { @@ -2317,7 +2319,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); @@ -4433,7 +4436,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)) { @@ -4545,7 +4549,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; @@ -5282,7 +5287,8 @@ qemuMigrationSrcCancel(virQEMUDriverPtr driver, static int qemuMigrationJobStart(virQEMUDriverPtr driver, virDomainObjPtr vm, - qemuDomainAsyncJob job) + qemuDomainAsyncJob job, + unsigned long apiFlags) { qemuDomainObjPrivatePtr priv = vm->privateData; virDomainJobOperation op; @@ -5298,7 +5304,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 c4d3f67d19..89669c9765 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -4185,10 +4185,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

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 e15eb49a5c..b9927b727b 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

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 3f3a49f064..d82c9aad23 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 b9927b727b..04eb0b6929 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

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 d82c9aad23..2a15eb273b 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 04eb0b6929..b871dab581 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 3ce180dd39..808a6c147e 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2403,8 +2403,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)) { @@ -3340,8 +3338,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

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 2a15eb273b..704f395c24 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

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 808a6c147e..c7dcbf0788 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; @@ -2496,7 +2496,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; @@ -2866,7 +2866,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); @@ -4490,7 +4490,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, @@ -4579,7 +4579,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); @@ -5035,7 +5035,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 6634fae4f6..a9c0d90f00 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -803,6 +803,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 "". @@ -811,13 +812,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 @@ -966,11 +970,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; @@ -978,7 +984,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 8116f3f59f..2e4cbcb315 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -116,7 +116,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 89669c9765..095ce26031 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3081,7 +3081,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; } @@ -3175,7 +3176,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

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 0f560290a0..6356ffbc97 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -1264,6 +1264,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 04, 2018 at 16:40:49 +0200, 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
Jiri Denemark (68): qemu: Move qemuDomainCheckMigrationCapabilities qemu: Rename qemuMigrationAnyCapsGet as qemuMigrationCapsGet qemu: Rename qemuMigrationParams qemu: New file for all APIs related to migration parameters qemu: Reindent qemuMigrationParamsSetEmptyTLS
I realized I forgot to do a few more changes on of which will affect several commits up until here. Thanks for the review so far, but you can ignore this series now and continue with v2 once I finish it. Jirka
participants (2)
-
Jiri Denemark
-
Ján Tomko