qemu: Add RDMA migration capabilities

This commit is contained in:
Jiri Denemark 2014-09-11 14:11:54 +02:00
parent e16a39fcd3
commit b3fd95e368
15 changed files with 3602 additions and 13 deletions

View File

@ -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:

View File

@ -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;

View File

@ -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,
@ -3788,6 +3788,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.
*/

View File

@ -481,12 +481,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,

View File

@ -5214,14 +5214,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)))
@ -5240,14 +5244,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;
@ -5263,21 +5270,40 @@ 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;
}
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)

View File

@ -137,6 +137,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,

View File

@ -1555,3 +1555,13 @@
"desc": "The command query-command-line-options has not been found"
}
}
{
"return": [
{
"capability": "xbzrle",
"state": false
}
],
"id": "libvirt-32"
}

View File

@ -1735,3 +1735,13 @@
"desc": "The command query-command-line-options has not been found"
}
}
{
"return": [
{
"capability": "xbzrle",
"state": false
}
],
"id": "libvirt-34"
}

View File

@ -1785,3 +1785,13 @@
"desc": "The command query-command-line-options has not been found"
}
}
{
"return": [
{
"capability": "xbzrle",
"state": false
}
],
"id": "libvirt-34"
}

View File

@ -2539,3 +2539,13 @@
],
"id": "libvirt-33"
}
{
"return": [
{
"capability": "xbzrle",
"state": false
}
],
"id": "libvirt-34"
}

View File

@ -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"
}

View File

@ -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"
}

View File

@ -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>

File diff suppressed because it is too large Load Diff

View File

@ -189,6 +189,7 @@ mymain(void)
DO_TEST("caps_1.5.3-1");
DO_TEST("caps_1.6.0-1");
DO_TEST("caps_1.6.50-1");
DO_TEST("caps_2.1.1-1");
virObjectUnref(xmlopt);
return (ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE;