summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorYonit Halperin <yhalperi@redhat.com>2013-04-08 16:16:05 -0400
committerYonit Halperin <yhalperi@redhat.com>2013-04-08 16:16:05 -0400
commitc7e81980917ac0172f943f2252b0458dbc1a8cfa (patch)
tree9b4fe1031e42853cca0104903fc5057e1a8e80fc /server
parent21123f34e7f3601f072efa5b5ad8bf7024e5b555 (diff)
downloadspice-c7e81980917ac0172f943f2252b0458dbc1a8cfa.tar.gz
spice-c7e81980917ac0172f943f2252b0458dbc1a8cfa.tar.xz
spice-c7e81980917ac0172f943f2252b0458dbc1a8cfa.zip
red_worker.c: fix not destroying streams before sending MSG_MIGRATE
When qemu migration completes, we need to stop the streams, and to send the corresponding upgrade_items to the client. Otherwise, (1) the client might display lossy regions that we don't track (streams are not part of the migration data). (2) streams_timeout may occur after MSG_MIGRATE has been sent, leading to messages being sent to the client after MSG_MIGRATE and before MSG_MIGRATE_DATA (e.g., STREAM_CLIP, STREAM_DESTROY, DRAW_COPY). No message besides MSG_MIGRATE_DATA should be sent after MSG_MIGRATE. When a msg other than MIGRATE_DATA reached spice-gtk after MSG_MIGRATE, spice-gtk sent it to dest server as the migration data, and the dest server crashed with a "bad message size" assert.
Diffstat (limited to 'server')
-rw-r--r--server/red_worker.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/server/red_worker.c b/server/red_worker.c
index 25824b49..4842ad61 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -9171,10 +9171,33 @@ void red_disconnect_all_display_TODO_remove_me(RedChannel *channel)
red_channel_apply_clients(channel, red_channel_client_disconnect);
}
+static void red_destroy_streams(RedWorker *worker)
+{
+ RingItem *stream_item;
+
+ spice_debug(NULL);
+ while ((stream_item = ring_get_head(&worker->streams))) {
+ Stream *stream = SPICE_CONTAINEROF(stream_item, Stream, link);
+
+ red_detach_stream_gracefully(worker, stream, NULL);
+ red_stop_stream(worker, stream);
+ }
+}
+
static void red_migrate_display(RedWorker *worker, RedChannelClient *rcc)
{
+ /* We need to stop the streams, and to send upgrade_items to the client.
+ * Otherwise, (1) the client might display lossy regions that we don't track
+ * (streams are not part of the migration data) (2) streams_timeout may occur
+ * after the MIGRATE message has been sent. This can result in messages
+ * being sent to the client after MSG_MIGRATE and before MSG_MIGRATE_DATA (e.g.,
+ * STREAM_CLIP, STREAM_DESTROY, DRAW_COPY)
+ * No message besides MSG_MIGRATE_DATA should be sent after MSG_MIGRATE.
+ * Notice that red_destroy_streams won't lead to any dev ram changes, since
+ * handle_dev_stop already took care of releasing all the dev ram resources.
+ */
+ red_destroy_streams(worker);
if (red_channel_client_is_connected(rcc)) {
- red_pipe_add_verb(rcc, SPICE_MSG_DISPLAY_STREAM_DESTROY_ALL);
red_channel_client_default_migrate(rcc);
}
}