"e1000",
"virtio-net",
"gic-version",
+
+ "incoming-defer", /* 200 */
);
{ "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[] = {
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;
}
+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
char *qemuMigrationIncomingURI(const char *migrateFrom,
int migrateFd);
+int qemuMigrationRunIncoming(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ const char *uri,
+ qemuDomainAsyncJob asyncJob);
+
#endif /* __QEMU_MIGRATION_H__ */
return;
VIR_FREE(inc->launchURI);
+ VIR_FREE(inc->deferredURI);
VIR_FREE(inc);
}
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;
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 */
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 */
};
<flag name='rtl8139'/>
<flag name='e1000'/>
<flag name='virtio-net'/>
+ <flag name='incoming-defer'/>
</qemuCaps>