[libvirt] [PATCH 05/16] Wire up SPICE client relocation with QEMU migration

Daniel P. Berrange berrange at redhat.com
Wed May 11 09:09:51 UTC 2011


Use the graphics information from the QEMU migration cookie to
issue a 'client_migrate_info' monitor command to QEMU. This causes
the SPICE client to automatically reconnect to the target host
when migration completes

* src/qemu/qemu_migration.c: Set data for SPICE client relocation
  before starting migration on src
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
  src/qemu/qemu_monitor_json.c, src/qemu/qemu_monitor_json.h,
  src/qemu/qemu_monitor_text.c, src/qemu/qemu_monitor_text.h: Add
  new qemuMonitorGraphicsRelocate() command
---
 src/qemu/qemu_migration.c    |   39 +++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_monitor.c      |   31 +++++++++++++++++++++++++++++++
 src/qemu/qemu_monitor.h      |    6 ++++++
 src/qemu/qemu_monitor_json.c |   32 ++++++++++++++++++++++++++++++++
 src/qemu/qemu_monitor_json.h |    7 +++++++
 src/qemu/qemu_monitor_text.c |   31 +++++++++++++++++++++++++++++++
 src/qemu/qemu_monitor_text.h |    7 +++++++
 7 files changed, 153 insertions(+), 0 deletions(-)

diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 5fc09f7..98305c6 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -740,6 +740,39 @@ cleanup:
 }
 
 
+static int
+qemuDomainMigrateGraphicsRelocate(struct qemud_driver *driver,
+                                  virDomainObjPtr vm,
+                                  qemuMigrationCookiePtr cookie)
+{
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    int ret;
+
+    if (!cookie)
+        return 0;
+
+    if (!cookie->graphics)
+        return 0;
+
+    /* QEMU doesnt' support VNC relocation yet, so
+     * skip it to avoid generating an error
+     */
+    if (cookie->graphics->type != VIR_DOMAIN_GRAPHICS_TYPE_SPICE)
+        return 0;
+
+    qemuDomainObjEnterMonitorWithDriver(driver, vm);
+    ret = qemuMonitorGraphicsRelocate(priv->mon,
+                                      cookie->graphics->type,
+                                      cookie->hostname,
+                                      cookie->graphics->port,
+                                      cookie->graphics->tlsPort,
+                                      cookie->graphics->tlsSubject);
+    qemuDomainObjExitMonitorWithDriver(driver, vm);
+
+    return ret;
+}
+
+
 /* Prepare is the first step, and it runs on the destination host.
  *
  * This version starts an empty VM listening on a localhost TCP port, and
@@ -1129,6 +1162,9 @@ static int doNativeMigrate(struct qemud_driver *driver,
                                        QEMU_MIGRATION_COOKIE_GRAPHICS)))
         goto cleanup;
 
+    if (qemuDomainMigrateGraphicsRelocate(driver, vm, mig) < 0)
+        VIR_WARN0("unable to provide data for graphics client relocation");
+
     /* Issue the migrate command. */
     if (STRPREFIX(uri, "tcp:") && !STRPREFIX(uri, "tcp://")) {
         /* HACK: source host generates bogus URIs, so fix them up */
@@ -1261,6 +1297,9 @@ static int doTunnelMigrate(struct qemud_driver *driver,
      *   3. start migration on source
      */
 
+    /*
+     * XXX need to support migration cookies
+     */
 
     /* Stage 1. setup local support infrastructure */
 
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 9f0f20d..b658dab 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1620,6 +1620,37 @@ int qemuMonitorMigrateCancel(qemuMonitorPtr mon)
     return ret;
 }
 
+
+int qemuMonitorGraphicsRelocate(qemuMonitorPtr mon,
+                                int type,
+                                const char *hostname,
+                                int port,
+                                int tlsPort,
+                                const char *tlsSubject)
+{
+    int ret;
+    VIR_DEBUG("mon=%p type=%d hostname=%s port=%d tlsPort=%d tlsSubject=%s",
+              mon, type, hostname, port, tlsPort, NULLSTR(tlsSubject));
+
+    if (mon->json)
+        ret = qemuMonitorJSONGraphicsRelocate(mon,
+                                              type,
+                                              hostname,
+                                              port,
+                                              tlsPort,
+                                             tlsSubject);
+    else
+        ret = qemuMonitorTextGraphicsRelocate(mon,
+                                              type,
+                                              hostname,
+                                              port,
+                                              tlsPort,
+                                              tlsSubject);
+
+    return ret;
+}
+
+
 int qemuMonitorAddUSBDisk(qemuMonitorPtr mon,
                           const char *path)
 {
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index b84e230..8f2baff 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -304,6 +304,12 @@ int qemuMonitorMigrateToUnix(qemuMonitorPtr mon,
 
 int qemuMonitorMigrateCancel(qemuMonitorPtr mon);
 
+int qemuMonitorGraphicsRelocate(qemuMonitorPtr mon,
+                                int type,
+                                const char *hostname,
+                                int port,
+                                int tlsPort,
+                                const char *tlsSubject);
 
 /* XXX disk driver type eg,  qcow/etc.
  * XXX cache mode
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 04ef077..8fc2796 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -1820,6 +1820,38 @@ int qemuMonitorJSONMigrateCancel(qemuMonitorPtr mon)
 }
 
 
+int qemuMonitorJSONGraphicsRelocate(qemuMonitorPtr mon,
+                                    int type,
+                                    const char *hostname,
+                                    int port,
+                                    int tlsPort,
+                                    const char *tlsSubject)
+{
+    int ret = -1;
+    virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("client_migrate_info",
+                                                     "s:protocol",
+                                                     (type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE ? "spice" : "vnc"),
+                                                     "s:hostname", hostname,
+                                                     "i:port", port,
+                                                     "i:tls-port", tlsPort,
+                                                     (tlsSubject ? "s:cert-subject" : NULL),
+                                                     (tlsSubject ? tlsSubject : NULL),
+                                                     NULL);
+    virJSONValuePtr reply = NULL;
+    if (!cmd)
+        return -1;
+
+    ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+
+    if (ret == 0)
+        ret = qemuMonitorJSONCheckError(cmd, reply);
+
+    virJSONValueFree(cmd);
+    virJSONValueFree(reply);
+    return ret;
+}
+
+
 int qemuMonitorJSONAddUSBDisk(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                               const char *path ATTRIBUTE_UNUSED)
 {
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index f2dc4d2..98e3bed 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -117,6 +117,13 @@ int qemuMonitorJSONMigrate(qemuMonitorPtr mon,
 
 int qemuMonitorJSONMigrateCancel(qemuMonitorPtr mon);
 
+int qemuMonitorJSONGraphicsRelocate(qemuMonitorPtr mon,
+                                    int type,
+                                    const char *hostname,
+                                    int port,
+                                    int tlsPort,
+                                    const char *tlsSubject);
+
 int qemuMonitorJSONAddUSBDisk(qemuMonitorPtr mon,
                               const char *path);
 
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index 1a15d49..1fd2d33 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -1282,6 +1282,37 @@ int qemuMonitorTextMigrateCancel(qemuMonitorPtr mon)
     return 0;
 }
 
+
+int qemuMonitorTextGraphicsRelocate(qemuMonitorPtr mon,
+                                    int type,
+                                    const char *hostname,
+                                    int port,
+                                    int tlsPort,
+                                    const char *tlsSubject)
+{
+    char *cmd;
+    char *info = NULL;
+
+    if (virAsprintf(&cmd, "client_migrate_info %s %s %d %d %s",
+                    type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE ? "spice" : "vnc",
+                    hostname, port, tlsPort, tlsSubject ? tlsSubject : "") < 0) {
+        virReportOOMError();
+        return -1;
+    }
+
+    if (qemuMonitorHMPCommand(mon, cmd, &info) < 0) {
+        VIR_FREE(cmd);
+        qemuReportError(VIR_ERR_INTERNAL_ERROR,
+                        "%s", _("cannot run monitor command to relocate graphics client"));
+        return -1;
+    }
+    VIR_FREE(cmd);
+    VIR_FREE(info);
+
+    return 0;
+}
+
+
 int qemuMonitorTextAddUSBDisk(qemuMonitorPtr mon,
                               const char *path)
 {
diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h
index dbae72b..c803c57 100644
--- a/src/qemu/qemu_monitor_text.h
+++ b/src/qemu/qemu_monitor_text.h
@@ -113,6 +113,13 @@ int qemuMonitorTextMigrate(qemuMonitorPtr mon,
 
 int qemuMonitorTextMigrateCancel(qemuMonitorPtr mon);
 
+int qemuMonitorTextGraphicsRelocate(qemuMonitorPtr mon,
+                                    int type,
+                                    const char *hostname,
+                                    int port,
+                                    int tlsPort,
+                                    const char *tlsSubject);
+
 int qemuMonitorTextAddUSBDisk(qemuMonitorPtr mon,
                               const char *path);
 
-- 
1.7.4.4




More information about the libvir-list mailing list