mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
Wire up SPICE client relocation with QEMU migration
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
This commit is contained in:
parent
72de0d2819
commit
cc53b4c444
@ -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 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.
|
/* 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
|
* This version starts an empty VM listening on a localhost TCP port, and
|
||||||
@ -1127,6 +1160,9 @@ static int doNativeMigrate(struct qemud_driver *driver,
|
|||||||
QEMU_MIGRATION_COOKIE_GRAPHICS)))
|
QEMU_MIGRATION_COOKIE_GRAPHICS)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
if (qemuDomainMigrateGraphicsRelocate(driver, vm, mig) < 0)
|
||||||
|
VIR_WARN("unable to provide data for graphics client relocation");
|
||||||
|
|
||||||
/* Issue the migrate command. */
|
/* Issue the migrate command. */
|
||||||
if (STRPREFIX(uri, "tcp:") && !STRPREFIX(uri, "tcp://")) {
|
if (STRPREFIX(uri, "tcp:") && !STRPREFIX(uri, "tcp://")) {
|
||||||
/* HACK: source host generates bogus URIs, so fix them up */
|
/* HACK: source host generates bogus URIs, so fix them up */
|
||||||
@ -1259,6 +1295,9 @@ static int doTunnelMigrate(struct qemud_driver *driver,
|
|||||||
* 3. start migration on source
|
* 3. start migration on source
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX need to support migration cookies
|
||||||
|
*/
|
||||||
|
|
||||||
/* Stage 1. setup local support infrastructure */
|
/* Stage 1. setup local support infrastructure */
|
||||||
|
|
||||||
|
@ -1640,6 +1640,37 @@ int qemuMonitorMigrateCancel(qemuMonitorPtr mon)
|
|||||||
return ret;
|
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,
|
int qemuMonitorAddUSBDisk(qemuMonitorPtr mon,
|
||||||
const char *path)
|
const char *path)
|
||||||
{
|
{
|
||||||
|
@ -305,6 +305,12 @@ int qemuMonitorMigrateToUnix(qemuMonitorPtr mon,
|
|||||||
|
|
||||||
int qemuMonitorMigrateCancel(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 disk driver type eg, qcow/etc.
|
||||||
* XXX cache mode
|
* XXX cache mode
|
||||||
|
@ -1862,6 +1862,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,
|
int qemuMonitorJSONAddUSBDisk(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
|
||||||
const char *path ATTRIBUTE_UNUSED)
|
const char *path ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
|
@ -118,6 +118,13 @@ int qemuMonitorJSONMigrate(qemuMonitorPtr mon,
|
|||||||
|
|
||||||
int qemuMonitorJSONMigrateCancel(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,
|
int qemuMonitorJSONAddUSBDisk(qemuMonitorPtr mon,
|
||||||
const char *path);
|
const char *path);
|
||||||
|
|
||||||
|
@ -1312,6 +1312,37 @@ int qemuMonitorTextMigrateCancel(qemuMonitorPtr mon)
|
|||||||
return 0;
|
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,
|
int qemuMonitorTextAddUSBDisk(qemuMonitorPtr mon,
|
||||||
const char *path)
|
const char *path)
|
||||||
{
|
{
|
||||||
|
@ -114,6 +114,13 @@ int qemuMonitorTextMigrate(qemuMonitorPtr mon,
|
|||||||
|
|
||||||
int qemuMonitorTextMigrateCancel(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,
|
int qemuMonitorTextAddUSBDisk(qemuMonitorPtr mon,
|
||||||
const char *path);
|
const char *path);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user