[Spice-devel] [PATCH 1/3] client migration: switch host

Gerd Hoffmann kraxel at redhat.com
Tue Dec 14 04:10:51 PST 2010


Implement server-side support for switch-host client migration.  Client
side support is present already in the tree.

Setting the migration information is done using the existing
spice_server_migrate_info() function.  A new
spice_server_migrate_switch() function has been added which triggers
sending out the switch-host message.

Seamless migration functions are left there for now.
spice_server_migrate_start() has been chamnged to just fail
unconditionally though as seamless migration is broken anyway.

Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
---
 server/reds.c               |   66 ++++++++++++++++++++++++++++++++++++------
 server/spice-experimental.h |    4 ++-
 2 files changed, 59 insertions(+), 11 deletions(-)

diff --git a/server/reds.c b/server/reds.c
index 103a41d..ba6f552 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -2761,6 +2761,7 @@ struct RedsMigSpice {
     char pub_key[SPICE_TICKET_PUBKEY_BYTES];
     uint32_t mig_key;
     char *host;
+    char *cert_subject;
     int port;
     int sport;
     uint16_t cert_pub_key_type;
@@ -2777,6 +2778,16 @@ typedef struct RedsMigCertPubKeyInfo {
     uint32_t len;
 } RedsMigCertPubKeyInfo;
 
+static void reds_mig_release(void)
+{
+    if (reds->mig_spice) {
+        free(reds->mig_spice->cert_subject);
+        free(reds->mig_spice->host);
+        free(reds->mig_spice);
+        reds->mig_spice = NULL;
+    }
+}
+
 static void reds_mig_continue(void)
 {
     RedsMigSpice *s = reds->mig_spice;
@@ -2797,9 +2808,7 @@ static void reds_mig_continue(void)
 
     reds_push_pipe_item(item);
 
-    free(reds->mig_spice->host);
-    free(reds->mig_spice);
-    reds->mig_spice = NULL;
+    reds_mig_release();
 
     reds->mig_wait_connect = TRUE;
     core->timer_start(reds->mig_timer, MIGRATE_TIMEOUT);
@@ -2834,11 +2843,7 @@ static void reds_mig_started(void)
     return;
 
 error:
-    if (reds->mig_spice) {
-        free(reds->mig_spice->host);
-        free(reds->mig_spice);
-        reds->mig_spice = NULL;
-    }
+    reds_mig_release();
     reds_mig_disconnect();
 }
 
@@ -2885,6 +2890,33 @@ static void reds_mig_finished(int completed)
     }
 }
 
+static void reds_mig_switch(void)
+{
+    RedsMigSpice *s = reds->mig_spice;
+    SpiceMsgMainMigrationSwitchHost migrate;
+    RedsOutItem *item;
+
+    red_printf("");
+    item = new_out_item(SPICE_MSG_MAIN_MIGRATE_SWITCH_HOST);
+
+    migrate.port = s->port;
+    migrate.sport = s->sport;
+    migrate.host_size = strlen(s->host) + 1;
+    migrate.host_data = (uint8_t *)s->host;
+    if (s->cert_subject) {
+        migrate.cert_subject_size = strlen(s->cert_subject) + 1;
+        migrate.cert_subject_data = (uint8_t *)s->cert_subject;
+    } else {
+        migrate.cert_subject_size = 0;
+        migrate.cert_subject_data = NULL;
+    }
+    spice_marshall_msg_main_migrate_switch_host(item->m, &migrate);
+
+    reds_push_pipe_item(item);
+
+    reds_mig_release();
+}
+
 static void migrate_timout(void *opaque)
 {
     red_printf("");
@@ -3596,19 +3628,25 @@ __visible__ int spice_server_migrate_info(SpiceServer *s, const char* dest,
     spice_migration->port = port;
     spice_migration->sport = secure_port;
     spice_migration->host = strdup(dest);
-
     if (cert_subject) {
-        /* TODO */
+        spice_migration->cert_subject = strdup(cert_subject);
     }
 
+    reds_mig_release();
     reds->mig_spice = spice_migration;
     return 0;
 }
 
+/* interface for seamless migration */
 __visible__ int spice_server_migrate_start(SpiceServer *s)
 {
     ASSERT(reds == s);
 
+    if (1) {
+        /* seamless doesn't work, fixing needs protocol change. */
+        return -1;
+    }
+
     if (!reds->mig_spice) {
         return -1;
     }
@@ -3636,3 +3674,11 @@ __visible__ int spice_server_migrate_end(SpiceServer *s, int completed)
     reds_mig_finished(completed);
     return 0;
 }
+
+/* interface for switch-host migration */
+__visible__ int spice_server_migrate_switch(SpiceServer *s)
+{
+    ASSERT(reds == s);
+    reds_mig_switch();
+    return 0;
+}
diff --git a/server/spice-experimental.h b/server/spice-experimental.h
index 526062f..70d2246 100644
--- a/server/spice-experimental.h
+++ b/server/spice-experimental.h
@@ -61,11 +61,13 @@ enum {
     SPICE_MIGRATE_CLIENT_READY,
 };
 
-int spice_server_migrate_info(SpiceServer *s, const char* dest, int port, int secure_port,
+int spice_server_migrate_info(SpiceServer *s, const char* dest,
+                              int port, int secure_port,
                               const char* cert_subject);
 int spice_server_migrate_start(SpiceServer *s);
 int spice_server_migrate_client_state(SpiceServer *s);
 int spice_server_migrate_end(SpiceServer *s, int completed);
+int spice_server_migrate_switch(SpiceServer *s);
 
 #endif // __SPICE_EXPERIMENTAL_H__
 
-- 
1.7.1



More information about the Spice-devel mailing list