monitor: Make client_migrate_info synchronous
authorMarkus Armbruster <armbru@redhat.com>
Thu, 5 Mar 2015 08:30:16 +0000 (09:30 +0100)
committerGerd Hoffmann <kraxel@redhat.com>
Mon, 27 Apr 2015 10:46:57 +0000 (12:46 +0200)
Live migration with spice works like this today:

  (1) client_migrate_info monitor cmd
  (2) spice server notifies client, client connects to target host.
  (3) qemu waits until spice client connect is finished.
  (4) send over vmstate (i.e. main part of live migration).
  (5) spice handover to target host.

(3) is implemented by making client_migrate_info a async monitor
command.  This is the only async monitor command we have.

The original reason to implement this dance was that qemu did not accept
new tcp connections while the incoming migration was running, so (2) and
(4) could not be done in parallel.  That issue was fixed long ago though.
Qemu version 1.3.0 (released Dec 2012) and newer happily accept tcp
connects while the incoming migration runs.

Time to drop step (3).  This patch does exactly that, by making the
monitor command synchronous and removing the code needed to handle the
async monitor command in ui/spice-core.c

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
hmp-commands.hx
include/ui/qemu-spice.h
monitor.c
qmp-commands.hx
ui/spice-core.c

index 3089533a4f723d8e43169c838cc3e8f9004e181c..a6de819f690816473aad59faf7e80afecccc5455 100644 (file)
@@ -998,8 +998,7 @@ ETEXI
         .params     = "protocol hostname port tls-port cert-subject",
         .help       = "send migration info to spice/vnc client",
         .user_print = monitor_user_noop,
-        .mhandler.cmd_async = client_migrate_info,
-        .flags      = MONITOR_CMD_ASYNC,
+        .mhandler.cmd_new = client_migrate_info,
     },
 
 STEXI
index 25b94c753026a888764e61cc2cd1e0f6321a7ae1..42db3c1645bdbbc308cae354c1112afdb0bb410d 100644 (file)
@@ -42,8 +42,7 @@ int qemu_spice_set_passwd(const char *passwd,
                           bool fail_if_connected, bool disconnect_if_connected);
 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,
-                            MonitorCompletion cb, void *opaque);
+                            const char *subject);
 
 CharDriverState *qemu_chr_open_spice_vmc(const char *type);
 #if SPICE_SERVER_VERSION >= 0x000c02
@@ -70,10 +69,8 @@ static inline int qemu_spice_set_pw_expire(time_t expires)
     return -1;
 }
 static inline int qemu_spice_migrate_info(const char *h, int p, int t,
-                                          const char *s,
-                                          MonitorCompletion cb, void *opaque)
+                                          const char *s)
 {
-    cb(opaque, NULL);
     return -1;
 }
 
index 68873ec09cd6d39e7d907eeca24f779adff5b131..4b6403733aab794e77ab71ba4f270fa9a4982469 100644 (file)
--- a/monitor.c
+++ b/monitor.c
@@ -1086,7 +1086,7 @@ static void hmp_info_trace_events(Monitor *mon, const QDict *qdict)
 }
 
 static int client_migrate_info(Monitor *mon, const QDict *qdict,
-                               MonitorCompletion cb, void *opaque)
+                               QObject **ret_data)
 {
     const char *protocol = qdict_get_str(qdict, "protocol");
     const char *hostname = qdict_get_str(qdict, "hostname");
@@ -1108,8 +1108,7 @@ static int client_migrate_info(Monitor *mon, const QDict *qdict,
             return -1;
         }
 
-        ret = qemu_spice_migrate_info(hostname, port, tls_port, subject,
-                                      cb, opaque);
+        ret = qemu_spice_migrate_info(hostname, port, tls_port, subject);
         if (ret != 0) {
             qerror_report(QERR_UNDEFINED_ERROR);
             return -1;
index 3a42ad0bffeb23778f877410f6e2038943da46c0..35ef759bba2951215591a1682c302211f5b4d315 100644 (file)
@@ -785,8 +785,7 @@ EQMP
         .args_type  = "protocol:s,hostname:s,port:i?,tls-port:i?,cert-subject:s?",
         .params     = "protocol hostname port tls-port cert-subject",
         .help       = "send migration info to spice/vnc client",
-        .mhandler.cmd_async = client_migrate_info,
-        .flags      = MONITOR_CMD_ASYNC,
+        .mhandler.cmd_new = client_migrate_info,
     },
 
 SQMP
index c8f7f183c6f26aa4dedb8569eb92c3efddb5920c..f00e0742b4adac2e08bb22349c0e55d39ab5e98e 100644 (file)
@@ -273,14 +273,6 @@ static SpiceCoreInterface core_interface = {
     .channel_event      = channel_event,
 };
 
-typedef struct SpiceMigration {
-    SpiceMigrateInstance sin;
-    struct {
-        MonitorCompletion *cb;
-        void *opaque;
-    } connect_complete;
-} SpiceMigration;
-
 static void migrate_connect_complete_cb(SpiceMigrateInstance *sin);
 static void migrate_end_complete_cb(SpiceMigrateInstance *sin);
 
@@ -293,15 +285,11 @@ static const SpiceMigrateInterface migrate_interface = {
     .migrate_end_complete = migrate_end_complete_cb,
 };
 
-static SpiceMigration spice_migrate;
+static SpiceMigrateInstance spice_migrate;
 
 static void migrate_connect_complete_cb(SpiceMigrateInstance *sin)
 {
-    SpiceMigration *sm = container_of(sin, SpiceMigration, sin);
-    if (sm->connect_complete.cb) {
-        sm->connect_complete.cb(sm->connect_complete.opaque, NULL);
-    }
-    sm->connect_complete.cb = NULL;
+    /* nothing, but libspice-server expects this cb being present. */
 }
 
 static void migrate_end_complete_cb(SpiceMigrateInstance *sin)
@@ -585,13 +573,10 @@ static void migration_state_notifier(Notifier *notifier, void *data)
 }
 
 int qemu_spice_migrate_info(const char *hostname, int port, int tls_port,
-                            const char *subject,
-                            MonitorCompletion *cb, void *opaque)
+                            const char *subject)
 {
     int ret;
 
-    spice_migrate.connect_complete.cb = cb;
-    spice_migrate.connect_complete.opaque = opaque;
     ret = spice_server_migrate_connect(spice_server, hostname,
                                        port, tls_port, subject);
     spice_have_target_host = true;
@@ -812,9 +797,8 @@ void qemu_spice_init(void)
 
     migration_state.notify = migration_state_notifier;
     add_migration_state_change_notifier(&migration_state);
-    spice_migrate.sin.base.sif = &migrate_interface.base;
-    spice_migrate.connect_complete.cb = NULL;
-    qemu_spice_add_interface(&spice_migrate.sin.base);
+    spice_migrate.base.sif = &migrate_interface.base;
+    qemu_spice_add_interface(&spice_migrate.base);
 
     qemu_spice_input_init();
     qemu_spice_audio_init();