]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Use -incoming defer for migrations
authorJiri Denemark <jdenemar@redhat.com>
Wed, 11 Nov 2015 17:02:23 +0000 (18:02 +0100)
committerJiri Denemark <jdenemar@redhat.com>
Thu, 19 Nov 2015 08:41:23 +0000 (09:41 +0100)
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: Jiri Denemark <jdenemar@redhat.com>
src/qemu/qemu_capabilities.c
src/qemu/qemu_capabilities.h
src/qemu/qemu_migration.c
src/qemu/qemu_migration.h
src/qemu/qemu_process.c
src/qemu/qemu_process.h
tests/qemucapabilitiesdata/caps_2.4.0-1.caps

index 7475298357c15ce262d1207dc931d37d0c43663e..2813212c755be3d2e3e4b882c5e699970ed802f2 100644 (file)
@@ -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[] = {
index 14541f629eb0fb756c396b65bd46814196e3d6fe..e3e40e59543df0d2c49f1faa41b41fcc619bdd0f 100644 (file)
@@ -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;
 
index 4d5b966b2537a4871bbdbef5d9db0d00b60479a4..0c4c94aeea4271e9976269f758b87f6536cf3484 100644 (file)
@@ -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
index ff4fe30b88f580e66d029a71db749543c3923b06..2445e13936333d3865017ff8bee786471d61142e 100644 (file)
@@ -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__ */
index 1b20f412f58d7360ffbb89169c4a0f84608c3901..82f914ac39ade65aa88a4968c7aba38880779892 100644 (file)
@@ -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 */
index dcba72816210f6c64a0d89717a1970c905c30ea4..dcb7e2848e672e355db64c9a473d89744c819481 100644 (file)
@@ -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 */
 };
index 0d1b1c0818ae3e9dcbab53cfae88e994895fca18..6694b7dbc1c1ee7c530617ddfd325880cb30b766 100644 (file)
     <flag name='rtl8139'/>
     <flag name='e1000'/>
     <flag name='virtio-net'/>
+    <flag name='incoming-defer'/>
   </qemuCaps>