[libvirt] [PATCH 0/6] RDMA migration support

This is a modified version of RDMA migration patches sent back in January by Michael R. Hines. See individual patches for (numerous) changes since v2. Jiri Denemark (3): qemu: Fix old tcp:host URIs more cleanly qemu: Prepare support for arbitrary migration protocol qemu: Add RDMA migration capabilities Michael R. Hines (3): qemu: Expose additional migration statistics qemu: RDMA migration support qemu: Memory pre-pinning support for RDMA migration include/libvirt/libvirt.h.in | 26 + src/qemu/qemu.conf | 8 + src/qemu/qemu_capabilities.c | 32 +- src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 8 + src/qemu/qemu_domain.c | 18 + src/qemu/qemu_migration.c | 216 +- src/qemu/qemu_migration.h | 3 +- src/qemu/qemu_monitor.c | 25 +- src/qemu/qemu_monitor.h | 13 + src/qemu/qemu_monitor_json.c | 61 +- src/qemu/qemu_monitor_json.h | 2 + tests/qemucapabilitiesdata/caps_1.2.2-1.replies | 10 + tests/qemucapabilitiesdata/caps_1.3.1-1.replies | 10 + tests/qemucapabilitiesdata/caps_1.4.2-1.replies | 10 + tests/qemucapabilitiesdata/caps_1.5.3-1.replies | 10 + tests/qemucapabilitiesdata/caps_1.6.0-1.replies | 22 + tests/qemucapabilitiesdata/caps_1.6.50-1.replies | 22 + tests/qemucapabilitiesdata/caps_2.1.1-1.caps | 162 ++ tests/qemucapabilitiesdata/caps_2.1.1-1.replies | 3264 ++++++++++++++++++++++ tests/qemucapabilitiestest.c | 1 + tools/virsh-domain.c | 34 + 22 files changed, 3886 insertions(+), 72 deletions(-) create mode 100644 tests/qemucapabilitiesdata/caps_2.1.1-1.caps create mode 100644 tests/qemucapabilitiesdata/caps_2.1.1-1.replies -- 2.1.0

From: "Michael R. Hines" <mrhines@us.ibm.com> RDMA migration uses the 'setup' state in QEMU to optionally lock all memory before the migration starts. The total time spent in this state is exposed as VIR_DOMAIN_JOB_SETUP_TIME. Additionally, QEMU also exports migration throughput (mbps) for both memory and disk, so let's add them too: VIR_DOMAIN_JOB_MEMORY_BPS, VIR_DOMAIN_JOB_DISK_BPS. Signed-off-by: Michael R. Hines <mrhines@us.ibm.com> Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- Notes: Version 3: - changed MBPS to BPS - added support for both memory and disk BPS - changed BPS to ULLONG - added code to transfer the new statistics to the destination daemon when migration completes - added the new parameters to virsh include/libvirt/libvirt.h.in | 25 +++++++++++++++++++++++++ src/qemu/qemu_domain.c | 18 ++++++++++++++++++ src/qemu/qemu_migration.c | 17 +++++++++++++++++ src/qemu/qemu_monitor.h | 9 +++++++++ src/qemu/qemu_monitor_json.c | 17 +++++++++++++++++ tools/virsh-domain.c | 27 +++++++++++++++++++++++++++ 6 files changed, 113 insertions(+) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index c2f9d26..702f797 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -4388,6 +4388,15 @@ int virDomainAbortJob(virDomainPtr dom); #define VIR_DOMAIN_JOB_DOWNTIME "downtime" /** + * VIR_DOMAIN_JOB_SETUP_TIME: + * + * virDomainGetJobStats field: total time in milliseconds spent preparing + * the migration in the 'setup' phase before the iterations begin, as + * VIR_TYPED_PARAM_ULLONG. + */ +#define VIR_DOMAIN_JOB_SETUP_TIME "setup_time" + +/** * VIR_DOMAIN_JOB_DATA_TOTAL: * * virDomainGetJobStats field: total number of bytes supposed to be @@ -4485,6 +4494,14 @@ int virDomainAbortJob(virDomainPtr dom); #define VIR_DOMAIN_JOB_MEMORY_NORMAL_BYTES "memory_normal_bytes" /** + * VIR_DOMAIN_JOB_MEMORY_BPS: + * + * virDomainGetJobStats field: network throughput used while migrating + * memory in Bytes per second, as VIR_TYPED_PARAM_ULLONG. + */ +#define VIR_DOMAIN_JOB_MEMORY_BPS "memory_bps" + +/** * VIR_DOMAIN_JOB_DISK_TOTAL: * * virDomainGetJobStats field: as VIR_DOMAIN_JOB_DATA_TOTAL but only @@ -4515,6 +4532,14 @@ int virDomainAbortJob(virDomainPtr dom); #define VIR_DOMAIN_JOB_DISK_REMAINING "disk_remaining" /** + * VIR_DOMAIN_JOB_DISK_BPS: + * + * virDomainGetJobStats field: network throughput used while migrating + * disks in Bytes per second, as VIR_TYPED_PARAM_ULLONG. + */ +#define VIR_DOMAIN_JOB_DISK_BPS "disk_bps" + +/** * VIR_DOMAIN_JOB_COMPRESSION_CACHE: * * virDomainGetJobStats field: size of the cache (in bytes) used for diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 863ab09..9b3edd7 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -304,6 +304,12 @@ qemuDomainJobInfoToParams(qemuDomainJobInfoPtr jobInfo, status->downtime) < 0) goto error; + if (status->setup_time_set && + virTypedParamsAddULLong(&par, &npar, &maxpar, + VIR_DOMAIN_JOB_SETUP_TIME, + status->setup_time) < 0) + goto error; + if (virTypedParamsAddULLong(&par, &npar, &maxpar, VIR_DOMAIN_JOB_DATA_TOTAL, status->ram_total + @@ -329,6 +335,12 @@ qemuDomainJobInfoToParams(qemuDomainJobInfoPtr jobInfo, status->ram_remaining) < 0) goto error; + if (status->ram_bps && + virTypedParamsAddULLong(&par, &npar, &maxpar, + VIR_DOMAIN_JOB_MEMORY_BPS, + status->ram_bps) < 0) + goto error; + if (status->ram_duplicate_set) { if (virTypedParamsAddULLong(&par, &npar, &maxpar, VIR_DOMAIN_JOB_MEMORY_CONSTANT, @@ -353,6 +365,12 @@ qemuDomainJobInfoToParams(qemuDomainJobInfoPtr jobInfo, status->disk_remaining) < 0) goto error; + if (status->disk_bps && + virTypedParamsAddULLong(&par, &npar, &maxpar, + VIR_DOMAIN_JOB_DISK_BPS, + status->disk_bps) < 0) + goto error; + if (status->xbzrle_set) { if (virTypedParamsAddULLong(&par, &npar, &maxpar, VIR_DOMAIN_JOB_COMPRESSION_CACHE, diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index ce1a5cd..d738f9b 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -636,6 +636,10 @@ qemuMigrationCookieStatisticsXMLFormat(virBufferPtr buf, virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n", VIR_DOMAIN_JOB_DOWNTIME, status->downtime); + if (status->setup_time_set) + virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n", + VIR_DOMAIN_JOB_SETUP_TIME, + status->setup_time); virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n", VIR_DOMAIN_JOB_MEMORY_TOTAL, @@ -646,6 +650,9 @@ qemuMigrationCookieStatisticsXMLFormat(virBufferPtr buf, virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n", VIR_DOMAIN_JOB_MEMORY_REMAINING, status->ram_remaining); + virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n", + VIR_DOMAIN_JOB_MEMORY_BPS, + status->ram_bps); if (status->ram_duplicate_set) { virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n", @@ -668,6 +675,9 @@ qemuMigrationCookieStatisticsXMLFormat(virBufferPtr buf, virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n", VIR_DOMAIN_JOB_DISK_REMAINING, status->disk_remaining); + virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n", + VIR_DOMAIN_JOB_DISK_BPS, + status->disk_bps); if (status->xbzrle_set) { virBufferAsprintf(buf, "<%1$s>%2$llu</%1$s>\n", @@ -904,6 +914,9 @@ qemuMigrationCookieStatisticsXMLParse(xmlXPathContextPtr ctxt) if (virXPathULongLong("string(./" VIR_DOMAIN_JOB_DOWNTIME "[1])", ctxt, &status->downtime) == 0) status->downtime_set = true; + if (virXPathULongLong("string(./" VIR_DOMAIN_JOB_SETUP_TIME "[1])", + ctxt, &status->setup_time) == 0) + status->setup_time_set = true; virXPathULongLong("string(./" VIR_DOMAIN_JOB_MEMORY_TOTAL "[1])", ctxt, &status->ram_total); @@ -911,6 +924,8 @@ qemuMigrationCookieStatisticsXMLParse(xmlXPathContextPtr ctxt) ctxt, &status->ram_transferred); virXPathULongLong("string(./" VIR_DOMAIN_JOB_MEMORY_REMAINING "[1])", ctxt, &status->ram_remaining); + virXPathULongLong("string(./" VIR_DOMAIN_JOB_MEMORY_BPS "[1])", + ctxt, &status->ram_bps); if (virXPathULongLong("string(./" VIR_DOMAIN_JOB_MEMORY_CONSTANT "[1])", ctxt, &status->ram_duplicate) == 0) @@ -926,6 +941,8 @@ qemuMigrationCookieStatisticsXMLParse(xmlXPathContextPtr ctxt) ctxt, &status->disk_transferred); virXPathULongLong("string(./" VIR_DOMAIN_JOB_DISK_REMAINING "[1])", ctxt, &status->disk_remaining); + virXPathULongLong("string(./" VIR_DOMAIN_JOB_DISK_BPS "[1])", + ctxt, &status->disk_bps); if (virXPathULongLong("string(./" VIR_DOMAIN_JOB_COMPRESSION_CACHE "[1])", ctxt, &status->xbzrle_cache_size) == 0) diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 61a14d4..5fb83ff 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -423,10 +423,18 @@ struct _qemuMonitorMigrationStatus { /* total or expected depending on status */ bool downtime_set; unsigned long long downtime; + /* + * Duration of the QEMU 'setup' state. + * for RDMA, this may be on the order of several seconds + * if pinning support is requested before the migration begins. + */ + bool setup_time_set; + unsigned long long setup_time; unsigned long long ram_transferred; unsigned long long ram_remaining; unsigned long long ram_total; + unsigned long long ram_bps; bool ram_duplicate_set; unsigned long long ram_duplicate; unsigned long long ram_normal; @@ -435,6 +443,7 @@ struct _qemuMonitorMigrationStatus { unsigned long long disk_transferred; unsigned long long disk_remaining; unsigned long long disk_total; + unsigned long long disk_bps; bool xbzrle_set; unsigned long long xbzrle_cache_size; diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 1e14a95..ce3b2cd 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -2469,6 +2469,7 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply, virJSONValuePtr ret; const char *statusstr; int rc; + double mbps; if (!(ret = virJSONValueObjectGet(reply, "return"))) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -2501,6 +2502,10 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply, if (rc == 0) status->downtime_set = true; + if (virJSONValueObjectGetNumberUlong(ret, "setup-time", + &status->setup_time) == 0) + status->setup_time_set = true; + if (status->status == QEMU_MONITOR_MIGRATION_STATUS_ACTIVE || status->status == QEMU_MONITOR_MIGRATION_STATUS_COMPLETED) { virJSONValuePtr ram = virJSONValueObjectGet(ret, "ram"); @@ -2532,6 +2537,12 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply, return -1; } + if (virJSONValueObjectGetNumberDouble(ram, "mbps", &mbps) == 0 && + mbps > 0) { + /* mpbs from QEMU reports Mbits/s (M as in 10^6 not Mi as 2^20) */ + status->ram_bps = mbps * (1000 * 1000 / 8); + } + if (virJSONValueObjectGetNumberUlong(ram, "duplicate", &status->ram_duplicate) == 0) status->ram_duplicate_set = true; @@ -2568,6 +2579,12 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply, "data was missing")); return -1; } + + if (virJSONValueObjectGetNumberDouble(disk, "mbps", &mbps) == 0 && + mbps > 0) { + /* mpbs from QEMU reports Mbits/s (M as in 10^6 not Mi as 2^20) */ + status->disk_bps = mbps * (1000 * 1000 / 8); + } } virJSONValuePtr comp = virJSONValueObjectGet(ret, "xbzrle-cache"); diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 435d045..105b99e 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -5518,6 +5518,16 @@ cmdDomjobinfo(vshControl *ctl, const vshCmd *cmd) vshPrint(ctl, "%-17s %-.3lf %s\n", _("Memory remaining:"), val, unit); val = vshPrettyCapacity(info.memTotal, &unit); vshPrint(ctl, "%-17s %-.3lf %s\n", _("Memory total:"), val, unit); + + if ((rc = virTypedParamsGetULLong(params, nparams, + VIR_DOMAIN_JOB_MEMORY_BPS, + &value)) < 0) { + goto save_error; + } else if (rc && value) { + val = vshPrettyCapacity(value, &unit); + vshPrint(ctl, "%-17s %-.3lf %s/s\n", + _("Memory bandwidth:"), val, unit); + } } if (info.fileTotal || info.fileRemaining || info.fileProcessed) { @@ -5527,6 +5537,16 @@ cmdDomjobinfo(vshControl *ctl, const vshCmd *cmd) vshPrint(ctl, "%-17s %-.3lf %s\n", _("File remaining:"), val, unit); val = vshPrettyCapacity(info.fileTotal, &unit); vshPrint(ctl, "%-17s %-.3lf %s\n", _("File total:"), val, unit); + + if ((rc = virTypedParamsGetULLong(params, nparams, + VIR_DOMAIN_JOB_DISK_BPS, + &value)) < 0) { + goto save_error; + } else if (rc && value) { + val = vshPrettyCapacity(value, &unit); + vshPrint(ctl, "%-17s %-.3lf %s/s\n", + _("File bandwidth:"), val, unit); + } } if ((rc = virTypedParamsGetULLong(params, nparams, @@ -5567,6 +5587,13 @@ cmdDomjobinfo(vshControl *ctl, const vshCmd *cmd) } if ((rc = virTypedParamsGetULLong(params, nparams, + VIR_DOMAIN_JOB_SETUP_TIME, + &value)) < 0) + goto save_error; + else if (rc) + vshPrint(ctl, "%-17s %-12llu ms\n", _("Setup time:"), value); + + if ((rc = virTypedParamsGetULLong(params, nparams, VIR_DOMAIN_JOB_COMPRESSION_CACHE, &value)) < 0) { goto save_error; -- 2.1.0

For compatibility with old libvirt we need to support both tcp:host and tcp://host migration URIs. Let's make the code that parses them a bit cleaner. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- Notes: Version 3: - new patch to make "qemu: RDMA migration support" a bit more straightforward src/qemu/qemu_migration.c | 77 ++++++++++++++++++++--------------------------- 1 file changed, 33 insertions(+), 44 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index d738f9b..5741de2 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2817,6 +2817,29 @@ qemuMigrationPrepareTunnel(virQEMUDriverPtr driver, } +static virURIPtr +qemuMigrationParseURI(const char *uri, bool *wellFormed) +{ + char *tmp = NULL; + virURIPtr parsed; + + /* For compatibility reasons tcp://... URIs are sent as tcp:... + * We need to transform them to a well-formed URI before parsing. */ + if (STRPREFIX(uri, "tcp:") && !STRPREFIX(uri + 4, "//")) { + if (virAsprintf(&tmp, "tcp://%s", uri + 4) < 0) + return NULL; + uri = tmp; + } + + parsed = virURIParse(uri); + if (parsed && wellFormed) + *wellFormed = !tmp; + VIR_FREE(tmp); + + return parsed; +} + + int qemuMigrationPrepareDirect(virQEMUDriverPtr driver, virConnectPtr dconn, @@ -2834,11 +2857,8 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver, unsigned short port = 0; bool autoPort = true; char *hostname = NULL; - const char *p; - char *uri_str = NULL; int ret = -1; virURIPtr uri = NULL; - bool well_formed_uri = true; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); const char *migrateHost = cfg->migrateHost; @@ -2890,34 +2910,18 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver, * compatibility with old targets. We at least make the * new targets accept both syntaxes though. */ - /* Caller frees */ if (virAsprintf(uri_out, "tcp:%s:%d", hostname, port) < 0) goto cleanup; } else { - /* Check the URI starts with "tcp:". We will escape the - * URI when passing it to the qemu monitor, so bad - * characters in hostname part don't matter. - */ - if (!(p = STRSKIP(uri_in, "tcp:"))) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("only tcp URIs are supported for KVM/QEMU" - " migrations")); + bool well_formed_uri; + + if (!(uri = qemuMigrationParseURI(uri_in, &well_formed_uri))) goto cleanup; - } - /* Convert uri_in to well-formed URI with // after tcp: */ - if (!(STRPREFIX(uri_in, "tcp://"))) { - well_formed_uri = false; - if (virAsprintf(&uri_str, "tcp://%s", p) < 0) - goto cleanup; - } - - uri = virURIParse(uri_str ? uri_str : uri_in); - VIR_FREE(uri_str); - - if (uri == NULL) { - virReportError(VIR_ERR_INVALID_ARG, _("unable to parse URI: %s"), - uri_in); + if (STRNEQ(uri->scheme, "tcp")) { + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, + _("unsupported scheme %s in migration URI %s"), + uri->scheme, uri_in); goto cleanup; } @@ -2931,27 +2935,22 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver, if (virPortAllocatorAcquire(driver->migrationPorts, &port) < 0) goto cleanup; + /* Send well-formed URI only if uri_in was well-formed */ if (well_formed_uri) { uri->port = port; - - /* Caller frees */ if (!(*uri_out = virURIFormat(uri))) goto cleanup; } else { - /* Caller frees */ if (virAsprintf(uri_out, "%s:%d", uri_in, port) < 0) goto cleanup; } - } else { port = uri->port; autoPort = false; } } - if (*uri_out) - VIR_DEBUG("Generated uri_out=%s", *uri_out); - + VIR_DEBUG("Generated uri_out=%s", *uri_out); ret = qemuMigrationPrepareAny(driver, dconn, cookiein, cookieinlen, cookieout, cookieoutlen, def, origname, NULL, port, autoPort, listenAddress, flags); @@ -3704,17 +3703,7 @@ static int doNativeMigrate(virQEMUDriverPtr driver, cookieout, cookieoutlen, flags, resource, NULLSTR(graphicsuri)); - if (STRPREFIX(uri, "tcp:") && !STRPREFIX(uri, "tcp://")) { - char *tmp; - /* HACK: source host generates bogus URIs, so fix them up */ - if (virAsprintf(&tmp, "tcp://%s", uri + strlen("tcp:")) < 0) - return -1; - uribits = virURIParse(tmp); - VIR_FREE(tmp); - } else { - uribits = virURIParse(uri); - } - if (!uribits) + if (!(uribits = qemuMigrationParseURI(uri, NULL))) return -1; if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD)) -- 2.1.0

On 09/17/2014 04:53 PM, Jiri Denemark wrote:
For compatibility with old libvirt we need to support both tcp:host and tcp://host migration URIs. Let's make the code that parses them a bit cleaner.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> ---
Notes: Version 3: - new patch to make "qemu: RDMA migration support" a bit more straightforward
src/qemu/qemu_migration.c | 77 ++++++++++++++++++++--------------------------- 1 file changed, 33 insertions(+), 44 deletions(-)
@@ -2931,27 +2935,22 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver, if (virPortAllocatorAcquire(driver->migrationPorts, &port) < 0) goto cleanup;
+ /* Send well-formed URI only if uri_in was well-formed */ if (well_formed_uri) { uri->port = port; - - /* Caller frees */ if (!(*uri_out = virURIFormat(uri))) goto cleanup; } else { - /* Caller frees */ if (virAsprintf(uri_out, "%s:%d", uri_in, port) < 0) goto cleanup; } - } else { port = uri->port; autoPort = false; } }
- if (*uri_out) - VIR_DEBUG("Generated uri_out=%s", *uri_out); - + VIR_DEBUG("Generated uri_out=%s", *uri_out);
If uri_in contains a port, uri_out will not be generated. ACK with this hunk removed. Jan

On Mon, Sep 22, 2014 at 18:34:47 +0200, Jano Tomko wrote:
On 09/17/2014 04:53 PM, Jiri Denemark wrote:
For compatibility with old libvirt we need to support both tcp:host and tcp://host migration URIs. Let's make the code that parses them a bit cleaner.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> ---
Notes: Version 3: - new patch to make "qemu: RDMA migration support" a bit more straightforward
src/qemu/qemu_migration.c | 77 ++++++++++++++++++++--------------------------- 1 file changed, 33 insertions(+), 44 deletions(-)
@@ -2931,27 +2935,22 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver, if (virPortAllocatorAcquire(driver->migrationPorts, &port) < 0) goto cleanup;
+ /* Send well-formed URI only if uri_in was well-formed */ if (well_formed_uri) { uri->port = port; - - /* Caller frees */ if (!(*uri_out = virURIFormat(uri))) goto cleanup; } else { - /* Caller frees */ if (virAsprintf(uri_out, "%s:%d", uri_in, port) < 0) goto cleanup; } - } else { port = uri->port; autoPort = false; } }
- if (*uri_out) - VIR_DEBUG("Generated uri_out=%s", *uri_out); - + VIR_DEBUG("Generated uri_out=%s", *uri_out);
If uri_in contains a port, uri_out will not be generated.
Oh right, I knew I was missing something :-) Jirka

Currently we only support TCP protocol for native QEMU migration but this is going to be changed. Let's make the code more general and remove hardcoded TCP protocol from several places. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- Notes: Version 3: - separated from "qemu: RDMA migration support" src/qemu/qemu_migration.c | 36 ++++++++++++++++++++++++------------ src/qemu/qemu_monitor.c | 3 ++- src/qemu/qemu_monitor.h | 1 + 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 5741de2..d0e2653 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2457,6 +2457,7 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver, virDomainDefPtr *def, const char *origname, virStreamPtr st, + const char *protocol, unsigned short port, bool autoPort, const char *listenAddress, @@ -2569,6 +2570,7 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver, struct addrinfo *info = NULL; struct addrinfo hints = { .ai_flags = AI_ADDRCONFIG, .ai_socktype = SOCK_STREAM }; + const char *incFormat; if (getaddrinfo("::", NULL, &hints, &info) == 0) { freeaddrinfo(info); @@ -2605,21 +2607,27 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver, } else { /* listenAddress is a hostname */ } - } else { + } else if (qemuIPv6Capable && hostIPv6Capable) { /* Listen on :: instead of 0.0.0.0 if QEMU understands it * and there is at least one IPv6 address configured */ - listenAddress = qemuIPv6Capable && hostIPv6Capable ? - encloseAddress = true, "::" : "0.0.0.0"; + listenAddress = "::"; + encloseAddress = true; + } else { + listenAddress = "0.0.0.0"; } - /* QEMU will be started with -incoming [<IPv6 addr>]:port, - * -incoming <IPv4 addr>:port or -incoming <hostname>:port + /* QEMU will be started with + * -incoming protocol:[<IPv6 addr>]:port, + * -incoming protocol:<IPv4 addr>:port, or + * -incoming protocol:<hostname>:port */ - if ((encloseAddress && - virAsprintf(&migrateFrom, "tcp:[%s]:%d", listenAddress, port) < 0) || - (!encloseAddress && - virAsprintf(&migrateFrom, "tcp:%s:%d", listenAddress, port) < 0)) + if (encloseAddress) + incFormat = "%s:[%s]:%d"; + else + incFormat = "%s:%s:%d"; + if (virAsprintf(&migrateFrom, incFormat, + protocol, listenAddress, port) < 0) goto cleanup; } @@ -2812,7 +2820,7 @@ qemuMigrationPrepareTunnel(virQEMUDriverPtr driver, ret = qemuMigrationPrepareAny(driver, dconn, cookiein, cookieinlen, cookieout, cookieoutlen, def, origname, - st, 0, false, NULL, flags); + st, NULL, 0, false, NULL, flags); return ret; } @@ -2953,7 +2961,8 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver, VIR_DEBUG("Generated uri_out=%s", *uri_out); ret = qemuMigrationPrepareAny(driver, dconn, cookiein, cookieinlen, cookieout, cookieoutlen, def, origname, - NULL, port, autoPort, listenAddress, flags); + NULL, uri ? uri->scheme : "tcp", + port, autoPort, listenAddress, flags); cleanup: virURIFree(uri); VIR_FREE(hostname); @@ -3169,6 +3178,7 @@ struct _qemuMigrationSpec { enum qemuMigrationDestinationType destType; union { struct { + const char *protocol; const char *name; int port; } host; @@ -3536,6 +3546,7 @@ qemuMigrationRun(virQEMUDriverPtr driver, switch (spec->destType) { case MIGRATION_DEST_HOST: ret = qemuMonitorMigrateToHost(priv->mon, migrate_flags, + spec->dest.host.protocol, spec->dest.host.name, spec->dest.host.port); break; @@ -3676,7 +3687,7 @@ qemuMigrationRun(virQEMUDriverPtr driver, goto cleanup; } -/* Perform migration using QEMU's native TCP migrate support, +/* Perform migration using QEMU's native migrate support, * not encrypted obviously */ static int doNativeMigrate(virQEMUDriverPtr driver, @@ -3710,6 +3721,7 @@ static int doNativeMigrate(virQEMUDriverPtr driver, spec.destType = MIGRATION_DEST_CONNECT_HOST; else spec.destType = MIGRATION_DEST_HOST; + spec.dest.host.protocol = uribits->scheme; spec.dest.host.name = uribits->server; spec.dest.host.port = uribits->port; spec.fwdType = MIGRATION_FWD_DIRECT; diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 3603cd8..31ab37d 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -2205,6 +2205,7 @@ int qemuMonitorMigrateToFd(qemuMonitorPtr mon, int qemuMonitorMigrateToHost(qemuMonitorPtr mon, unsigned int flags, + const char *protocol, const char *hostname, int port) { @@ -2220,7 +2221,7 @@ int qemuMonitorMigrateToHost(qemuMonitorPtr mon, } - if (virAsprintf(&uri, "tcp:%s:%d", hostname, port) < 0) + if (virAsprintf(&uri, "%s:%s:%d", protocol, hostname, port) < 0) return -1; if (mon->json) diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 5fb83ff..ca11631 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -485,6 +485,7 @@ int qemuMonitorMigrateToFd(qemuMonitorPtr mon, int qemuMonitorMigrateToHost(qemuMonitorPtr mon, unsigned int flags, + const char *protocol, const char *hostname, int port); -- 2.1.0

Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- Notes: Version 3: - separated from "qemu: RDMA migration support" - switched from version based to feature based probing - fixed existing capabilities tests - added new capabilities test for QEMU 2.1.1 which supports rdma-pin-all migration capability src/qemu/qemu_capabilities.c | 32 +- src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_monitor.c | 22 +- src/qemu/qemu_monitor.h | 3 + src/qemu/qemu_monitor_json.c | 44 +- src/qemu/qemu_monitor_json.h | 2 + tests/qemucapabilitiesdata/caps_1.2.2-1.replies | 10 + tests/qemucapabilitiesdata/caps_1.3.1-1.replies | 10 + tests/qemucapabilitiesdata/caps_1.4.2-1.replies | 10 + tests/qemucapabilitiesdata/caps_1.5.3-1.replies | 10 + tests/qemucapabilitiesdata/caps_1.6.0-1.replies | 22 + tests/qemucapabilitiesdata/caps_1.6.50-1.replies | 22 + tests/qemucapabilitiesdata/caps_2.1.1-1.caps | 162 ++ tests/qemucapabilitiesdata/caps_2.1.1-1.replies | 3264 ++++++++++++++++++++++ tests/qemucapabilitiestest.c | 1 + 15 files changed, 3602 insertions(+), 13 deletions(-) create mode 100644 tests/qemucapabilitiesdata/caps_2.1.1-1.caps create mode 100644 tests/qemucapabilitiesdata/caps_2.1.1-1.replies diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 9f8868d..30b3c5d 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -269,6 +269,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, "splash-timeout", /* 175 */ "iothread", + "migrate-rdma", ); @@ -993,9 +994,9 @@ virCapsPtr virQEMUCapsInit(virQEMUCapsCachePtr cache) if (virQEMUCapsInitPages(caps) < 0) VIR_WARN("Failed to get pages info"); - /* Add domain migration transport URI */ - virCapabilitiesAddHostMigrateTransport(caps, - "tcp"); + /* Add domain migration transport URIs */ + virCapabilitiesAddHostMigrateTransport(caps, "tcp"); + virCapabilitiesAddHostMigrateTransport(caps, "rdma"); /* QEMU can support pretty much every arch that exists, * so just probe for them all - we gracefully fail @@ -1435,6 +1436,10 @@ struct virQEMUCapsStringFlags virQEMUCapsCommands[] = { { "rtc-reset-reinjection", QEMU_CAPS_RTC_RESET_REINJECTION }, }; +struct virQEMUCapsStringFlags virQEMUCapsMigration[] = { + { "rdma-pin-all", QEMU_CAPS_MIGRATE_RDMA }, +}; + struct virQEMUCapsStringFlags virQEMUCapsEvents[] = { { "BALLOON_CHANGE", QEMU_CAPS_BALLOON_EVENT }, { "SPICE_MIGRATE_COMPLETED", QEMU_CAPS_SEAMLESS_MIGRATION }, @@ -2476,6 +2481,25 @@ virQEMUCapsProbeQMPCommandLine(virQEMUCapsPtr qemuCaps, return 0; } +static int +virQEMUCapsProbeQMPMigrationCapabilities(virQEMUCapsPtr qemuCaps, + qemuMonitorPtr mon) +{ + char **caps = NULL; + int ncaps; + + if ((ncaps = qemuMonitorGetMigrationCapabilities(mon, &caps)) < 0) + return -1; + + virQEMUCapsProcessStringFlags(qemuCaps, + ARRAY_CARDINALITY(virQEMUCapsMigration), + virQEMUCapsMigration, + ncaps, caps); + virQEMUCapsFreeStringList(ncaps, caps); + + return 0; +} + int virQEMUCapsProbeQMP(virQEMUCapsPtr qemuCaps, qemuMonitorPtr mon) { @@ -3168,6 +3192,8 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps, goto cleanup; if (virQEMUCapsProbeQMPCommandLine(qemuCaps, mon) < 0) goto cleanup; + if (virQEMUCapsProbeQMPMigrationCapabilities(qemuCaps, mon) < 0) + goto cleanup; ret = 0; cleanup: diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 0980c00..6a8b84f 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -216,6 +216,7 @@ typedef enum { QEMU_CAPS_RTC_RESET_REINJECTION = 174, /* rtc-reset-reinjection monitor command */ QEMU_CAPS_SPLASH_TIMEOUT = 175, /* -boot splash-time */ QEMU_CAPS_OBJECT_IOTHREAD = 176, /* -object iothread */ + QEMU_CAPS_MIGRATE_RDMA = 177, /* have rdma migration */ QEMU_CAPS_LAST, /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 31ab37d..0f48398 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -121,7 +121,7 @@ VIR_ENUM_IMPL(qemuMonitorMigrationStatus, VIR_ENUM_IMPL(qemuMonitorMigrationCaps, QEMU_MONITOR_MIGRATION_CAPS_LAST, - "xbzrle", "auto-converge") + "xbzrle", "auto-converge", "rdma-pin-all") VIR_ENUM_IMPL(qemuMonitorVMStatus, QEMU_MONITOR_VM_STATUS_LAST, @@ -3762,6 +3762,26 @@ char *qemuMonitorGetTargetArch(qemuMonitorPtr mon) } +int +qemuMonitorGetMigrationCapabilities(qemuMonitorPtr mon, + char ***capabilities) +{ + VIR_DEBUG("mon=%p", mon); + + if (!mon) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("monitor must not be NULL")); + return -1; + } + + /* No capability is supported without JSON monitor */ + if (!mon->json) + return 0; + + return qemuMonitorJSONGetMigrationCapabilities(mon, capabilities); +} + + /** * Returns 1 if @capability is supported, 0 if it's not, or -1 on error. */ diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index ca11631..a53b0f1 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -461,12 +461,15 @@ int qemuMonitorGetSpiceMigrationStatus(qemuMonitorPtr mon, typedef enum { QEMU_MONITOR_MIGRATION_CAPS_XBZRLE, QEMU_MONITOR_MIGRATION_CAPS_AUTO_CONVERGE, + QEMU_MONITOR_MIGRATION_CAPS_RDMA_PIN_ALL, QEMU_MONITOR_MIGRATION_CAPS_LAST } qemuMonitorMigrationCaps; VIR_ENUM_DECL(qemuMonitorMigrationCaps); +int qemuMonitorGetMigrationCapabilities(qemuMonitorPtr mon, + char ***capabilities); int qemuMonitorGetMigrationCapability(qemuMonitorPtr mon, qemuMonitorMigrationCaps capability); int qemuMonitorSetMigrationCapability(qemuMonitorPtr mon, diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index ce3b2cd..b43a527 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -5164,14 +5164,18 @@ qemuMonitorJSONGetTargetArch(qemuMonitorPtr mon) int -qemuMonitorJSONGetMigrationCapability(qemuMonitorPtr mon, - qemuMonitorMigrationCaps capability) +qemuMonitorJSONGetMigrationCapabilities(qemuMonitorPtr mon, + char ***capabilities) { int ret; virJSONValuePtr cmd; virJSONValuePtr reply = NULL; virJSONValuePtr caps; + char **list = NULL; size_t i; + int n; + + *capabilities = NULL; if (!(cmd = qemuMonitorJSONMakeCommand("query-migrate-capabilities", NULL))) @@ -5190,14 +5194,17 @@ qemuMonitorJSONGetMigrationCapability(qemuMonitorPtr mon, ret = -1; - caps = virJSONValueObjectGet(reply, "return"); - if (!caps || caps->type != VIR_JSON_TYPE_ARRAY) { + if (!(caps = virJSONValueObjectGet(reply, "return")) || + (n = virJSONValueArraySize(caps)) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("missing migration capabilities")); goto cleanup; } - for (i = 0; i < virJSONValueArraySize(caps); i++) { + if (VIR_ALLOC_N(list, n + 1) < 0) + goto cleanup; + + for (i = 0; i < n; i++) { virJSONValuePtr cap = virJSONValueArrayGet(caps, i); const char *name; @@ -5213,15 +5220,16 @@ qemuMonitorJSONGetMigrationCapability(qemuMonitorPtr mon, goto cleanup; } - if (qemuMonitorMigrationCapsTypeFromString(name) == capability) { - ret = 1; + if (VIR_STRDUP(list[i], name) < 1) goto cleanup; - } } - ret = 0; + ret = n; + *capabilities = list; cleanup: + if (ret < 0) + virStringFreeList(list); virJSONValueFree(cmd); virJSONValueFree(reply); return ret; @@ -5229,6 +5237,24 @@ qemuMonitorJSONGetMigrationCapability(qemuMonitorPtr mon, int +qemuMonitorJSONGetMigrationCapability(qemuMonitorPtr mon, + qemuMonitorMigrationCaps capability) +{ + int ret; + char **capsList = NULL; + const char *cap = qemuMonitorMigrationCapsTypeToString(capability); + + if (qemuMonitorJSONGetMigrationCapabilities(mon, &capsList) < 0) + return -1; + + ret = virStringArrayHasString(capsList, cap); + + virStringFreeList(capsList); + return ret; +} + + +int qemuMonitorJSONSetMigrationCapability(qemuMonitorPtr mon, qemuMonitorMigrationCaps capability) { diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 732209d..5c5d810 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -133,6 +133,8 @@ int qemuMonitorJSONSetMigrationCacheSize(qemuMonitorPtr mon, int qemuMonitorJSONGetMigrationStatus(qemuMonitorPtr mon, qemuMonitorMigrationStatusPtr status); +int qemuMonitorJSONGetMigrationCapabilities(qemuMonitorPtr mon, + char ***capabilities); int qemuMonitorJSONGetMigrationCapability(qemuMonitorPtr mon, qemuMonitorMigrationCaps capability); int qemuMonitorJSONSetMigrationCapability(qemuMonitorPtr mon, diff --git a/tests/qemucapabilitiesdata/caps_1.2.2-1.replies b/tests/qemucapabilitiesdata/caps_1.2.2-1.replies index 345c32b..4fce9d7 100644 --- a/tests/qemucapabilitiesdata/caps_1.2.2-1.replies +++ b/tests/qemucapabilitiesdata/caps_1.2.2-1.replies @@ -1555,3 +1555,13 @@ "desc": "The command query-command-line-options has not been found" } } + +{ + "return": [ + { + "capability": "xbzrle", + "state": false + } + ], + "id": "libvirt-32" +} diff --git a/tests/qemucapabilitiesdata/caps_1.3.1-1.replies b/tests/qemucapabilitiesdata/caps_1.3.1-1.replies index 04d2141..43713b2 100644 --- a/tests/qemucapabilitiesdata/caps_1.3.1-1.replies +++ b/tests/qemucapabilitiesdata/caps_1.3.1-1.replies @@ -1735,3 +1735,13 @@ "desc": "The command query-command-line-options has not been found" } } + +{ + "return": [ + { + "capability": "xbzrle", + "state": false + } + ], + "id": "libvirt-34" +} diff --git a/tests/qemucapabilitiesdata/caps_1.4.2-1.replies b/tests/qemucapabilitiesdata/caps_1.4.2-1.replies index aef359c..34384f8 100644 --- a/tests/qemucapabilitiesdata/caps_1.4.2-1.replies +++ b/tests/qemucapabilitiesdata/caps_1.4.2-1.replies @@ -1785,3 +1785,13 @@ "desc": "The command query-command-line-options has not been found" } } + +{ + "return": [ + { + "capability": "xbzrle", + "state": false + } + ], + "id": "libvirt-34" +} diff --git a/tests/qemucapabilitiesdata/caps_1.5.3-1.replies b/tests/qemucapabilitiesdata/caps_1.5.3-1.replies index 1f84bb6..4613472 100644 --- a/tests/qemucapabilitiesdata/caps_1.5.3-1.replies +++ b/tests/qemucapabilitiesdata/caps_1.5.3-1.replies @@ -2539,3 +2539,13 @@ ], "id": "libvirt-33" } + +{ + "return": [ + { + "capability": "xbzrle", + "state": false + } + ], + "id": "libvirt-34" +} diff --git a/tests/qemucapabilitiesdata/caps_1.6.0-1.replies b/tests/qemucapabilitiesdata/caps_1.6.0-1.replies index c9dc29b..4205c89 100644 --- a/tests/qemucapabilitiesdata/caps_1.6.0-1.replies +++ b/tests/qemucapabilitiesdata/caps_1.6.0-1.replies @@ -2519,3 +2519,25 @@ ], "id": "libvirt-33" } + +{ + "return": [ + { + "capability": "xbzrle", + "state": false + }, + { + "capability": "x-rdma-pin-all", + "state": false + }, + { + "capability": "auto-converge", + "state": false + }, + { + "capability": "zero-blocks", + "state": false + } + ], + "id": "libvirt-34" +} diff --git a/tests/qemucapabilitiesdata/caps_1.6.50-1.replies b/tests/qemucapabilitiesdata/caps_1.6.50-1.replies index ec7451f..7582385 100644 --- a/tests/qemucapabilitiesdata/caps_1.6.50-1.replies +++ b/tests/qemucapabilitiesdata/caps_1.6.50-1.replies @@ -2501,3 +2501,25 @@ ], "id": "libvirt-33" } + +{ + "return": [ + { + "capability": "xbzrle", + "state": false + }, + { + "capability": "x-rdma-pin-all", + "state": false + }, + { + "capability": "auto-converge", + "state": false + }, + { + "capability": "zero-blocks", + "state": false + } + ], + "id": "libvirt-34" +} diff --git a/tests/qemucapabilitiesdata/caps_2.1.1-1.caps b/tests/qemucapabilitiesdata/caps_2.1.1-1.caps new file mode 100644 index 0000000..71d2459 --- /dev/null +++ b/tests/qemucapabilitiesdata/caps_2.1.1-1.caps @@ -0,0 +1,162 @@ + <qemuCaps> + <flag name='vnc-colon'/> + <flag name='no-reboot'/> + <flag name='drive'/> + <flag name='name'/> + <flag name='uuid'/> + <flag name='vnet-hdr'/> + <flag name='migrate-qemu-tcp'/> + <flag name='migrate-qemu-exec'/> + <flag name='drive-cache-v2'/> + <flag name='drive-format'/> + <flag name='vga'/> + <flag name='0.10'/> + <flag name='mem-path'/> + <flag name='drive-serial'/> + <flag name='migrate-qemu-unix'/> + <flag name='chardev'/> + <flag name='enable-kvm'/> + <flag name='monitor-json'/> + <flag name='balloon'/> + <flag name='device'/> + <flag name='sdl'/> + <flag name='smp-topology'/> + <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='drive-readonly'/> + <flag name='smbios-type'/> + <flag name='vga-qxl'/> + <flag name='spice'/> + <flag name='vga-none'/> + <flag name='migrate-qemu-fd'/> + <flag name='boot-index'/> + <flag name='hda-duplex'/> + <flag name='drive-aio'/> + <flag name='pci-multibus'/> + <flag name='pci-bootindex'/> + <flag name='ccid-emulated'/> + <flag name='ccid-passthru'/> + <flag name='chardev-spicevmc'/> + <flag name='virtio-tx-alg'/> + <flag name='device-qxl-vga'/> + <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='rombar'/> + <flag name='ich9-ahci'/> + <flag name='no-acpi'/> + <flag name='fsdev-readonly'/> + <flag name='virtio-blk-pci.scsi'/> + <flag name='blk-sg-io'/> + <flag name='drive-copy-on-read'/> + <flag name='cpu-host'/> + <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='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='reboot-timeout'/> + <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='memory-backend-file'/> + <flag name='numa'/> + <flag name='usb-audio'/> + <flag name='rtc-reset-reinjection'/> + <flag name='splash-timeout'/> + <flag name='iothread'/> + <flag name='migrate-rdma'/> + </qemuCaps> diff --git a/tests/qemucapabilitiesdata/caps_2.1.1-1.replies b/tests/qemucapabilitiesdata/caps_2.1.1-1.replies new file mode 100644 index 0000000..74d09dc --- /dev/null +++ b/tests/qemucapabilitiesdata/caps_2.1.1-1.replies @@ -0,0 +1,3264 @@ +{ + "QMP": { + "version": { + "qemu": { + "micro": 1, + "minor": 1, + "major": 2 + }, + "package": "" + }, + "capabilities": [ + ] + } +} + +{ + "return": { + }, + "id": "libvirt-1" +} + +{ + "return": { + "qemu": { + "micro": 1, + "minor": 1, + "major": 2 + }, + "package": "" + }, + "id": "libvirt-2" +} + +{ + "return": { + "arch": "x86_64" + }, + "id": "libvirt-3" +} + +{ + "return": [ + { + "name": "rtc-reset-reinjection" + }, + { + "name": "query-acpi-ospm-status" + }, + { + "name": "query-memory-devices" + }, + { + "name": "query-memdev" + }, + { + "name": "query-named-block-nodes" + }, + { + "name": "blockdev-add" + }, + { + "name": "query-rx-filter" + }, + { + "name": "chardev-remove" + }, + { + "name": "chardev-add" + }, + { + "name": "query-tpm-types" + }, + { + "name": "query-tpm-models" + }, + { + "name": "query-tpm" + }, + { + "name": "query-target" + }, + { + "name": "query-cpu-definitions" + }, + { + "name": "query-machines" + }, + { + "name": "device-list-properties" + }, + { + "name": "qom-list-types" + }, + { + "name": "change-vnc-password" + }, + { + "name": "nbd-server-stop" + }, + { + "name": "nbd-server-add" + }, + { + "name": "nbd-server-start" + }, + { + "name": "qom-get" + }, + { + "name": "qom-set" + }, + { + "name": "qom-list" + }, + { + "name": "query-block-jobs" + }, + { + "name": "query-balloon" + }, + { + "name": "query-migrate-capabilities" + }, + { + "name": "migrate-set-capabilities" + }, + { + "name": "query-migrate" + }, + { + "name": "query-command-line-options" + }, + { + "name": "query-uuid" + }, + { + "name": "query-name" + }, + { + "name": "query-spice" + }, + { + "name": "query-vnc" + }, + { + "name": "query-mice" + }, + { + "name": "query-status" + }, + { + "name": "query-kvm" + }, + { + "name": "query-pci" + }, + { + "name": "query-iothreads" + }, + { + "name": "query-cpus" + }, + { + "name": "query-blockstats" + }, + { + "name": "query-block" + }, + { + "name": "query-chardev-backends" + }, + { + "name": "query-chardev" + }, + { + "name": "query-events" + }, + { + "name": "query-commands" + }, + { + "name": "query-version" + }, + { + "name": "human-monitor-command" + }, + { + "name": "qmp_capabilities" + }, + { + "name": "add_client" + }, + { + "name": "expire_password" + }, + { + "name": "set_password" + }, + { + "name": "block_set_io_throttle" + }, + { + "name": "block_passwd" + }, + { + "name": "query-fdsets" + }, + { + "name": "remove-fd" + }, + { + "name": "add-fd" + }, + { + "name": "closefd" + }, + { + "name": "getfd" + }, + { + "name": "set_link" + }, + { + "name": "balloon" + }, + { + "name": "change-backing-file" + }, + { + "name": "drive-mirror" + }, + { + "name": "blockdev-snapshot-delete-internal-sync" + }, + { + "name": "blockdev-snapshot-internal-sync" + }, + { + "name": "blockdev-snapshot-sync" + }, + { + "name": "transaction" + }, + { + "name": "block-job-complete" + }, + { + "name": "block-job-resume" + }, + { + "name": "block-job-pause" + }, + { + "name": "block-job-cancel" + }, + { + "name": "block-job-set-speed" + }, + { + "name": "drive-backup" + }, + { + "name": "block-commit" + }, + { + "name": "block-stream" + }, + { + "name": "block_resize" + }, + { + "name": "object-del" + }, + { + "name": "object-add" + }, + { + "name": "netdev_del" + }, + { + "name": "netdev_add" + }, + { + "name": "query-dump-guest-memory-capability" + }, + { + "name": "dump-guest-memory" + }, + { + "name": "client_migrate_info" + }, + { + "name": "migrate_set_downtime" + }, + { + "name": "migrate_set_speed" + }, + { + "name": "query-migrate-cache-size" + }, + { + "name": "migrate-set-cache-size" + }, + { + "name": "migrate_cancel" + }, + { + "name": "migrate" + }, + { + "name": "xen-set-global-dirty-log" + }, + { + "name": "xen-save-devices-state" + }, + { + "name": "ringbuf-read" + }, + { + "name": "ringbuf-write" + }, + { + "name": "inject-nmi" + }, + { + "name": "pmemsave" + }, + { + "name": "memsave" + }, + { + "name": "cpu-add" + }, + { + "name": "cpu" + }, + { + "name": "send-key" + }, + { + "name": "device_del" + }, + { + "name": "device_add" + }, + { + "name": "system_powerdown" + }, + { + "name": "system_reset" + }, + { + "name": "system_wakeup" + }, + { + "name": "cont" + }, + { + "name": "stop" + }, + { + "name": "screendump" + }, + { + "name": "change" + }, + { + "name": "eject" + }, + { + "name": "quit" + } + ], + "id": "libvirt-4" +} + +{ + "return": { + "fd": 10, + "fdset-id": 0 + }, + "id": "libvirt-5" +} + +{ + "id": "libvirt-6", + "error": { + "class": "DeviceNotFound", + "desc": "Device 'bogus' not found" + } +} + +{ + "return": [ + { + "name": "VSERPORT_CHANGE" + }, + { + "name": "QUORUM_REPORT_BAD" + }, + { + "name": "QUORUM_FAILURE" + }, + { + "name": "GUEST_PANICKED" + }, + { + "name": "BALLOON_CHANGE" + }, + { + "name": "ACPI_DEVICE_OST" + }, + { + "name": "SPICE_MIGRATE_COMPLETED" + }, + { + "name": "SPICE_DISCONNECTED" + }, + { + "name": "SPICE_INITIALIZED" + }, + { + "name": "SPICE_CONNECTED" + }, + { + "name": "VNC_DISCONNECTED" + }, + { + "name": "VNC_INITIALIZED" + }, + { + "name": "VNC_CONNECTED" + }, + { + "name": "NIC_RX_FILTER_CHANGED" + }, + { + "name": "DEVICE_DELETED" + }, + { + "name": "WATCHDOG" + }, + { + "name": "RTC_CHANGE" + }, + { + "name": "WAKEUP" + }, + { + "name": "SUSPEND_DISK" + }, + { + "name": "SUSPEND" + }, + { + "name": "RESUME" + }, + { + "name": "STOP" + }, + { + "name": "RESET" + }, + { + "name": "POWERDOWN" + }, + { + "name": "SHUTDOWN" + }, + { + "name": "DEVICE_TRAY_MOVED" + }, + { + "name": "BLOCK_JOB_READY" + }, + { + "name": "BLOCK_JOB_ERROR" + }, + { + "name": "BLOCK_JOB_CANCELLED" + }, + { + "name": "BLOCK_JOB_COMPLETED" + }, + { + "name": "BLOCK_IO_ERROR" + }, + { + "name": "BLOCK_IMAGE_CORRUPTED" + } + ], + "id": "libvirt-7" +} + +{ + "return": [ + { + "name": "pc-0.13-machine" + }, + { + "name": "fw_cfg" + }, + { + "name": "i82551" + }, + { + "name": "i82550" + }, + { + "name": "Westmere-x86_64-cpu" + }, + { + "name": "xlnx,ps7-usb" + }, + { + "name": "e1000-82540em" + }, + { + "name": "pci-serial-4x" + }, + { + "name": "Penryn-x86_64-cpu" + }, + { + "name": "Haswell-x86_64-cpu" + }, + { + "name": "iothread" + }, + { + "name": "icc-bridge" + }, + { + "name": "cfi.pflash01" + }, + { + "name": "Opteron_G3-x86_64-cpu" + }, + { + "name": "Broadwell-x86_64-cpu" + }, + { + "name": "piix3-ide" + }, + { + "name": "isa-parallel" + }, + { + "name": "i2c-bus" + }, + { + "name": "megasas" + }, + { + "name": "usb-braille" + }, + { + "name": "exynos4210-ehci-usb" + }, + { + "name": "vmware-svga" + }, + { + "name": "pc-i440fx-2.0-machine" + }, + { + "name": "PIIX3-xen" + }, + { + "name": "ccid-bus" + }, + { + "name": "scsi-cd" + }, + { + "name": "isa-serial" + }, + { + "name": "usb-ehci" + }, + { + "name": "user-creatable" + }, + { + "name": "container" + }, + { + "name": "host-x86_64-cpu" + }, + { + "name": "pci-serial-2x" + }, + { + "name": "piix4-ide" + }, + { + "name": "scsi-generic" + }, + { + "name": "pc-1.0-machine" + }, + { + "name": "virtio-net-pci" + }, + { + "name": "pc-dimm" + }, + { + "name": "pc-i440fx-2.1-machine" + }, + { + "name": "isa-debugcon" + }, + { + "name": "ide-hd" + }, + { + "name": "qemu64-x86_64-cpu" + }, + { + "name": "pc-q35-1.7-machine" + }, + { + "name": "rng-egd" + }, + { + "name": "isa-pcspk" + }, + { + "name": "isa-pit" + }, + { + "name": "pc-1.1-machine" + }, + { + "name": "ich9-usb-ehci2" + }, + { + "name": "ich9-usb-ehci1" + }, + { + "name": "irq" + }, + { + "name": "cirrus-vga" + }, + { + "name": "virtconsole" + }, + { + "name": "virtio-rng-pci" + }, + { + "name": "PCIE" + }, + { + "name": "pentium3-x86_64-cpu" + }, + { + "name": "qxl-vga" + }, + { + "name": "ioapic" + }, + { + "name": "kvm-pit" + }, + { + "name": "pc-0.14-machine" + }, + { + "name": "xen-apic" + }, + { + "name": "pc-q35-2.0-machine" + }, + { + "name": "usb-host" + }, + { + "name": "usb-bus" + }, + { + "name": "pc-i440fx-1.4-machine" + }, + { + "name": "vhost-scsi-pci" + }, + { + "name": "usb-kbd" + }, + { + "name": "486-x86_64-cpu" + }, + { + "name": "ES1370" + }, + { + "name": "gus" + }, + { + "name": "isa-applesmc" + }, + { + "name": "PIIX3" + }, + { + "name": "kvm-pci-assign" + }, + { + "name": "xen-pci-passthrough" + }, + { + "name": "i82559er" + }, + { + "name": "e1000-82545em" + }, + { + "name": "q35-pcihost" + }, + { + "name": "tegra2-ehci-usb" + }, + { + "name": "pc-i440fx-1.5-machine" + }, + { + "name": "usb-bt-dongle" + }, + { + "name": "AC97" + }, + { + "name": "i6300esb" + }, + { + "name": "mc146818rtc" + }, + { + "name": "e1000-82544gc" + }, + { + "name": "PIIX4_PM" + }, + { + "name": "piix4-usb-uhci" + }, + { + "name": "sysbus-ahci" + }, + { + "name": "kvm-ioapic" + }, + { + "name": "pvpanic" + }, + { + "name": "core2duo-x86_64-cpu" + }, + { + "name": "virtio-9p-pci" + }, + { + "name": "scsi-disk" + }, + { + "name": "acpi-device-interface" + }, + { + "name": "sb16" + }, + { + "name": "pc-0.15-machine" + }, + { + "name": "xenfv-machine" + }, + { + "name": "usb-mouse" + }, + { + "name": "piix3-usb-uhci" + }, + { + "name": "virtio-scsi-device" + }, + { + "name": "virtio-blk-pci" + }, + { + "name": "virtio-9p-device" + }, + { + "name": "hda-output" + }, + { + "name": "SUNW,fdtwo" + }, + { + "name": "tpci200" + }, + { + "name": "Opteron_G4-x86_64-cpu" + }, + { + "name": "pc-q35-1.4-machine" + }, + { + "name": "virtio-mmio" + }, + { + "name": "qemu-console" + }, + { + "name": "isa-i8259" + }, + { + "name": "System" + }, + { + "name": "pvscsi" + }, + { + "name": "virtio-net-device" + }, + { + "name": "usb-hub" + }, + { + "name": "hda-duplex" + }, + { + "name": "isapc-machine" + }, + { + "name": "ipoctal232" + }, + { + "name": "pc-1.2-machine" + }, + { + "name": "xio3130-downstream" + }, + { + "name": "ide-cd" + }, + { + "name": "apic" + }, + { + "name": "isabus-bridge" + }, + { + "name": "memory-backend-file" + }, + { + "name": "isa-ide" + }, + { + "name": "isa-vga" + }, + { + "name": "qemu:memory-region" + }, + { + "name": "kvm-i8259" + }, + { + "name": "rng-random" + }, + { + "name": "hotplug-handler" + }, + { + "name": "pci-ohci" + }, + { + "name": "i440FX-pcihost" + }, + { + "name": "qemu32-x86_64-cpu" + }, + { + "name": "tpm-tis" + }, + { + "name": "tpm-passthrough" + }, + { + "name": "nec-usb-xhci" + }, + { + "name": "isa-debug-exit" + }, + { + "name": "pc-0.10-machine" + }, + { + "name": "pc-testdev" + }, + { + "name": "sga" + }, + { + "name": "Opteron_G1-x86_64-cpu" + }, + { + "name": "xen-pvdevice" + }, + { + "name": "pcnet" + }, + { + "name": "ivshmem" + }, + { + "name": "hpet" + }, + { + "name": "adlib" + }, + { + "name": "lsi53c895a" + }, + { + "name": "usb-audio" + }, + { + "name": "usb-wacom-tablet" + }, + { + "name": "pc-0.11-machine" + }, + { + "name": "kvm-apic" + }, + { + "name": "phenom-x86_64-cpu" + }, + { + "name": "ioh3420" + }, + { + "name": "cs4231a" + }, + { + "name": "dc390" + }, + { + "name": "nvme" + }, + { + "name": "i82801b11-bridge" + }, + { + "name": "kvmvapic" + }, + { + "name": "pc-q35-2.1-machine" + }, + { + "name": "fw-path-provider" + }, + { + "name": "usb-net" + }, + { + "name": "mch" + }, + { + "name": "usb-tablet" + }, + { + "name": "vhost-scsi" + }, + { + "name": "usb-ccid" + }, + { + "name": "pc-i440fx-1.7-machine" + }, + { + "name": "virtio-mmio-bus" + }, + { + "name": "usb-bot" + }, + { + "name": "ICH9-LPC" + }, + { + "name": "pci-bridge" + }, + { + "name": "pc-i440fx-1.6-machine" + }, + { + "name": "kvmclock" + }, + { + "name": "lsi53c810" + }, + { + "name": "isa-cirrus-vga" + }, + { + "name": "virtio-serial-bus" + }, + { + "name": "ICH9 SMB" + }, + { + "name": "SandyBridge-x86_64-cpu" + }, + { + "name": "esp" + }, + { + "name": "virtio-balloon-device" + }, + { + "name": "ccid-card-passthru" + }, + { + "name": "qxl" + }, + { + "name": "intel-hda" + }, + { + "name": "vmxnet3" + }, + { + "name": "virtio-serial-device" + }, + { + "name": "pci-testdev" + }, + { + "name": "ich9-usb-uhci6" + }, + { + "name": "ib700" + }, + { + "name": "ich9-usb-uhci4" + }, + { + "name": "piix3-ide-xen" + }, + { + "name": "ich9-usb-uhci5" + }, + { + "name": "icc-bus" + }, + { + "name": "IDE" + }, + { + "name": "VGA" + }, + { + "name": "ich9-usb-uhci3" + }, + { + "name": "ich9-usb-uhci2" + }, + { + "name": "ich9-usb-uhci1" + }, + { + "name": "x3130-upstream" + }, + { + "name": "none-machine" + }, + { + "name": "sysbus-fdc" + }, + { + "name": "SCSI" + }, + { + "name": "n270-x86_64-cpu" + }, + { + "name": "pci-serial" + }, + { + "name": "xenpv-machine" + }, + { + "name": "athlon-x86_64-cpu" + }, + { + "name": "ISA" + }, + { + "name": "i8042" + }, + { + "name": "ccid-card-emulated" + }, + { + "name": "i82559c" + }, + { + "name": "i82559b" + }, + { + "name": "i82559a" + }, + { + "name": "scsi-hd" + }, + { + "name": "pc-q35-1.5-machine" + }, + { + "name": "virtio-balloon-pci" + }, + { + "name": "hda-micro" + }, + { + "name": "scsi-block" + }, + { + "name": "virtio-scsi-pci" + }, + { + "name": "rtl8139" + }, + { + "name": "vmmouse" + }, + { + "name": "ich9-intel-hda" + }, + { + "name": "usb-mtp" + }, + { + "name": "ide-drive" + }, + { + "name": "PCI" + }, + { + "name": "Opteron_G5-x86_64-cpu" + }, + { + "name": "vmport" + }, + { + "name": "coreduo-x86_64-cpu" + }, + { + "name": "virtio-serial-pci" + }, + { + "name": "pc-q35-1.6-machine" + }, + { + "name": "xen-platform" + }, + { + "name": "pentium2-x86_64-cpu" + }, + { + "name": "i82558b" + }, + { + "name": "i82558a" + }, + { + "name": "pc-0.12-machine" + }, + { + "name": "kvm64-x86_64-cpu" + }, + { + "name": "port92" + }, + { + "name": "virtio-pci-bus" + }, + { + "name": "am53c974" + }, + { + "name": "e1000" + }, + { + "name": "Conroe-x86_64-cpu" + }, + { + "name": "ne2k_isa" + }, + { + "name": "HDA" + }, + { + "name": "usb-storage" + }, + { + "name": "pc-1.3-machine" + }, + { + "name": "usb-serial" + }, + { + "name": "sysbus-ohci" + }, + { + "name": "usb-redir" + }, + { + "name": "i82801" + }, + { + "name": "usb-uas" + }, + { + "name": "i82557b" + }, + { + "name": "i82557c" + }, + { + "name": "Nehalem-x86_64-cpu" + }, + { + "name": "memory-backend-ram" + }, + { + "name": "i82557a" + }, + { + "name": "virtserialport" + }, + { + "name": "i440FX" + }, + { + "name": "ne2k_pci" + }, + { + "name": "smbus-eeprom" + }, + { + "name": "i82562" + }, + { + "name": "ich9-ahci" + }, + { + "name": "isa-fdc" + }, + { + "name": "kvm32-x86_64-cpu" + }, + { + "name": "Opteron_G2-x86_64-cpu" + }, + { + "name": "virtio-rng-device" + }, + { + "name": "IndustryPack" + }, + { + "name": "vfio-pci" + }, + { + "name": "vt82c686b-usb-uhci" + }, + { + "name": "secondary-vga" + }, + { + "name": "pentium-x86_64-cpu" + }, + { + "name": "virtio-blk-device" + }, + { + "name": "fusbh200-ehci-usb" + } + ], + "id": "libvirt-8" +} + +{ + "return": [ + { + "name": "iothread", + "type": "link<iothread>" + }, + { + "name": "x-data-plane", + "type": "bool" + }, + { + "name": "scsi", + "type": "bool" + }, + { + "name": "config-wce", + "type": "bool" + }, + { + "name": "serial", + "type": "str" + }, + { + "name": "secs", + "type": "uint32" + }, + { + "name": "heads", + "type": "uint32" + }, + { + "name": "cyls", + "type": "uint32" + }, + { + "name": "discard_granularity", + "type": "uint32" + }, + { + "name": "bootindex", + "type": "int32" + }, + { + "name": "opt_io_size", + "type": "uint32" + }, + { + "name": "min_io_size", + "type": "uint16" + }, + { + "name": "physical_block_size", + "type": "uint16" + }, + { + "name": "logical_block_size", + "type": "uint16" + }, + { + "name": "drive", + "type": "str" + }, + { + "name": "virtio-backend", + "type": "child<virtio-blk-device>" + }, + { + "name": "command_serr_enable", + "type": "on/off" + }, + { + "name": "multifunction", + "type": "on/off" + }, + { + "name": "rombar", + "type": "uint32" + }, + { + "name": "romfile", + "type": "str" + }, + { + "name": "addr", + "type": "pci-devfn" + }, + { + "name": "event_idx", + "type": "on/off" + }, + { + "name": "indirect_desc", + "type": "on/off" + }, + { + "name": "vectors", + "type": "uint32" + }, + { + "name": "ioeventfd", + "type": "on/off" + }, + { + "name": "class", + "type": "uint32" + } + ], + "id": "libvirt-9" +} + +{ + "return": [ + { + "name": "virtio-backend", + "type": "child<virtio-net-device>" + }, + { + "name": "command_serr_enable", + "type": "on/off" + }, + { + "name": "multifunction", + "type": "on/off" + }, + { + "name": "rombar", + "type": "uint32" + }, + { + "name": "romfile", + "type": "str" + }, + { + "name": "addr", + "type": "pci-devfn" + }, + { + "name": "event_idx", + "type": "on/off" + }, + { + "name": "indirect_desc", + "type": "on/off" + }, + { + "name": "tx", + "type": "str" + }, + { + "name": "x-txburst", + "type": "int32" + }, + { + "name": "x-txtimer", + "type": "uint32" + }, + { + "name": "bootindex", + "type": "int32" + }, + { + "name": "netdev", + "type": "netdev" + }, + { + "name": "vlan", + "type": "vlan" + }, + { + "name": "mac", + "type": "macaddr" + }, + { + "name": "mq", + "type": "on/off" + }, + { + "name": "ctrl_guest_offloads", + "type": "on/off" + }, + { + "name": "ctrl_mac_addr", + "type": "on/off" + }, + { + "name": "ctrl_rx_extra", + "type": "on/off" + }, + { + "name": "ctrl_vlan", + "type": "on/off" + }, + { + "name": "ctrl_rx", + "type": "on/off" + }, + { + "name": "ctrl_vq", + "type": "on/off" + }, + { + "name": "status", + "type": "on/off" + }, + { + "name": "mrg_rxbuf", + "type": "on/off" + }, + { + "name": "host_ufo", + "type": "on/off" + }, + { + "name": "host_ecn", + "type": "on/off" + }, + { + "name": "host_tso6", + "type": "on/off" + }, + { + "name": "host_tso4", + "type": "on/off" + }, + { + "name": "guest_announce", + "type": "on/off" + }, + { + "name": "guest_ufo", + "type": "on/off" + }, + { + "name": "guest_ecn", + "type": "on/off" + }, + { + "name": "guest_tso6", + "type": "on/off" + }, + { + "name": "guest_tso4", + "type": "on/off" + }, + { + "name": "gso", + "type": "on/off" + }, + { + "name": "guest_csum", + "type": "on/off" + }, + { + "name": "csum", + "type": "on/off" + }, + { + "name": "any_layout", + "type": "on/off" + }, + { + "name": "vectors", + "type": "uint32" + }, + { + "name": "ioeventfd", + "type": "on/off" + } + ], + "id": "libvirt-10" +} + +{ + "id": "libvirt-11", + "error": { + "class": "DeviceNotFound", + "desc": "Device 'virtio-blk-ccw' not found" + } +} + +{ + "id": "libvirt-12", + "error": { + "class": "DeviceNotFound", + "desc": "Device 'virtio-net-ccw' not found" + } +} + +{ + "id": "libvirt-13", + "error": { + "class": "DeviceNotFound", + "desc": "Device 'virtio-blk-s390' not found" + } +} + +{ + "id": "libvirt-14", + "error": { + "class": "DeviceNotFound", + "desc": "Device 'virtio-net-s390' not found" + } +} + +{ + "id": "libvirt-15", + "error": { + "class": "DeviceNotFound", + "desc": "Device 'pci-assign' not found" + } +} + +{ + "return": [ + { + "name": "command_serr_enable", + "type": "on/off" + }, + { + "name": "multifunction", + "type": "on/off" + }, + { + "name": "rombar", + "type": "uint32" + }, + { + "name": "romfile", + "type": "str" + }, + { + "name": "addr", + "type": "pci-devfn" + }, + { + "name": "configfd", + "type": "str" + }, + { + "name": "bootindex", + "type": "int32" + }, + { + "name": "share_intx", + "type": "on/off" + }, + { + "name": "prefer_msi", + "type": "on/off" + }, + { + "name": "host", + "type": "pci-host-devaddr" + } + ], + "id": "libvirt-16" +} + +{ + "return": [ + { + "name": "command_serr_enable", + "type": "on/off" + }, + { + "name": "multifunction", + "type": "on/off" + }, + { + "name": "rombar", + "type": "uint32" + }, + { + "name": "romfile", + "type": "str" + }, + { + "name": "addr", + "type": "pci-devfn" + }, + { + "name": "bootindex", + "type": "int32" + }, + { + "name": "x-vga", + "type": "on/off" + }, + { + "name": "x-intx-mmap-timeout-ms", + "type": "uint32" + }, + { + "name": "host", + "type": "pci-host-devaddr" + } + ], + "id": "libvirt-17" +} + +{ + "return": [ + { + "name": "lun", + "type": "uint32" + }, + { + "name": "scsi-id", + "type": "uint32" + }, + { + "name": "channel", + "type": "uint32" + }, + { + "name": "max_unmap_size", + "type": "uint64" + }, + { + "name": "port_index", + "type": "uint16" + }, + { + "name": "port_wwn", + "type": "uint64" + }, + { + "name": "wwn", + "type": "uint64" + }, + { + "name": "dpofua", + "type": "on/off" + }, + { + "name": "removable", + "type": "on/off" + }, + { + "name": "product", + "type": "str" + }, + { + "name": "vendor", + "type": "str" + }, + { + "name": "serial", + "type": "str" + }, + { + "name": "ver", + "type": "str" + }, + { + "name": "discard_granularity", + "type": "uint32" + }, + { + "name": "bootindex", + "type": "int32" + }, + { + "name": "opt_io_size", + "type": "uint32" + }, + { + "name": "min_io_size", + "type": "uint16" + }, + { + "name": "physical_block_size", + "type": "blocksize" + }, + { + "name": "logical_block_size", + "type": "blocksize" + }, + { + "name": "drive", + "type": "drive" + } + ], + "id": "libvirt-18" +} + +{ + "return": [ + { + "name": "unit", + "type": "uint32" + }, + { + "name": "model", + "type": "str" + }, + { + "name": "serial", + "type": "str" + }, + { + "name": "wwn", + "type": "uint64" + }, + { + "name": "ver", + "type": "str" + }, + { + "name": "discard_granularity", + "type": "uint32" + }, + { + "name": "bootindex", + "type": "int32" + }, + { + "name": "opt_io_size", + "type": "uint32" + }, + { + "name": "min_io_size", + "type": "uint16" + }, + { + "name": "physical_block_size", + "type": "blocksize" + }, + { + "name": "logical_block_size", + "type": "blocksize" + }, + { + "name": "drive", + "type": "drive" + } + ], + "id": "libvirt-19" +} + +{ + "return": [ + { + "name": "command_serr_enable", + "type": "on/off" + }, + { + "name": "multifunction", + "type": "on/off" + }, + { + "name": "rombar", + "type": "uint32" + }, + { + "name": "romfile", + "type": "str" + }, + { + "name": "addr", + "type": "pci-devfn" + }, + { + "name": "memory-hotplug-support", + "type": "bool" + }, + { + "name": "acpi-pci-hotplug-with-bridge-support", + "type": "bool" + }, + { + "name": "s4_val", + "type": "uint8" + }, + { + "name": "disable_s4", + "type": "uint8" + }, + { + "name": "disable_s3", + "type": "uint8" + }, + { + "name": "smb_io_base", + "type": "uint32" + } + ], + "id": "libvirt-20" +} + +{ + "return": [ + { + "name": "msos-desc", + "type": "on/off" + }, + { + "name": "full-path", + "type": "on/off" + }, + { + "name": "serial", + "type": "str" + }, + { + "name": "port", + "type": "str" + }, + { + "name": "bootindex", + "type": "int32" + }, + { + "name": "filter", + "type": "str" + }, + { + "name": "debug", + "type": "uint8" + }, + { + "name": "chardev", + "type": "chr" + } + ], + "id": "libvirt-21" +} + +{ + "return": [ + { + "name": "msos-desc", + "type": "on/off" + }, + { + "name": "full-path", + "type": "on/off" + }, + { + "name": "serial", + "type": "str" + }, + { + "name": "port", + "type": "str" + }, + { + "name": "pipeline", + "type": "on/off" + }, + { + "name": "loglevel", + "type": "uint32" + }, + { + "name": "bootindex", + "type": "int32" + }, + { + "name": "isobsize", + "type": "uint32" + }, + { + "name": "isobufs", + "type": "uint32" + }, + { + "name": "productid", + "type": "uint32" + }, + { + "name": "vendorid", + "type": "uint32" + }, + { + "name": "hostport", + "type": "str" + }, + { + "name": "hostaddr", + "type": "uint32" + }, + { + "name": "hostbus", + "type": "uint32" + } + ], + "id": "libvirt-22" +} + +{ + "return": [ + { + "name": "lun", + "type": "uint32" + }, + { + "name": "scsi-id", + "type": "uint32" + }, + { + "name": "channel", + "type": "uint32" + }, + { + "name": "bootindex", + "type": "int32" + }, + { + "name": "drive", + "type": "drive" + } + ], + "id": "libvirt-23" +} + +{ + "return": [ + { + "name": "pci-hole64-end", + "type": "int" + }, + { + "name": "pci-hole64-start", + "type": "int" + }, + { + "name": "pci-hole-end", + "type": "int" + }, + { + "name": "pci-hole-start", + "type": "int" + }, + { + "name": "pci-conf-data[0]", + "type": "child<qemu:memory-region>" + }, + { + "name": "pci-conf-idx[0]", + "type": "child<qemu:memory-region>" + }, + { + "name": "short_root_bus", + "type": "uint32" + }, + { + "name": "pci-hole64-size", + "type": "size" + } + ], + "id": "libvirt-24" +} + +{ + "return": [ + { + "name": "mcfg_size", + "type": "int" + }, + { + "name": "pci-hole64-end", + "type": "int" + }, + { + "name": "pci-hole64-start", + "type": "int" + }, + { + "name": "pci-hole-end", + "type": "int" + }, + { + "name": "pci-hole-start", + "type": "int" + }, + { + "name": "mch", + "type": "child<mch>" + }, + { + "name": "pci-conf-data[0]", + "type": "child<qemu:memory-region>" + }, + { + "name": "pci-conf-idx[0]", + "type": "child<qemu:memory-region>" + }, + { + "name": "short_root_bus", + "type": "uint32" + }, + { + "name": "pci-hole64-size", + "type": "size" + }, + { + "name": "MCFG", + "type": "uint64" + } + ], + "id": "libvirt-25" +} + +{ + "return": [ + { + "name": "msos-desc", + "type": "on/off" + }, + { + "name": "full-path", + "type": "on/off" + }, + { + "name": "serial", + "type": "str" + }, + { + "name": "port", + "type": "str" + }, + { + "name": "removable", + "type": "on/off" + }, + { + "name": "discard_granularity", + "type": "uint32" + }, + { + "name": "bootindex", + "type": "int32" + }, + { + "name": "opt_io_size", + "type": "uint32" + }, + { + "name": "min_io_size", + "type": "uint16" + }, + { + "name": "physical_block_size", + "type": "blocksize" + }, + { + "name": "logical_block_size", + "type": "blocksize" + }, + { + "name": "drive", + "type": "drive" + } + ], + "id": "libvirt-26" +} + +{ + "return": [ + { + "name": "lost_tick_policy", + "type": "LostTickPolicy" + }, + { + "name": "iobase", + "type": "uint32" + } + ], + "id": "libvirt-27" +} + +{ + "return": [ + { + "name": "pc-1.3", + "cpu-max": 255 + }, + { + "name": "pc-0.12", + "cpu-max": 255 + }, + { + "name": "pc-q35-1.6", + "cpu-max": 255 + }, + { + "name": "pc-q35-1.5", + "cpu-max": 255 + }, + { + "name": "xenpv", + "cpu-max": 1 + }, + { + "name": "none", + "cpu-max": 1 + }, + { + "name": "pc-i440fx-1.6", + "cpu-max": 255 + }, + { + "name": "pc-i440fx-1.7", + "cpu-max": 255 + }, + { + "name": "pc-q35-2.1", + "cpu-max": 255, + "alias": "q35" + }, + { + "name": "pc-0.11", + "cpu-max": 255 + }, + { + "name": "pc-0.10", + "cpu-max": 255 + }, + { + "name": "pc-1.2", + "cpu-max": 255 + }, + { + "name": "isapc", + "cpu-max": 1 + }, + { + "name": "pc-q35-1.4", + "cpu-max": 255 + }, + { + "name": "xenfv", + "cpu-max": 128 + }, + { + "name": "pc-0.15", + "cpu-max": 255 + }, + { + "name": "pc-i440fx-1.5", + "cpu-max": 255 + }, + { + "name": "pc-i440fx-1.4", + "cpu-max": 255 + }, + { + "name": "pc-q35-2.0", + "cpu-max": 255 + }, + { + "name": "pc-0.14", + "cpu-max": 255 + }, + { + "name": "pc-1.1", + "cpu-max": 255 + }, + { + "name": "pc-q35-1.7", + "cpu-max": 255 + }, + { + "name": "pc-i440fx-2.1", + "is-default": true, + "cpu-max": 255, + "alias": "pc" + }, + { + "name": "pc-1.0", + "cpu-max": 255 + }, + { + "name": "pc-i440fx-2.0", + "cpu-max": 255 + }, + { + "name": "pc-0.13", + "cpu-max": 255 + } + ], + "id": "libvirt-28" +} + +{ + "return": [ + { + "name": "Opteron_G5" + }, + { + "name": "Opteron_G4" + }, + { + "name": "Opteron_G3" + }, + { + "name": "Opteron_G2" + }, + { + "name": "Opteron_G1" + }, + { + "name": "Broadwell" + }, + { + "name": "Haswell" + }, + { + "name": "SandyBridge" + }, + { + "name": "Westmere" + }, + { + "name": "Nehalem" + }, + { + "name": "Penryn" + }, + { + "name": "Conroe" + }, + { + "name": "n270" + }, + { + "name": "athlon" + }, + { + "name": "pentium3" + }, + { + "name": "pentium2" + }, + { + "name": "pentium" + }, + { + "name": "486" + }, + { + "name": "coreduo" + }, + { + "name": "kvm32" + }, + { + "name": "qemu32" + }, + { + "name": "kvm64" + }, + { + "name": "core2duo" + }, + { + "name": "phenom" + }, + { + "name": "qemu64" + } + ], + "id": "libvirt-29" +} + +{ + "return": { + "enabled": false, + "present": true + }, + "id": "libvirt-30" +} + +{ + "return": [ + "tpm-tis" + ], + "id": "libvirt-31" +} + +{ + "return": [ + "passthrough" + ], + "id": "libvirt-32" +} + +{ + "return": [ + { + "parameters": [ + { + "name": "initiator-name", + "help": "Initiator iqn name to use when connecting", + "type": "string" + }, + { + "name": "header-digest", + "help": "HeaderDigest setting. {CRC32C|CRC32C-NONE|NONE-CRC32C|NONE}", + "type": "string" + }, + { + "name": "password", + "help": "password for CHAP authentication to target", + "type": "string" + }, + { + "name": "user", + "help": "username for CHAP authentication to target", + "type": "string" + } + ], + "option": "iscsi" + }, + { + "parameters": [ + { + "name": "seamless-migration", + "type": "boolean" + }, + { + "name": "playback-compression", + "type": "boolean" + }, + { + "name": "agent-mouse", + "type": "boolean" + }, + { + "name": "streaming-video", + "type": "string" + }, + { + "name": "zlib-glz-wan-compression", + "type": "string" + }, + { + "name": "jpeg-wan-compression", + "type": "string" + }, + { + "name": "image-compression", + "type": "string" + }, + { + "name": "plaintext-channel", + "type": "string" + }, + { + "name": "tls-channel", + "type": "string" + }, + { + "name": "tls-ciphers", + "type": "string" + }, + { + "name": "x509-dh-key-file", + "type": "string" + }, + { + "name": "x509-cacert-file", + "type": "string" + }, + { + "name": "x509-cert-file", + "type": "string" + }, + { + "name": "x509-key-password", + "type": "string" + }, + { + "name": "x509-key-file", + "type": "string" + }, + { + "name": "x509-dir", + "type": "string" + }, + { + "name": "sasl", + "type": "boolean" + }, + { + "name": "disable-agent-file-xfer", + "type": "boolean" + }, + { + "name": "disable-copy-paste", + "type": "boolean" + }, + { + "name": "disable-ticketing", + "type": "boolean" + }, + { + "name": "password", + "type": "string" + }, + { + "name": "ipv6", + "type": "boolean" + }, + { + "name": "ipv4", + "type": "boolean" + }, + { + "name": "addr", + "type": "string" + }, + { + "name": "tls-port", + "type": "number" + }, + { + "name": "port", + "type": "number" + } + ], + "option": "spice" + }, + { + "parameters": [ + ], + "option": "acpi" + }, + { + "parameters": [ + { + "name": "sock_fd", + "type": "number" + }, + { + "name": "socket", + "type": "string" + }, + { + "name": "readonly", + "type": "boolean" + }, + { + "name": "writeout", + "type": "string" + }, + { + "name": "security_model", + "type": "string" + }, + { + "name": "mount_tag", + "type": "string" + }, + { + "name": "path", + "type": "string" + }, + { + "name": "fsdriver", + "type": "string" + } + ], + "option": "virtfs" + }, + { + "parameters": [ + { + "name": "sock_fd", + "type": "number" + }, + { + "name": "socket", + "type": "string" + }, + { + "name": "readonly", + "type": "boolean" + }, + { + "name": "writeout", + "type": "string" + }, + { + "name": "security_model", + "type": "string" + }, + { + "name": "path", + "type": "string" + }, + { + "name": "fsdriver", + "type": "string" + } + ], + "option": "fsdev" + }, + { + "parameters": [ + ], + "option": "smbios" + }, + { + "parameters": [ + ], + "option": "numa" + }, + { + "parameters": [ + { + "name": "debug-threads", + "help": "When enabled, name the individual threads; defaults off.\nNOTE: The thread names are for debugging and not a\nstable API.", + "type": "boolean" + }, + { + "name": "process", + "help": "Sets the name of the QEMU process, as shown in top etc", + "type": "string" + }, + { + "name": "guest", + "help": "Sets the name of the guest.\nThis name will be displayed in the SDL window caption.\nThe name will also be used for the VNC server", + "type": "string" + } + ], + "option": "name" + }, + { + "parameters": [ + { + "name": "timestamp", + "type": "boolean" + } + ], + "option": "msg" + }, + { + "parameters": [ + { + "name": "mlock", + "type": "boolean" + } + ], + "option": "realtime" + }, + { + "parameters": [ + ], + "option": "tpmdev" + }, + { + "parameters": [ + ], + "option": "object" + }, + { + "parameters": [ + { + "name": "opaque", + "help": "free-form string used to describe fd", + "type": "string" + }, + { + "name": "set", + "help": "ID of the fd set to add fd to", + "type": "number" + }, + { + "name": "fd", + "help": "file descriptor of which a duplicate is added to fd set", + "type": "number" + } + ], + "option": "add-fd" + }, + { + "parameters": [ + { + "name": "enable", + "type": "boolean" + } + ], + "option": "sandbox" + }, + { + "parameters": [ + { + "name": "strict", + "type": "boolean" + }, + { + "name": "reboot-timeout", + "type": "string" + }, + { + "name": "splash-time", + "type": "string" + }, + { + "name": "splash", + "type": "string" + }, + { + "name": "menu", + "type": "boolean" + }, + { + "name": "once", + "type": "string" + }, + { + "name": "order", + "type": "string" + } + ], + "option": "boot-opts" + }, + { + "parameters": [ + { + "name": "maxcpus", + "type": "number" + }, + { + "name": "threads", + "type": "number" + }, + { + "name": "cores", + "type": "number" + }, + { + "name": "sockets", + "type": "number" + }, + { + "name": "cpus", + "type": "number" + } + ], + "option": "smp-opts" + }, + { + "parameters": [ + { + "name": "maxmem", + "type": "size" + }, + { + "name": "slots", + "type": "number" + }, + { + "name": "size", + "type": "size" + } + ], + "option": "memory" + }, + { + "parameters": [ + { + "name": "max-ram-below-4g", + "help": "maximum ram below the 4G boundary (32bit boundary)", + "type": "size" + }, + { + "name": "kvm-type", + "help": "Specifies the KVM virtualization mode (HV, PR)", + "type": "string" + }, + { + "name": "firmware", + "help": "firmware image", + "type": "string" + }, + { + "name": "usb", + "help": "Set on/off to enable/disable usb", + "type": "boolean" + }, + { + "name": "mem-merge", + "help": "enable/disable memory merge support", + "type": "boolean" + }, + { + "name": "dump-guest-core", + "help": "Include guest memory in a core dump", + "type": "boolean" + }, + { + "name": "dt_compatible", + "help": "Overrides the \"compatible\" property of the dt root node", + "type": "string" + }, + { + "name": "phandle_start", + "help": "The first phandle ID we may generate dynamically", + "type": "number" + }, + { + "name": "dumpdtb", + "help": "Dump current dtb to a file and quit", + "type": "string" + }, + { + "name": "dtb", + "help": "Linux kernel device tree file", + "type": "string" + }, + { + "name": "append", + "help": "Linux kernel command line", + "type": "string" + }, + { + "name": "initrd", + "help": "Linux initial ramdisk file", + "type": "string" + }, + { + "name": "kernel", + "help": "Linux kernel image file", + "type": "string" + }, + { + "name": "kvm_shadow_mem", + "help": "KVM shadow MMU size", + "type": "size" + }, + { + "name": "kernel_irqchip", + "help": "use KVM in-kernel irqchip", + "type": "boolean" + }, + { + "name": "accel", + "help": "accelerator list", + "type": "string" + }, + { + "name": "type", + "help": "emulated machine", + "type": "string" + } + ], + "option": "machine" + }, + { + "parameters": [ + { + "name": "romfile", + "type": "string" + }, + { + "name": "bootindex", + "type": "number" + } + ], + "option": "option-rom" + }, + { + "parameters": [ + { + "name": "file", + "type": "string" + }, + { + "name": "events", + "type": "string" + } + ], + "option": "trace" + }, + { + "parameters": [ + { + "name": "pretty", + "type": "boolean" + }, + { + "name": "default", + "type": "boolean" + }, + { + "name": "chardev", + "type": "string" + }, + { + "name": "mode", + "type": "string" + } + ], + "option": "mon" + }, + { + "parameters": [ + { + "name": "value", + "type": "string" + }, + { + "name": "property", + "type": "string" + }, + { + "name": "driver", + "type": "string" + } + ], + "option": "global" + }, + { + "parameters": [ + { + "name": "driftfix", + "type": "string" + }, + { + "name": "clock", + "type": "string" + }, + { + "name": "base", + "type": "string" + } + ], + "option": "rtc" + }, + { + "parameters": [ + ], + "option": "net" + }, + { + "parameters": [ + ], + "option": "netdev" + }, + { + "parameters": [ + ], + "option": "device" + }, + { + "parameters": [ + { + "name": "chardev", + "type": "string" + }, + { + "name": "size", + "type": "size" + }, + { + "name": "debug", + "type": "number" + }, + { + "name": "name", + "type": "string" + }, + { + "name": "signal", + "type": "boolean" + }, + { + "name": "mux", + "type": "boolean" + }, + { + "name": "rows", + "type": "number" + }, + { + "name": "cols", + "type": "number" + }, + { + "name": "height", + "type": "number" + }, + { + "name": "width", + "type": "number" + }, + { + "name": "telnet", + "type": "boolean" + }, + { + "name": "delay", + "type": "boolean" + }, + { + "name": "server", + "type": "boolean" + }, + { + "name": "wait", + "type": "boolean" + }, + { + "name": "ipv6", + "type": "boolean" + }, + { + "name": "ipv4", + "type": "boolean" + }, + { + "name": "to", + "type": "number" + }, + { + "name": "localport", + "type": "string" + }, + { + "name": "localaddr", + "type": "string" + }, + { + "name": "port", + "type": "string" + }, + { + "name": "host", + "type": "string" + }, + { + "name": "path", + "type": "string" + }, + { + "name": "backend", + "type": "string" + } + ], + "option": "chardev" + }, + { + "parameters": [ + { + "name": "copy-on-read", + "help": "copy read data from backing file into image file", + "type": "boolean" + }, + { + "name": "werror", + "help": "write error action", + "type": "string" + }, + { + "name": "rerror", + "help": "read error action", + "type": "string" + }, + { + "name": "read-only", + "help": "open drive file as read-only", + "type": "boolean" + }, + { + "name": "file", + "help": "file name", + "type": "string" + }, + { + "name": "serial", + "help": "disk serial number", + "type": "string" + }, + { + "name": "addr", + "help": "pci address (virtio only)", + "type": "string" + }, + { + "name": "boot", + "help": "(deprecated, ignored)", + "type": "boolean" + }, + { + "name": "trans", + "help": "chs translation (auto, lba, none)", + "type": "string" + }, + { + "name": "secs", + "help": "number of sectors (ide disk geometry)", + "type": "number" + }, + { + "name": "heads", + "help": "number of heads (ide disk geometry)", + "type": "number" + }, + { + "name": "cyls", + "help": "number of cylinders (ide disk geometry)", + "type": "number" + }, + { + "name": "if", + "help": "interface (ide, scsi, sd, mtd, floppy, pflash, virtio)", + "type": "string" + }, + { + "name": "media", + "help": "media type (disk, cdrom)", + "type": "string" + }, + { + "name": "index", + "help": "index number", + "type": "number" + }, + { + "name": "unit", + "help": "unit number (i.e. lun for scsi)", + "type": "number" + }, + { + "name": "bus", + "help": "bus number", + "type": "number" + }, + { + "name": "detect-zeroes", + "help": "try to optimize zero writes (off, on, unmap)", + "type": "string" + }, + { + "name": "throttling.iops-size", + "help": "when limiting by iops max size of an I/O in bytes", + "type": "number" + }, + { + "name": "throttling.bps-write-max", + "help": "total bytes write burst", + "type": "number" + }, + { + "name": "throttling.bps-read-max", + "help": "total bytes read burst", + "type": "number" + }, + { + "name": "throttling.bps-total-max", + "help": "total bytes burst", + "type": "number" + }, + { + "name": "throttling.iops-write-max", + "help": "I/O operations write burst", + "type": "number" + }, + { + "name": "throttling.iops-read-max", + "help": "I/O operations read burst", + "type": "number" + }, + { + "name": "throttling.iops-total-max", + "help": "I/O operations burst", + "type": "number" + }, + { + "name": "throttling.bps-write", + "help": "limit write bytes per second", + "type": "number" + }, + { + "name": "throttling.bps-read", + "help": "limit read bytes per second", + "type": "number" + }, + { + "name": "throttling.bps-total", + "help": "limit total bytes per second", + "type": "number" + }, + { + "name": "throttling.iops-write", + "help": "limit write operations per second", + "type": "number" + }, + { + "name": "throttling.iops-read", + "help": "limit read operations per second", + "type": "number" + }, + { + "name": "throttling.iops-total", + "help": "limit total I/O operations per second", + "type": "number" + }, + { + "name": "werror", + "help": "write error action", + "type": "string" + }, + { + "name": "format", + "help": "disk format (raw, qcow2, ...)", + "type": "string" + }, + { + "name": "aio", + "help": "host AIO implementation (threads, native)", + "type": "string" + }, + { + "name": "cache.no-flush", + "help": "ignore any flush requests for the device", + "type": "boolean" + }, + { + "name": "cache.direct", + "help": "enables use of O_DIRECT (bypass the host page cache)", + "type": "boolean" + }, + { + "name": "cache.writeback", + "help": "enables writeback mode for any caches", + "type": "boolean" + }, + { + "name": "discard", + "help": "discard operation (ignore/off, unmap/on)", + "type": "string" + }, + { + "name": "snapshot", + "help": "enable/disable snapshot mode", + "type": "boolean" + } + ], + "option": "drive" + } + ], + "id": "libvirt-33" +} + +{ + "return": [ + { + "state": false, + "capability": "xbzrle" + }, + { + "state": false, + "capability": "rdma-pin-all" + }, + { + "state": false, + "capability": "auto-converge" + }, + { + "state": false, + "capability": "zero-blocks" + } + ], + "id": "libvirt-34" +} diff --git a/tests/qemucapabilitiestest.c b/tests/qemucapabilitiestest.c index 4e5f9e5..a5cb584 100644 --- a/tests/qemucapabilitiestest.c +++ b/tests/qemucapabilitiestest.c @@ -197,6 +197,7 @@ mymain(void) DO_TEST("caps_1.5.3-1"); DO_TEST_FULL("caps_1.6.0-1", true); DO_TEST("caps_1.6.50-1"); + DO_TEST("caps_2.1.1-1"); virObjectUnref(xmlopt); return (ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE; -- 2.1.0

From: "Michael R. Hines" <mrhines@us.ibm.com> This patch adds support for RDMA protocol in migration URIs. USAGE: $ virsh migrate --live --migrateuri rdma://hostname domain qemu+ssh://hostname/system Since libvirt runs QEMU in a pretty restricted environment, several files needs to be added to cgroup_device_acl (in qemu.conf) for QEMU to be able to access the host's infiniband hardware. Full documenation of the feature can be found on QEMU wiki: http://wiki.qemu.org/Features/RDMALiveMigration Signed-off-by: Michael R. Hines <mrhines@us.ibm.com> Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- Notes: The question is whether the IB devices should be added to cgroup_device_acl by default or not... Version 3: - moved capabilities code into a separate patch - got rid of migration URI hacks - removed hacks that disabled IPv6 with RDMA - moved refactoring into a dedicated patch - documented IB devices which need to be added to cgroup acl in qemu.conf - forbid RDMA migrations unless memory hard limit is set until we have a better plan for setting limits for mlock - set QEMU's RLIMIT_MEMLOCK to memory hard_limit before starting RDMA migration - check if RDMA migration is supported by source QEMU before trying to migrate src/qemu/qemu.conf | 8 ++++++++ src/qemu/qemu_command.c | 8 ++++++++ src/qemu/qemu_migration.c | 39 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf index 79bba36..92ca715 100644 --- a/src/qemu/qemu.conf +++ b/src/qemu/qemu.conf @@ -274,6 +274,14 @@ # "/dev/ptmx", "/dev/kvm", "/dev/kqemu", # "/dev/rtc","/dev/hpet", "/dev/vfio/vfio" #] +# +# RDMA migration requires the following extra files to be added to the list: +# "/dev/infiniband/rdma_cm", +# "/dev/infiniband/issm0", +# "/dev/infiniband/issm1", +# "/dev/infiniband/umad0", +# "/dev/infiniband/umad1", +# "/dev/infiniband/uverbs0" # The default format for Qemu/KVM guest save images is raw; that is, the diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index a892d99..fceed62 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -9399,6 +9399,14 @@ qemuBuildCommandLine(virConnectPtr conn, goto error; } virCommandAddArg(cmd, migrateFrom); + } else if (STRPREFIX(migrateFrom, "rdma")) { + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_RDMA)) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("incoming RDMA migration is not supported " + "with this QEMU binary")); + goto error; + } + virCommandAddArg(cmd, migrateFrom); } else if (STREQ(migrateFrom, "stdio")) { if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD)) { virCommandAddArgFormat(cmd, "fd:%d", migrateFd); diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index d0e2653..b59e94d 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -56,6 +56,7 @@ #include "virhook.h" #include "virstring.h" #include "virtypedparam.h" +#include "virprocess.h" #define VIR_FROM_THIS VIR_FROM_QEMU @@ -2653,6 +2654,13 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver, QEMU_MIGRATION_COOKIE_NBD))) goto cleanup; + if (STREQ(protocol, "rdma") && !vm->def->mem.hard_limit) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("cannot start RDMA migration with no memory hard " + "limit set")); + goto cleanup; + } + if (qemuMigrationJobStart(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN) < 0) goto cleanup; qemuMigrationJobSetPhase(driver, vm, QEMU_MIGRATION_PHASE_PREPARE); @@ -2696,6 +2704,11 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver, QEMU_ASYNC_JOB_MIGRATION_IN) < 0) goto stop; + if (STREQ(protocol, "rdma") && + virProcessSetMaxMemLock(vm->pid, vm->def->mem.hard_limit << 10) < 0) { + goto stop; + } + if (mig->lockState) { VIR_DEBUG("Received lockstate %s", mig->lockState); VIR_FREE(priv->lockState); @@ -2926,7 +2939,8 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver, if (!(uri = qemuMigrationParseURI(uri_in, &well_formed_uri))) goto cleanup; - if (STRNEQ(uri->scheme, "tcp")) { + if (STRNEQ(uri->scheme, "tcp") && + STRNEQ(uri->scheme, "rdma")) { virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, _("unsupported scheme %s in migration URI %s"), uri->scheme, uri_in); @@ -3545,6 +3559,11 @@ qemuMigrationRun(virQEMUDriverPtr driver, switch (spec->destType) { case MIGRATION_DEST_HOST: + if (STREQ(spec->dest.host.protocol, "rdma") && + virProcessSetMaxMemLock(vm->pid, vm->def->mem.hard_limit << 10) < 0) { + qemuDomainObjExitMonitor(driver, vm); + goto cleanup; + } ret = qemuMonitorMigrateToHost(priv->mon, migrate_flags, spec->dest.host.protocol, spec->dest.host.name, @@ -3717,7 +3736,23 @@ static int doNativeMigrate(virQEMUDriverPtr driver, if (!(uribits = qemuMigrationParseURI(uri, NULL))) return -1; - if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD)) + if (STREQ(uribits->scheme, "rdma")) { + if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_RDMA)) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("outgoing RDMA migration is not supported " + "with this QEMU binary")); + return -1; + } + if (!vm->def->mem.hard_limit) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("cannot start RDMA migration with no memory hard " + "limit set")); + return -1; + } + } + + if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD) && + STRNEQ(uribits->scheme, "rdma")) spec.destType = MIGRATION_DEST_CONNECT_HOST; else spec.destType = MIGRATION_DEST_HOST; -- 2.1.0

On 09/17/2014 10:53 AM, Jiri Denemark wrote:
From: "Michael R. Hines" <mrhines@us.ibm.com>
This patch adds support for RDMA protocol in migration URIs.
USAGE: $ virsh migrate --live --migrateuri rdma://hostname domain qemu+ssh://hostname/system
Since libvirt runs QEMU in a pretty restricted environment, several files needs to be added to cgroup_device_acl (in qemu.conf) for QEMU to be able to access the host's infiniband hardware. Full documenation of the feature can be found on QEMU wiki: http://wiki.qemu.org/Features/RDMALiveMigration
Signed-off-by: Michael R. Hines <mrhines@us.ibm.com> Signed-off-by: Jiri Denemark <jdenemar@redhat.com> ---
Notes: The question is whether the IB devices should be added to cgroup_device_acl by default or not...
Version 3: - moved capabilities code into a separate patch - got rid of migration URI hacks - removed hacks that disabled IPv6 with RDMA - moved refactoring into a dedicated patch - documented IB devices which need to be added to cgroup acl in qemu.conf - forbid RDMA migrations unless memory hard limit is set until we have a better plan for setting limits for mlock - set QEMU's RLIMIT_MEMLOCK to memory hard_limit before starting RDMA migration - check if RDMA migration is supported by source QEMU before trying to migrate
src/qemu/qemu.conf | 8 ++++++++ src/qemu/qemu_command.c | 8 ++++++++ src/qemu/qemu_migration.c | 39 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 53 insertions(+), 2 deletions(-)
My morning Coverity run found a memory leak...
diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf index 79bba36..92ca715 100644 --- a/src/qemu/qemu.conf +++ b/src/qemu/qemu.conf @@ -274,6 +274,14 @@ # "/dev/ptmx", "/dev/kvm", "/dev/kqemu", # "/dev/rtc","/dev/hpet", "/dev/vfio/vfio" #] +# +# RDMA migration requires the following extra files to be added to the list: +# "/dev/infiniband/rdma_cm", +# "/dev/infiniband/issm0", +# "/dev/infiniband/issm1", +# "/dev/infiniband/umad0", +# "/dev/infiniband/umad1", +# "/dev/infiniband/uverbs0"
# The default format for Qemu/KVM guest save images is raw; that is, the diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index a892d99..fceed62 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -9399,6 +9399,14 @@ qemuBuildCommandLine(virConnectPtr conn, goto error; } virCommandAddArg(cmd, migrateFrom); + } else if (STRPREFIX(migrateFrom, "rdma")) { + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_RDMA)) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("incoming RDMA migration is not supported " + "with this QEMU binary")); + goto error; + } + virCommandAddArg(cmd, migrateFrom); } else if (STREQ(migrateFrom, "stdio")) { if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD)) { virCommandAddArgFormat(cmd, "fd:%d", migrateFd); diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index d0e2653..b59e94d 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -56,6 +56,7 @@ #include "virhook.h" #include "virstring.h" #include "virtypedparam.h" +#include "virprocess.h"
#define VIR_FROM_THIS VIR_FROM_QEMU
@@ -2653,6 +2654,13 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver, QEMU_MIGRATION_COOKIE_NBD))) goto cleanup;
+ if (STREQ(protocol, "rdma") && !vm->def->mem.hard_limit) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("cannot start RDMA migration with no memory hard " + "limit set")); + goto cleanup; + } + if (qemuMigrationJobStart(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN) < 0) goto cleanup; qemuMigrationJobSetPhase(driver, vm, QEMU_MIGRATION_PHASE_PREPARE); @@ -2696,6 +2704,11 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver, QEMU_ASYNC_JOB_MIGRATION_IN) < 0) goto stop;
+ if (STREQ(protocol, "rdma") && + virProcessSetMaxMemLock(vm->pid, vm->def->mem.hard_limit << 10) < 0) { + goto stop; + } + if (mig->lockState) { VIR_DEBUG("Received lockstate %s", mig->lockState); VIR_FREE(priv->lockState); @@ -2926,7 +2939,8 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver, if (!(uri = qemuMigrationParseURI(uri_in, &well_formed_uri))) goto cleanup;
- if (STRNEQ(uri->scheme, "tcp")) { + if (STRNEQ(uri->scheme, "tcp") && + STRNEQ(uri->scheme, "rdma")) { virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, _("unsupported scheme %s in migration URI %s"), uri->scheme, uri_in); @@ -3545,6 +3559,11 @@ qemuMigrationRun(virQEMUDriverPtr driver,
switch (spec->destType) { case MIGRATION_DEST_HOST: + if (STREQ(spec->dest.host.protocol, "rdma") && + virProcessSetMaxMemLock(vm->pid, vm->def->mem.hard_limit << 10) < 0) { + qemuDomainObjExitMonitor(driver, vm); + goto cleanup; + } ret = qemuMonitorMigrateToHost(priv->mon, migrate_flags, spec->dest.host.protocol, spec->dest.host.name, @@ -3717,7 +3736,23 @@ static int doNativeMigrate(virQEMUDriverPtr driver, if (!(uribits = qemuMigrationParseURI(uri, NULL))) return -1;
- if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD)) + if (STREQ(uribits->scheme, "rdma")) { + if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_RDMA)) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("outgoing RDMA migration is not supported " + "with this QEMU binary"));
Need to virURIFree(uribits); or add a cleanup label below and jump there
+ return -1; + } + if (!vm->def->mem.hard_limit) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("cannot start RDMA migration with no memory hard " + "limit set")); + return -1;
Same here
+ } + } + + if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD) && + STRNEQ(uribits->scheme, "rdma")) spec.destType = MIGRATION_DEST_CONNECT_HOST; else spec.destType = MIGRATION_DEST_HOST;

From: "Michael R. Hines" <mrhines@us.ibm.com> RDMA Live migration requires registering memory with the hardware, and thus QEMU offers a new 'capability' to pre-register / mlock() the guest memory in advance for higher RDMA performance before the migration begins. This capability is disabled by default, which means QEMU will register the memory with the hardware in an on-demand basis. This patch exposes this capability with the following example usage: virsh migrate --live --rdma-pin-all --migrateuri rdma://hostname domain qemu+ssh://hostname/system Signed-off-by: Michael R. Hines <mrhines@us.ibm.com> Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- Notes: Version 3: - moved rdma-pin-all capability into "qemu: Add RDMA migration capabilities" patch - removed magic computation of mlock memory limit include/libvirt/libvirt.h.in | 1 + src/qemu/qemu_migration.c | 49 ++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_migration.h | 3 ++- tools/virsh-domain.c | 7 +++++++ 4 files changed, 59 insertions(+), 1 deletion(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 702f797..a028e2d 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -1224,6 +1224,7 @@ typedef enum { VIR_MIGRATE_COMPRESSED = (1 << 11), /* compress data during migration */ VIR_MIGRATE_ABORT_ON_ERROR = (1 << 12), /* abort migration on I/O errors happened during migration */ VIR_MIGRATE_AUTO_CONVERGE = (1 << 13), /* force convergence */ + VIR_MIGRATE_RDMA_PIN_ALL = (1 << 14), /* RDMA memory pinning */ } virDomainMigrateFlags; diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index b59e94d..2daac48 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -1874,6 +1874,46 @@ qemuMigrationSetAutoConverge(virQEMUDriverPtr driver, static int +qemuMigrationSetPinAll(virQEMUDriverPtr driver, + virDomainObjPtr vm, + qemuDomainAsyncJob job) +{ + qemuDomainObjPrivatePtr priv = vm->privateData; + int ret; + + if (qemuDomainObjEnterMonitorAsync(driver, vm, job) < 0) + return -1; + + ret = qemuMonitorGetMigrationCapability( + priv->mon, + QEMU_MONITOR_MIGRATION_CAPS_RDMA_PIN_ALL); + + if (ret < 0) { + goto cleanup; + } else if (ret == 0) { + if (job == QEMU_ASYNC_JOB_MIGRATION_IN) { + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", + _("rdma pinning migration is not supported by " + "target QEMU binary")); + } else { + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", + _("rdma pinning migration is not supported by " + "source QEMU binary")); + } + ret = -1; + goto cleanup; + } + + ret = qemuMonitorSetMigrationCapability( + priv->mon, + QEMU_MONITOR_MIGRATION_CAPS_RDMA_PIN_ALL); + + cleanup: + qemuDomainObjExitMonitor(driver, vm); + return ret; +} + +static int qemuMigrationWaitForSpice(virQEMUDriverPtr driver, virDomainObjPtr vm) { @@ -2709,6 +2749,10 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver, goto stop; } + if (flags & VIR_MIGRATE_RDMA_PIN_ALL && + qemuMigrationSetPinAll(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN) < 0) + goto stop; + if (mig->lockState) { VIR_DEBUG("Received lockstate %s", mig->lockState); VIR_FREE(priv->lockState); @@ -3530,6 +3574,11 @@ qemuMigrationRun(virQEMUDriverPtr driver, QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) goto cleanup; + if (flags & VIR_MIGRATE_RDMA_PIN_ALL && + qemuMigrationSetPinAll(driver, vm, + QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) + goto cleanup; + if (qemuDomainObjEnterMonitorAsync(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) goto cleanup; diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h index 3fa68dc..e7a90c3 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -40,7 +40,8 @@ VIR_MIGRATE_OFFLINE | \ VIR_MIGRATE_COMPRESSED | \ VIR_MIGRATE_ABORT_ON_ERROR | \ - VIR_MIGRATE_AUTO_CONVERGE) + VIR_MIGRATE_AUTO_CONVERGE | \ + VIR_MIGRATE_RDMA_PIN_ALL) /* All supported migration parameters and their types. */ # define QEMU_MIGRATION_PARAMETERS \ diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 105b99e..a6ced5f 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -9212,6 +9212,10 @@ static const vshCmdOptDef opts_migrate[] = { .type = VSH_OT_BOOL, .help = N_("force convergence during live migration") }, + {.name = "rdma-pin-all", + .type = VSH_OT_BOOL, + .help = N_("support memory pinning during RDMA live migration") + }, {.name = "abort-on-error", .type = VSH_OT_BOOL, .help = N_("abort on soft errors during migration") @@ -9360,6 +9364,9 @@ doMigrate(void *opaque) if (vshCommandOptBool(cmd, "auto-converge")) flags |= VIR_MIGRATE_AUTO_CONVERGE; + if (vshCommandOptBool(cmd, "rdma-pin-all")) + flags |= VIR_MIGRATE_RDMA_PIN_ALL; + if (vshCommandOptBool(cmd, "offline")) { flags |= VIR_MIGRATE_OFFLINE; } -- 2.1.0

On Wed, Sep 17, 2014 at 16:53:02 +0200, Jiri Denemark wrote:
This is a modified version of RDMA migration patches sent back in January by Michael R. Hines. See individual patches for (numerous) changes since v2.
Jiri Denemark (3): qemu: Fix old tcp:host URIs more cleanly qemu: Prepare support for arbitrary migration protocol qemu: Add RDMA migration capabilities
Michael R. Hines (3): qemu: Expose additional migration statistics qemu: RDMA migration support qemu: Memory pre-pinning support for RDMA migration
And this whole series should have been obviously marked as v3... Jirka

On 09/17/2014 04:53 PM, Jiri Denemark wrote:
This is a modified version of RDMA migration patches sent back in January by Michael R. Hines. See individual patches for (numerous) changes since v2.
Jiri Denemark (3): qemu: Fix old tcp:host URIs more cleanly qemu: Prepare support for arbitrary migration protocol qemu: Add RDMA migration capabilities
Michael R. Hines (3): qemu: Expose additional migration statistics qemu: RDMA migration support qemu: Memory pre-pinning support for RDMA migration
include/libvirt/libvirt.h.in | 26 + src/qemu/qemu.conf | 8 + src/qemu/qemu_capabilities.c | 32 +- src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 8 + src/qemu/qemu_domain.c | 18 + src/qemu/qemu_migration.c | 216 +- src/qemu/qemu_migration.h | 3 +- src/qemu/qemu_monitor.c | 25 +- src/qemu/qemu_monitor.h | 13 + src/qemu/qemu_monitor_json.c | 61 +- src/qemu/qemu_monitor_json.h | 2 + tests/qemucapabilitiesdata/caps_1.2.2-1.replies | 10 + tests/qemucapabilitiesdata/caps_1.3.1-1.replies | 10 + tests/qemucapabilitiesdata/caps_1.4.2-1.replies | 10 + tests/qemucapabilitiesdata/caps_1.5.3-1.replies | 10 + tests/qemucapabilitiesdata/caps_1.6.0-1.replies | 22 + tests/qemucapabilitiesdata/caps_1.6.50-1.replies | 22 + tests/qemucapabilitiesdata/caps_2.1.1-1.caps | 162 ++ tests/qemucapabilitiesdata/caps_2.1.1-1.replies | 3264 ++++++++++++++++++++++ tests/qemucapabilitiestest.c | 1 + tools/virsh-domain.c | 34 + 22 files changed, 3886 insertions(+), 72 deletions(-) create mode 100644 tests/qemucapabilitiesdata/caps_2.1.1-1.caps create mode 100644 tests/qemucapabilitiesdata/caps_2.1.1-1.replies
ACK series. Jan

On Mon, Sep 22, 2014 at 18:34:46 +0200, Jano Tomko wrote:
On 09/17/2014 04:53 PM, Jiri Denemark wrote:
This is a modified version of RDMA migration patches sent back in January by Michael R. Hines. See individual patches for (numerous) changes since v2.
Jiri Denemark (3): qemu: Fix old tcp:host URIs more cleanly qemu: Prepare support for arbitrary migration protocol qemu: Add RDMA migration capabilities
Michael R. Hines (3): qemu: Expose additional migration statistics qemu: RDMA migration support qemu: Memory pre-pinning support for RDMA migration
include/libvirt/libvirt.h.in | 26 + src/qemu/qemu.conf | 8 + src/qemu/qemu_capabilities.c | 32 +- src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 8 + src/qemu/qemu_domain.c | 18 + src/qemu/qemu_migration.c | 216 +- src/qemu/qemu_migration.h | 3 +- src/qemu/qemu_monitor.c | 25 +- src/qemu/qemu_monitor.h | 13 + src/qemu/qemu_monitor_json.c | 61 +- src/qemu/qemu_monitor_json.h | 2 + tests/qemucapabilitiesdata/caps_1.2.2-1.replies | 10 + tests/qemucapabilitiesdata/caps_1.3.1-1.replies | 10 + tests/qemucapabilitiesdata/caps_1.4.2-1.replies | 10 + tests/qemucapabilitiesdata/caps_1.5.3-1.replies | 10 + tests/qemucapabilitiesdata/caps_1.6.0-1.replies | 22 + tests/qemucapabilitiesdata/caps_1.6.50-1.replies | 22 + tests/qemucapabilitiesdata/caps_2.1.1-1.caps | 162 ++ tests/qemucapabilitiesdata/caps_2.1.1-1.replies | 3264 ++++++++++++++++++++++ tests/qemucapabilitiestest.c | 1 + tools/virsh-domain.c | 34 + 22 files changed, 3886 insertions(+), 72 deletions(-) create mode 100644 tests/qemucapabilitiesdata/caps_2.1.1-1.caps create mode 100644 tests/qemucapabilitiesdata/caps_2.1.1-1.replies
ACK series.
Pushed, thanks. Jirka
participants (3)
-
Jiri Denemark
-
John Ferlan
-
Ján Tomko