@@ -839,6 +839,21 @@ new parameters (if specified) once the vm migration finished successfully.
ETEXI
{
+ .name = "client_migrate_switch",
+ .args_type = "protocol:s",
+ .params = "protocol",
+ .help = "tell client to disconnect and reconnect to client_migrate_info set destination",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = client_migrate_switch,
+ },
+
+STEXI
+@item client_migrate_switch @var{protocol}
+@findex client_migrate_switch
+Tell the spice/vnc client to switch to the target set previously with client_migrate_info. Only has an effect if the last client_migrate_info used auto_switch=false.
+ETEXI
+
+ {
.name = "snapshot_blkdev",
.args_type = "device:B,snapshot-file:s?,format:s?",
.params = "device [new-image-file] [format]",
@@ -1248,6 +1248,29 @@ static int client_migrate_info(Monitor *mon, const QDict *qdict, QObject **ret_d
return -1;
}
+static int client_migrate_switch(Monitor *mon, const QDict *qdict,
+ QObject **ret_data)
+{
+ const char *protocol = qdict_get_str(qdict, "protocol");
+ int ret;
+
+ if (strcmp(protocol, "spice") == 0) {
+ if (!using_spice) {
+ qerror_report(QERR_DEVICE_NOT_ACTIVE, "spice");
+ return -1;
+ }
+ ret = qemu_spice_migrate_switch();
+ if (ret != 0) {
+ qerror_report(QERR_UNDEFINED_ERROR);
+ return -1;
+ }
+ return 0;
+ }
+
+ qerror_report(QERR_INVALID_PARAMETER, "protocol");
+ return -1;
+}
+
static int do_screen_dump(Monitor *mon, const QDict *qdict, QObject **ret_data)
{
vga_hw_screen_dump(qdict_get_str(qdict, "filename"));
@@ -609,6 +609,33 @@ Example:
EQMP
{
+ .name = "client_migrate_switch",
+ .args_type = "protocol:s",
+ .params = "protocol",
+ .help = "tell client to disconnect and reconnect to client_migrate_info set destination",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = client_migrate_switch,
+ },
+
+SQMP
+client_migrate_switch
+---------------------
+
+Tell the spice/vnc client to switch to the target set previously with client_migrate_info. Only has an effect if the last client_migrate_info used auto_switch=false.
+
+Arguments:
+
+- "protocol": protocol: "spice" or "vnc" (json-string)
+
+Example:
+
+-> { "execute": "client_migrate_switch",
+ "arguments": { "protocol": "spice" } }
+<- { "return": {} }
+
+EQMP
+
+ {
.name = "netdev_add",
.args_type = "netdev:O",
.params = "[user|tap|socket],id=str[,prop=value][,...]",
@@ -38,6 +38,7 @@ int qemu_spice_set_passwd(const char *passwd,
int qemu_spice_set_pw_expire(time_t expires);
int qemu_spice_migrate_info(const char *hostname, int port, int tls_port,
const char *subject, int auto_switch);
+int qemu_spice_migrate_switch(void);
void do_info_spice_print(Monitor *mon, const QObject *data);
void do_info_spice(Monitor *mon, QObject **ret_data);
@@ -60,6 +61,10 @@ static inline int qemu_spice_set_pw_expire(time_t expires)
static inline int qemu_spice_migrate_info(const char *h, int p, int t, const char *s)
{ return -1; }
+static inline int qemu_spice_migrate_switch(void)
+{ return -1; }
+
+
#endif /* CONFIG_SPICE */
#endif /* QEMU_SPICE_H */
@@ -451,6 +451,10 @@ int qemu_spice_migrate_info(const char *hostname, int port, int tls_port,
port, tls_port, subject);
}
+int qemu_spice_migrate_switch(void)
+{
+ return spice_server_migrate_switch(spice_server);
+}
static int add_channel(const char *name, const char *value, void *opaque)
{
Complementary to the auto_switch parameter of client_migrate_info, if that is set to false the new command client_migrate_switch can be used to complete the switch to the new client. This allows the vm manager (i.e. libvirt) to first ensure the ticketing information in the target vm is valid before issuing the switch. Signed-off-by: Alon Levy <alevy@redhat.com> --- hmp-commands.hx | 15 +++++++++++++++ monitor.c | 23 +++++++++++++++++++++++ qmp-commands.hx | 27 +++++++++++++++++++++++++++ ui/qemu-spice.h | 5 +++++ ui/spice-core.c | 4 ++++ 5 files changed, 74 insertions(+), 0 deletions(-)