* [Qemu-devel] [PATCH 1/3] add migration state change notifiers
2011-01-03 14:53 [Qemu-devel] [PATCH 0/2] migration notifiers and spice client migration Gerd Hoffmann
@ 2011-01-03 14:53 ` Gerd Hoffmann
2011-01-03 14:53 ` [Qemu-devel] [PATCH 2/3] spice: client migration Gerd Hoffmann
2011-01-03 14:53 ` [Qemu-devel] [PATCH 3/3] spice: MAINTAINERS update Gerd Hoffmann
2 siblings, 0 replies; 4+ messages in thread
From: Gerd Hoffmann @ 2011-01-03 14:53 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
This patch adds functions to register and unregister notifiers for
migration state changes and a function to query the migration state.
The notifier is called on every state change. Once after establishing a
new migration object (which is in active state then) and once when the
state changes from active to completed, canceled or error.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
migration.c | 28 ++++++++++++++++++++++++++++
migration.h | 5 +++++
2 files changed, 33 insertions(+), 0 deletions(-)
diff --git a/migration.c b/migration.c
index e5ba51c..3f88666 100644
--- a/migration.c
+++ b/migration.c
@@ -36,6 +36,9 @@ static int64_t max_throttle = (32 << 20);
static MigrationState *current_migration;
+static NotifierList migration_state_notifiers =
+ NOTIFIER_LIST_INITIALIZER(migration_state_notifiers);
+
int qemu_start_incoming_migration(const char *uri)
{
const char *p;
@@ -117,6 +120,7 @@ int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data)
}
current_migration = s;
+ notifier_list_notify(&migration_state_notifiers);
return 0;
}
@@ -268,6 +272,7 @@ void migrate_fd_error(FdMigrationState *s)
{
DPRINTF("setting error state\n");
s->state = MIG_STATE_ERROR;
+ notifier_list_notify(&migration_state_notifiers);
migrate_fd_cleanup(s);
}
@@ -325,6 +330,7 @@ ssize_t migrate_fd_put_buffer(void *opaque, const void *data, size_t size)
monitor_resume(s->mon);
}
s->state = MIG_STATE_ERROR;
+ notifier_list_notify(&migration_state_notifiers);
}
return ret;
@@ -385,6 +391,7 @@ void migrate_fd_put_ready(void *opaque)
state = MIG_STATE_ERROR;
}
s->state = state;
+ notifier_list_notify(&migration_state_notifiers);
}
}
@@ -404,6 +411,7 @@ void migrate_fd_cancel(MigrationState *mig_state)
DPRINTF("cancelling migration\n");
s->state = MIG_STATE_CANCELLED;
+ notifier_list_notify(&migration_state_notifiers);
qemu_savevm_state_cancel(s->mon, s->file);
migrate_fd_cleanup(s);
@@ -417,6 +425,7 @@ void migrate_fd_release(MigrationState *mig_state)
if (s->state == MIG_STATE_ACTIVE) {
s->state = MIG_STATE_CANCELLED;
+ notifier_list_notify(&migration_state_notifiers);
migrate_fd_cleanup(s);
}
qemu_free(s);
@@ -448,3 +457,22 @@ int migrate_fd_close(void *opaque)
qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
return s->close(s);
}
+
+void add_migration_state_change_notifier(Notifier *notify)
+{
+ notifier_list_add(&migration_state_notifiers, notify);
+}
+
+void remove_migration_state_change_notifier(Notifier *notify)
+{
+ notifier_list_remove(&migration_state_notifiers, notify);
+}
+
+int get_migration_state(void)
+{
+ if (current_migration) {
+ return migrate_fd_get_status(current_migration);
+ } else {
+ return MIG_STATE_ERROR;
+ }
+}
diff --git a/migration.h b/migration.h
index d13ed4f..2170792 100644
--- a/migration.h
+++ b/migration.h
@@ -16,6 +16,7 @@
#include "qdict.h"
#include "qemu-common.h"
+#include "notify.h"
#define MIG_STATE_ERROR -1
#define MIG_STATE_COMPLETED 0
@@ -134,4 +135,8 @@ static inline FdMigrationState *migrate_to_fms(MigrationState *mig_state)
return container_of(mig_state, FdMigrationState, mig_state);
}
+void add_migration_state_change_notifier(Notifier *notify);
+void remove_migration_state_change_notifier(Notifier *notify);
+int get_migration_state(void);
+
#endif
--
1.7.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [Qemu-devel] [PATCH 2/3] spice: client migration.
2011-01-03 14:53 [Qemu-devel] [PATCH 0/2] migration notifiers and spice client migration Gerd Hoffmann
2011-01-03 14:53 ` [Qemu-devel] [PATCH 1/3] add migration state change notifiers Gerd Hoffmann
@ 2011-01-03 14:53 ` Gerd Hoffmann
2011-01-03 14:53 ` [Qemu-devel] [PATCH 3/3] spice: MAINTAINERS update Gerd Hoffmann
2 siblings, 0 replies; 4+ messages in thread
From: Gerd Hoffmann @ 2011-01-03 14:53 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
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.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hmp-commands.hx | 20 ++++++++++++++++++++
qmp-commands.hx | 35 +++++++++++++++++++++++++++++++++++
ui/qemu-spice.h | 1 +
ui/spice-core.c | 40 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 96 insertions(+), 0 deletions(-)
diff --git a/hmp-commands.hx b/hmp-commands.hx
index df134f8..e6d8f36 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -815,6 +815,26 @@ ETEXI
},
STEXI
+@item spice_migrate_info @var{hostname} @var{port} @var{tls-port} @var{cert-subject}
+@findex spice_migrate_info
+Set the spice connection info for the migration target. The spice
+server will ask the spice client to automatically reconnect using the
+new parameters (if specified) once the vm migration finished
+successfully.
+ETEXI
+
+#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
@item snapshot_blkdev
@findex snapshot_blkdev
Snapshot device, using snapshot file as target if provided
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 56c4d8b..24ada04 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -503,6 +503,41 @@ EQMP
},
SQMP
+spice_migrate_info
+------------------
+
+Set the spice connection info for the migration target. The spice
+server will ask the spice client to automatically reconnect using the
+new parameters (if specified) once the vm migration finished
+successfully.
+
+Arguments:
+
+- "hostname": migration target hostname (json-string)
+- "port": spice tcp port for plaintext channels (json-int, optional)
+- "tls-port": spice tcp port for tls-secured channels (json-int, optional)
+- "cert-subject": server certificate subject (json-string, optional)
+
+Example:
+
+-> { "execute": "spice_migrate_info",
+ "arguments": { "hostname": "virt42.lab.kraxel.org", "port": 1234 } }
+<- { "return": {} }
+
+EQMP
+
+#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
+
+SQMP
migrate_set_speed
-----------------
diff --git a/ui/qemu-spice.h b/ui/qemu-spice.h
index 48239c3..13de5ad 100644
--- a/ui/qemu-spice.h
+++ b/ui/qemu-spice.h
@@ -38,6 +38,7 @@ int qemu_spice_set_pw_expire(time_t expires);
void do_info_spice_print(Monitor *mon, const QObject *data);
void do_info_spice(Monitor *mon, QObject **ret_data);
+int mon_spice_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data);
#else /* CONFIG_SPICE */
diff --git a/ui/spice-core.c b/ui/spice-core.c
index 27a1ced..95116cc 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -30,11 +30,15 @@
#include "qbool.h"
#include "qstring.h"
#include "qjson.h"
+#include "notify.h"
+#include "migration.h"
#include "monitor.h"
+#include "hw/hw.h"
/* core bits */
static SpiceServer *spice_server;
+static Notifier migration_state;
static const char *auth = "spice";
static char *auth_passwd;
static time_t auth_expires = TIME_MAX;
@@ -416,6 +420,39 @@ void do_info_spice(Monitor *mon, QObject **ret_data)
*ret_data = QOBJECT(server);
}
+static void migration_state_notifier(Notifier *notifier)
+{
+ int state = get_migration_state();
+
+ if (state == MIG_STATE_COMPLETED) {
+#if SPICE_SERVER_VERSION >= 0x000701 /* 0.7.1 */
+ spice_server_migrate_switch(spice_server);
+#endif
+ }
+}
+
+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);
+ int ret;
+
+ if (!spice_server) {
+ qerror_report(QERR_DEVICE_NOT_ACTIVE, "spice");
+ return -1;
+ }
+
+ ret = spice_server_migrate_info(spice_server, hostname,
+ port, tls_port, subject);
+ if (ret != 0) {
+ qerror_report(QERR_UNDEFINED_ERROR);
+ return -1;
+ }
+ return 0;
+}
+
static int add_channel(const char *name, const char *value, void *opaque)
{
int security = 0;
@@ -573,6 +610,9 @@ void qemu_spice_init(void)
spice_server_init(spice_server, &core_interface);
using_spice = 1;
+ migration_state.notify = migration_state_notifier;
+ add_migration_state_change_notifier(&migration_state);
+
qemu_spice_input_init();
qemu_spice_audio_init();
--
1.7.1
^ permalink raw reply related [flat|nested] 4+ messages in thread