提交 2c4ba8b4 编写于 作者: J Jiri Denemark

qemu: Use -incoming defer for migrations

Traditionally, we pass incoming migration URI on QEMU command line,
which has some drawbacks. Depending on the URI QEMU may initialize its
migration state immediately without giving us a chance to set any
additional migration parameters (this applies mainly for fd: URIs). For
some URIs the monitor may be completely blocked from the beginning until
migration is finished, which means we may be stuck in qmp_capabilities
command without being able to send any QMP commands.

QEMU solved this by introducing "defer" parameter for -incoming command
line option. This will tell QEMU to prepare for an incoming migration
while the actual incoming URI is sent using migrate-incoming QMP
command. Before calling this command we can normally talk to the
monitor and even set any migration parameters which will be honored by
the incoming migration.
Signed-off-by: NJiri Denemark <jdenemar@redhat.com>
上级 93d56e9d
......@@ -299,6 +299,8 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
"e1000",
"virtio-net",
"gic-version",
"incoming-defer", /* 200 */
);
......@@ -1458,6 +1460,7 @@ struct virQEMUCapsStringFlags virQEMUCapsCommands[] = {
{ "nbd-server-start", QEMU_CAPS_NBD_SERVER },
{ "change-backing-file", QEMU_CAPS_CHANGE_BACKING_FILE },
{ "rtc-reset-reinjection", QEMU_CAPS_RTC_RESET_REINJECTION },
{ "migrate-incoming", QEMU_CAPS_INCOMING_DEFER },
};
struct virQEMUCapsStringFlags virQEMUCapsMigration[] = {
......
......@@ -325,6 +325,9 @@ typedef enum {
QEMU_CAPS_DEVICE_VIRTIO_NET, /* -device virtio-net-* */
QEMU_CAPS_MACH_VIRT_GIC_VERSION, /* -machine virt,gic-version */
/* 200 */
QEMU_CAPS_INCOMING_DEFER, /* -incoming defer and migrate_incoming */
QEMU_CAPS_LAST /* this must always be the last item */
} virQEMUCapsFlags;
......
......@@ -2951,6 +2951,42 @@ qemuMigrationIncomingURI(const char *migrateFrom,
}
int
qemuMigrationRunIncoming(virQEMUDriverPtr driver,
virDomainObjPtr vm,
const char *uri,
qemuDomainAsyncJob asyncJob)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
int ret = -1;
int rv;
VIR_DEBUG("Setting up incoming migration with URI %s", uri);
if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
return -1;
rv = qemuMonitorMigrateIncoming(priv->mon, uri);
if (qemuDomainObjExitMonitor(driver, vm) < 0 || rv < 0)
goto cleanup;
if (asyncJob == QEMU_ASYNC_JOB_MIGRATION_IN) {
/* qemuMigrationWaitForDestCompletion is called from the Finish phase */
ret = 0;
goto cleanup;
}
if (qemuMigrationWaitForDestCompletion(driver, vm, asyncJob) < 0)
goto cleanup;
ret = 0;
cleanup:
return ret;
}
/* This is called for outgoing non-p2p migrations when a connection to the
* client which initiated the migration was closed but we were waiting for it
* to follow up with the next phase, that is, in between
......
......@@ -205,4 +205,9 @@ int qemuMigrationCheckIncoming(virQEMUCapsPtr qemuCaps,
char *qemuMigrationIncomingURI(const char *migrateFrom,
int migrateFd);
int qemuMigrationRunIncoming(virQEMUDriverPtr driver,
virDomainObjPtr vm,
const char *uri,
qemuDomainAsyncJob asyncJob);
#endif /* __QEMU_MIGRATION_H__ */
......@@ -4168,6 +4168,7 @@ qemuProcessIncomingDefFree(qemuProcessIncomingDefPtr inc)
return;
VIR_FREE(inc->launchURI);
VIR_FREE(inc->deferredURI);
VIR_FREE(inc);
}
......@@ -4195,6 +4196,12 @@ qemuProcessIncomingDefNew(virQEMUCapsPtr qemuCaps,
if (!inc->launchURI)
goto error;
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_INCOMING_DEFER)) {
inc->deferredURI = inc->launchURI;
if (VIR_STRDUP(inc->launchURI, "defer") < 0)
goto error;
}
inc->fd = fd;
inc->path = path;
......@@ -4940,6 +4947,11 @@ int qemuProcessStart(virConnectPtr conn,
if (qemuProcessUpdateVideoRamSize(driver, vm, asyncJob) < 0)
goto error;
if (incoming &&
incoming->deferredURI &&
qemuMigrationRunIncoming(driver, vm, incoming->deferredURI, asyncJob) < 0)
goto error;
if (!(flags & VIR_QEMU_PROCESS_START_PAUSED)) {
VIR_DEBUG("Starting domain CPUs");
/* Allow the CPUS to start executing */
......
......@@ -48,6 +48,7 @@ typedef struct _qemuProcessIncomingDef qemuProcessIncomingDef;
typedef qemuProcessIncomingDef *qemuProcessIncomingDefPtr;
struct _qemuProcessIncomingDef {
char *launchURI; /* used as a parameter for -incoming command line option */
char *deferredURI; /* used when calling migrate-incoming QMP command */
int fd; /* for fd:N URI */
const char *path; /* path associated with fd */
};
......
......@@ -161,4 +161,5 @@
<flag name='rtl8139'/>
<flag name='e1000'/>
<flag name='virtio-net'/>
<flag name='incoming-defer'/>
</qemuCaps>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册