summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2010-04-23 13:28:21 +0200
committerGerd Hoffmann <kraxel@redhat.com>2010-08-31 16:14:00 +0200
commitcb98fe20e2321788fd0fee9d650ce8eab3062af3 (patch)
treeea45a2c5552fb34365fb441fc71c6361c2490d3a
parent39c8f8819d60f4af973be15ddf7b809453eee74a (diff)
[wip] spice: client migration.
Handle spice client migration, i.e. inform a spice client connected about the new host and connection parameters, so it can move over the connection automatically.
-rw-r--r--monitor.c1
-rw-r--r--qemu-monitor.hx11
-rw-r--r--ui/qemu-spice.h2
-rw-r--r--ui/spice-core.c91
4 files changed, 105 insertions, 0 deletions
diff --git a/monitor.c b/monitor.c
index e27f8d8d3..61d12ec40 100644
--- a/monitor.c
+++ b/monitor.c
@@ -56,6 +56,7 @@
#include "json-parser.h"
#include "osdep.h"
#include "exec-all.h"
+#include "ui/qemu-spice.h"
//#define DEBUG
//#define DEBUG_COMPLETION
diff --git a/qemu-monitor.hx b/qemu-monitor.hx
index 5c1da3398..dc7f407a6 100644
--- a/qemu-monitor.hx
+++ b/qemu-monitor.hx
@@ -2531,6 +2531,17 @@ ETEXI
HXCOMM DO NOT add new commands after 'info', move your addition before it!
+#if defined(CONFIG_SPICE)
+ {
+ .name = "spice_migrate_info",
+ .args_type = "hostname:s,port:i?,tls-port:i?,cert-subject:s?",
+ .params = "hostname port tls-port cert-subject",
+ .help = "send migration info to spice client",
+ .user_print = monitor_user_noop,
+ .mhandler.cmd_new = mon_spice_migrate,
+ },
+#endif
+
STEXI
@end table
ETEXI
diff --git a/ui/qemu-spice.h b/ui/qemu-spice.h
index 0e3ad9b8c..79001cf75 100644
--- a/ui/qemu-spice.h
+++ b/ui/qemu-spice.h
@@ -33,6 +33,8 @@ void qemu_spice_audio_init(void);
void qemu_spice_display_init(DisplayState *ds);
int qemu_spice_add_interface(SpiceBaseInstance *sin);
+int mon_spice_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data);
+
#else /* CONFIG_SPICE */
#define using_spice 0
diff --git a/ui/spice-core.c b/ui/spice-core.c
index 7d43f7e22..688a60c69 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -24,6 +24,7 @@
#include "qemu-queue.h"
#include "qemu-x509.h"
#include "monitor.h"
+#include "hw/hw.h"
/* core bits */
@@ -202,8 +203,92 @@ static const char *wan_compression_names[] = {
parse_name(_name, "wan compression", \
wan_compression_names, ARRAY_SIZE(wan_compression_names))
+#if 0
+/* handle client migration */
+
+static int spice_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
+{
+ static int last_stage;
+ static int migrate_client, client_connected;
+ int ret = 1;
+
+ if (last_stage != stage) {
+ last_stage = stage;
+ fprintf(stderr, "%s: stage %d\n", __FUNCTION__, stage);
+ } else {
+ fprintf(stderr, ".");
+ }
+
+ switch (stage) {
+ case 1:
+ migrate_client = 1;
+ client_connected = 0;
+ fprintf(stderr, "%s: start client migration\n", __FUNCTION__);
+ if (spice_server_migrate_start(spice_server) != 0) {
+ fprintf(stderr, "%s: fail -> no client migration\n", __FUNCTION__);
+ migrate_client = 0;
+ }
+ break;
+ case 2:
+ if (!migrate_client)
+ break;
+ switch (spice_server_migrate_client_state(spice_server)) {
+ case SPICE_MIGRATE_CLIENT_NONE:
+ fprintf(stderr, "%s: no client connected\n", __FUNCTION__);
+ migrate_client = 0;
+ break;
+ case SPICE_MIGRATE_CLIENT_WAITING:
+ ret = 0;
+ break;
+ case SPICE_MIGRATE_CLIENT_READY:
+ if (!client_connected) {
+ fprintf(stderr, "%s: client connected to target\n", __FUNCTION__);
+ client_connected = 1;
+ }
+ break;
+ }
+ break;
+ case 3:
+ if (migrate_client && client_connected) {
+ fprintf(stderr, "%s: finish client migration\n", __FUNCTION__);
+ spice_server_migrate_end(spice_server, 1);
+ }
+ break;
+ }
+ return ret;
+}
+
+static void spice_save(QEMUFile *f, void *opaque)
+{
+ fprintf(stderr, "%s:\n", __FUNCTION__);
+}
+
+static int spice_load(QEMUFile *f, void *opaque, int version_id)
+{
+ fprintf(stderr, "%s:\n", __FUNCTION__);
+ return 0;
+}
+#endif
+
/* functions for the rest of qemu */
+int mon_spice_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data)
+{
+ const char *hostname = qdict_get_str(qdict, "hostname");
+ const char *subject = qdict_get_try_str(qdict, "cert-subject");
+ int port = qdict_get_try_int(qdict, "port", -1);
+ int tls_port = qdict_get_try_int(qdict, "tls-port", -1);
+
+ if (!spice_server) {
+ qerror_report(QERR_DEVICE_NOT_ACTIVE, "spice");
+ return -1;
+ }
+
+ /* TODO: Convert to QError */
+ return spice_server_migrate_info(spice_server, hostname,
+ port, tls_port, subject);
+}
+
static int add_channel(const char *name, const char *value, void *opaque)
{
int security = 0;
@@ -360,6 +445,12 @@ void qemu_spice_init(void)
qemu_spice_input_init();
qemu_spice_audio_init();
+#if 0
+ register_savevm_live(NULL, "spice", -1, 1, NULL,
+ spice_live, spice_save, spice_load,
+ spice_server);
+#endif
+
qemu_free(x509_key_file);
qemu_free(x509_cert_file);
qemu_free(x509_cacert_file);