mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-20 07:59:00 +00:00
qemu: RDMA migration support
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>
This commit is contained in:
parent
b3fd95e368
commit
ed22a47434
@ -274,6 +274,14 @@
|
|||||||
# "/dev/ptmx", "/dev/kvm", "/dev/kqemu",
|
# "/dev/ptmx", "/dev/kvm", "/dev/kqemu",
|
||||||
# "/dev/rtc","/dev/hpet", "/dev/vfio/vfio"
|
# "/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
|
# The default format for Qemu/KVM guest save images is raw; that is, the
|
||||||
|
@ -9476,6 +9476,14 @@ qemuBuildCommandLine(virConnectPtr conn,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
virCommandAddArg(cmd, migrateFrom);
|
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")) {
|
} else if (STREQ(migrateFrom, "stdio")) {
|
||||||
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD)) {
|
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD)) {
|
||||||
virCommandAddArgFormat(cmd, "fd:%d", migrateFd);
|
virCommandAddArgFormat(cmd, "fd:%d", migrateFd);
|
||||||
|
@ -56,6 +56,7 @@
|
|||||||
#include "virhook.h"
|
#include "virhook.h"
|
||||||
#include "virstring.h"
|
#include "virstring.h"
|
||||||
#include "virtypedparam.h"
|
#include "virtypedparam.h"
|
||||||
|
#include "virprocess.h"
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_QEMU
|
#define VIR_FROM_THIS VIR_FROM_QEMU
|
||||||
|
|
||||||
@ -2653,6 +2654,13 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
|
|||||||
QEMU_MIGRATION_COOKIE_NBD)))
|
QEMU_MIGRATION_COOKIE_NBD)))
|
||||||
goto cleanup;
|
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)
|
if (qemuMigrationJobStart(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
qemuMigrationJobSetPhase(driver, vm, QEMU_MIGRATION_PHASE_PREPARE);
|
qemuMigrationJobSetPhase(driver, vm, QEMU_MIGRATION_PHASE_PREPARE);
|
||||||
@ -2696,6 +2704,11 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
|
|||||||
QEMU_ASYNC_JOB_MIGRATION_IN) < 0)
|
QEMU_ASYNC_JOB_MIGRATION_IN) < 0)
|
||||||
goto stop;
|
goto stop;
|
||||||
|
|
||||||
|
if (STREQ(protocol, "rdma") &&
|
||||||
|
virProcessSetMaxMemLock(vm->pid, vm->def->mem.hard_limit << 10) < 0) {
|
||||||
|
goto stop;
|
||||||
|
}
|
||||||
|
|
||||||
if (mig->lockState) {
|
if (mig->lockState) {
|
||||||
VIR_DEBUG("Received lockstate %s", mig->lockState);
|
VIR_DEBUG("Received lockstate %s", mig->lockState);
|
||||||
VIR_FREE(priv->lockState);
|
VIR_FREE(priv->lockState);
|
||||||
@ -2926,7 +2939,8 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
|
|||||||
if (!(uri = qemuMigrationParseURI(uri_in, &well_formed_uri)))
|
if (!(uri = qemuMigrationParseURI(uri_in, &well_formed_uri)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (STRNEQ(uri->scheme, "tcp")) {
|
if (STRNEQ(uri->scheme, "tcp") &&
|
||||||
|
STRNEQ(uri->scheme, "rdma")) {
|
||||||
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED,
|
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED,
|
||||||
_("unsupported scheme %s in migration URI %s"),
|
_("unsupported scheme %s in migration URI %s"),
|
||||||
uri->scheme, uri_in);
|
uri->scheme, uri_in);
|
||||||
@ -3547,6 +3561,11 @@ qemuMigrationRun(virQEMUDriverPtr driver,
|
|||||||
|
|
||||||
switch (spec->destType) {
|
switch (spec->destType) {
|
||||||
case MIGRATION_DEST_HOST:
|
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,
|
ret = qemuMonitorMigrateToHost(priv->mon, migrate_flags,
|
||||||
spec->dest.host.protocol,
|
spec->dest.host.protocol,
|
||||||
spec->dest.host.name,
|
spec->dest.host.name,
|
||||||
@ -3719,7 +3738,23 @@ static int doNativeMigrate(virQEMUDriverPtr driver,
|
|||||||
if (!(uribits = qemuMigrationParseURI(uri, NULL)))
|
if (!(uribits = qemuMigrationParseURI(uri, NULL)))
|
||||||
return -1;
|
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;
|
spec.destType = MIGRATION_DEST_CONNECT_HOST;
|
||||||
else
|
else
|
||||||
spec.destType = MIGRATION_DEST_HOST;
|
spec.destType = MIGRATION_DEST_HOST;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user