}
+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 doesn't 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
QEMU_MIGRATION_COOKIE_GRAPHICS)))
goto cleanup;
+ if (qemuDomainMigrateGraphicsRelocate(driver, vm, mig) < 0)
+ VIR_WARN("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 */
* 3. start migration on source
*/
+ /*
+ * XXX need to support migration cookies
+ */
/* Stage 1. setup local support infrastructure */
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)
{
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
}
+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)
{
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);
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)
{
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);