[Spice-devel] [spice-gtk PATCH 6/7] seamless migration: don't reset messages data when swapping channels
Yonit Halperin
yhalperi at redhat.com
Wed Aug 15 00:56:41 PDT 2012
When swapping the src and dest channels's, we need to keep
the xmit_queue and msg serials. Their state is expected to stay the same
after migration.
---
gtk/channel-main.c | 4 +++-
gtk/spice-channel-priv.h | 2 +-
gtk/spice-channel.c | 12 +++++++-----
gtk/spice-session-priv.h | 4 +++-
gtk/spice-session.c | 18 ++++++++++++++----
gtk/spice-session.h | 7 +++++--
6 files changed, 33 insertions(+), 14 deletions(-)
diff --git a/gtk/channel-main.c b/gtk/channel-main.c
index bdcdbcb..7e98812 100644
--- a/gtk/channel-main.c
+++ b/gtk/channel-main.c
@@ -1829,7 +1829,9 @@ static void main_migrate_connect(SpiceChannel *channel,
SPICE_DEBUG("migration (semi-seamless): connections all ok");
reply_type = SPICE_MSGC_MAIN_MIGRATE_CONNECTED;
}
- spice_session_set_migration(spice_channel_get_session(channel), mig.session);
+ spice_session_set_migration(spice_channel_get_session(channel),
+ mig.session,
+ mig.do_seamless);
}
g_object_unref(mig.session);
diff --git a/gtk/spice-channel-priv.h b/gtk/spice-channel-priv.h
index 8ed79fa..cb2b75a 100644
--- a/gtk/spice-channel-priv.h
+++ b/gtk/spice-channel-priv.h
@@ -174,7 +174,7 @@ void spice_channel_handle_migrate(SpiceChannel *channel, SpiceMsgIn *in);
gint spice_channel_get_channel_id(SpiceChannel *channel);
gint spice_channel_get_channel_type(SpiceChannel *channel);
-void spice_channel_swap(SpiceChannel *channel, SpiceChannel *swap);
+void spice_channel_swap(SpiceChannel *channel, SpiceChannel *swap, gboolean keep_msgs);
gboolean spice_channel_get_read_only(SpiceChannel *channel);
void spice_channel_reset(SpiceChannel *channel, gboolean migrating);
diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c
index 5f37cbc..bb37c38 100644
--- a/gtk/spice-channel.c
+++ b/gtk/spice-channel.c
@@ -2591,7 +2591,7 @@ enum spice_channel_state spice_channel_get_state(SpiceChannel *channel)
}
G_GNUC_INTERNAL
-void spice_channel_swap(SpiceChannel *channel, SpiceChannel *swap)
+void spice_channel_swap(SpiceChannel *channel, SpiceChannel *swap, gboolean keep_msgs)
{
SpiceChannelPrivate *c = SPICE_CHANNEL_GET_PRIVATE(channel);
SpiceChannelPrivate *s = SPICE_CHANNEL_GET_PRIVATE(swap);
@@ -2614,11 +2614,13 @@ void spice_channel_swap(SpiceChannel *channel, SpiceChannel *swap)
SWAP(ctx);
SWAP(ssl);
SWAP(sslverify);
- SWAP(in_serial);
- SWAP(out_serial);
SWAP(use_mini_header);
- SWAP(xmit_queue);
- SWAP(xmit_queue_blocked);
+ if (!keep_msgs) {
+ SWAP(xmit_queue);
+ SWAP(xmit_queue_blocked);
+ SWAP(in_serial);
+ SWAP(out_serial);
+ }
SWAP(caps);
SWAP(common_caps);
SWAP(remote_caps);
diff --git a/gtk/spice-session-priv.h b/gtk/spice-session-priv.h
index c24ef8e..5efe846 100644
--- a/gtk/spice-session-priv.h
+++ b/gtk/spice-session-priv.h
@@ -119,7 +119,9 @@ void spice_session_set_mm_time(SpiceSession *session, guint32 time);
guint32 spice_session_get_mm_time(SpiceSession *session);
void spice_session_switching_disconnect(SpiceSession *session);
-void spice_session_set_migration(SpiceSession *session, SpiceSession *migration);
+void spice_session_set_migration(SpiceSession *session,
+ SpiceSession *migration,
+ gboolean seamless);
void spice_session_abort_migration(SpiceSession *session);
void spice_session_set_migration_state(SpiceSession *session, SpiceSessionMigration state);
diff --git a/gtk/spice-session.c b/gtk/spice-session.c
index 995b2ed..bfe6b89 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -1194,7 +1194,9 @@ void spice_session_switching_disconnect(SpiceSession *self)
}
G_GNUC_INTERNAL
-void spice_session_set_migration(SpiceSession *session, SpiceSession *migration)
+void spice_session_set_migration(SpiceSession *session,
+ SpiceSession *migration,
+ gboolean seamless)
{
SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session);
SpiceSessionPrivate *m = SPICE_SESSION_GET_PRIVATE(migration);
@@ -1202,7 +1204,9 @@ void spice_session_set_migration(SpiceSession *session, SpiceSession *migration)
g_return_if_fail(s != NULL);
- spice_session_set_migration_state(session, SPICE_SESSION_MIGRATION_MIGRATING);
+ spice_session_set_migration_state(session,
+ seamless ? SPICE_SESSION_MIGRATION_MIGRATING_FULL :
+ SPICE_SESSION_MIGRATION_MIGRATING_SEMI);
g_warn_if_fail(s->migration == NULL);
s->migration = g_object_ref(migration);
@@ -1259,6 +1263,7 @@ void spice_session_abort_migration(SpiceSession *session)
SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session);
RingItem *ring, *next;
struct channel *c;
+ gboolean keep_channel_msgs = s->migration_state == SPICE_SESSION_MIGRATION_MIGRATING_FULL;
g_return_if_fail(s != NULL);
@@ -1278,7 +1283,8 @@ void spice_session_abort_migration(SpiceSession *session)
spice_channel_swap(c->channel,
spice_session_lookup_channel(s->migration,
spice_channel_get_channel_id(c->channel),
- spice_channel_get_channel_type(c->channel)));
+ spice_channel_get_channel_type(c->channel)),
+ keep_channel_msgs);
}
g_list_free(s->migration_left);
@@ -1308,7 +1314,11 @@ void spice_session_channel_migrate(SpiceSession *session, SpiceChannel *channel)
c = spice_session_lookup_channel(s->migration, id, type);
g_return_if_fail(c != NULL);
- spice_channel_swap(channel, c);
+ if (!g_queue_is_empty(&c->priv->xmit_queue) &&
+ s->migration_state == SPICE_SESSION_MIGRATION_MIGRATING_FULL) {
+ g_critical("mig channel xmit queue is not empty. type %s", c->priv->name);
+ }
+ spice_channel_swap(channel, c, s->migration_state == SPICE_SESSION_MIGRATION_MIGRATING_FULL);
s->migration_left = g_list_remove(s->migration_left, channel);
if (g_list_length(s->migration_left) == 0) {
diff --git a/gtk/spice-session.h b/gtk/spice-session.h
index 4895288..4390ff0 100644
--- a/gtk/spice-session.h
+++ b/gtk/spice-session.h
@@ -52,14 +52,17 @@ typedef enum {
*
* @SPICE_SESSION_MIGRATION_NONE: no migration going on
* @SPICE_SESSION_MIGRATION_SWITCHING: the session is switching host (destroy and reconnect)
- * @SPICE_SESSION_MIGRATION_MIGRATING: the session is migrating seamlessly (reconnect)
+ * @SPICE_SESSION_MIGRATION_MIGRATING_SEMI: the session is migrating semi seamlessly (reconnect)
+ * @SPICE_SESSION_MIGRATION_MIGRATING_FULL: the session is migrating seamlessly
+ * (swap sockets, keep state)
*
* Session migration state.
**/
typedef enum {
SPICE_SESSION_MIGRATION_NONE,
SPICE_SESSION_MIGRATION_SWITCHING,
- SPICE_SESSION_MIGRATION_MIGRATING,
+ SPICE_SESSION_MIGRATION_MIGRATING_SEMI,
+ SPICE_SESSION_MIGRATION_MIGRATING_FULL,
} SpiceSessionMigration;
struct _SpiceSession
--
1.7.7.6
More information about the Spice-devel
mailing list