spice/server
Uri Lublin 2d1c00a659 migration: Don't assert() if MIGRATE_DATA comes before attaching the agent
During seamless migration, after switching host, if a client was connected
during the migration, it will have data to send back to the new
qemu/spice-server instance. This is handled through MIGRATE_DATA messages.
SPICE char devices use such MIGRATE_DATA messages to restore their state.

However, the MIGRATE_DATA message can arrive any time after the new qemu
instance has started, this can happen before or after the SPICE char
devices have been created. In order to handle this, if the migrate data
arrives early, it's stored in reds->agent_state.mig_data, and
attach_to_red_agent() will restore the agent state as appropriate.

Unfortunately this does not work as expected, for main
channel (agent messages).
If attach_to_red_agent() is called before the MIGRATE_DATA
message reaches the server, all goes well,
but if MIGRATE_DATA reaches the server before
attach_to_red_agent() gets called, then some assert() gets
triggered in spice_char_device_state_restore():

((null):32507): Spice-ERROR **: char_device.c:937:spice_char_device_state_restore: assertion `dev->num_clients == 1 && dev->wait_for_migrate_data' failed
Thread 3 (Thread 0x7f406b543700 (LWP 32543)):
Thread 2 (Thread 0x7f40697ff700 (LWP 32586)):
Thread 1 (Thread 0x7f4079b45a40 (LWP 32507)):

When restoring state, a client must already be added to the
spice-char-device.
What happens is that a client is not being added to the char-device
when when MIGRATE_DATA arrives first, which leaves both
dev->num_clients and dev->wait_for_migrate_data value at 0.

This commit changes the logic in spice_server_char_device_add_interface(),
such that if there is migrate data pending in reds->agent_state.mig_data
but no client was added to the spice-char-device yet,
then first the client is added to the device by calling
spice_char_device_client_add(), and only then the state is restored.

=== How to Reproduce
To reproduce, add delays to the migration connection between
qmeu-kvm on the source host (SRC) and on the destination (DST).

Specifically I added a man in the middle DLY host between
migration ports from SRC to DST.

+-----+    +-----+     +-----+
| SRC |--> | DLY | --> | DST |
+-----+    +-----+     +-----+

DLY listens on port P1 (e.g. 4444) and DST listens on port
PINCOMING (e.g. 4444, from qemu-kvm '-incoming' command line option)

Precondition: make sure port P1 on DLY is accessible in iptables.
Option 1: use ssh tcp port forwarding
On DLY host run ssh:
  ssh DLY:P1:DST:PINCOMING DST
Then use the following migration command (on qemu-kvm monitor):
  client_migrate_info spice DST PSPICE
  migrate -d tcp:DLY:P1

Option 2: Use a simple proxy program that forwards
packets from SRC to DST while adding some delays.
The program runs on DLY, listens to port D1, upon
accept connects to DST:PINCOMING and forward all
packets from DLY:D1 to DST:PINCOMING.
Then use the same migrate command as in option 1:
  client_migrate_info spice DST PSPICE
  migrate -d tcp:DLY:P1

=== How to Reproduce Ends

This fixes https://bugzilla.redhat.com/show_bug.cgi?id=1035184

Based-on-a-patch-by: Christophe Fergeau <cfergeau@redhat.com>
2014-10-14 15:48:02 +03:00
..
tests server/tests/Makefile.am: White-space cleanup 2014-09-18 14:06:55 +02:00
.gitignore gitignore: add generated_*, vim temps, pyc 2010-11-08 16:06:55 +02:00
agent-msg-filter.c server: Add support for filtering out agent file-xfer msgs (rhbz#961848) 2013-06-06 16:07:30 +02:00
agent-msg-filter.h server: Add support for filtering out agent file-xfer msgs (rhbz#961848) 2013-06-06 16:07:30 +02:00
char_device.c syntax-check: remove trailing whitespaces 2013-07-16 23:37:29 +03:00
char_device.h syntax-check: s/the the/the/ in a comment 2013-07-16 23:37:28 +03:00
demarshallers.h Remove trailing blank lines 2012-01-13 18:11:59 +02:00
dispatcher.c Don't do arithmetic on void * type, use uint8_t instead 2012-04-25 09:40:18 +01:00
dispatcher.h dispatcher.h: fix - s/#define MAIN_DISPATCHER_H/#define DISPATCHER_H 2013-04-22 16:30:54 -04:00
glz_encode_match_tmpl.c add #include <config.h> to all source files 2011-05-03 14:44:10 +02:00
glz_encode_tmpl.c Remove trailing whitespace from end of lines 2012-01-13 18:11:59 +02:00
glz_encoder_config.h Fix multiple printf format problems 2012-04-25 09:42:11 +01:00
glz_encoder_dictionary_protected.h server: s/max_encdoers/max_encoders/ 2012-08-30 17:08:09 +03:00
glz_encoder_dictionary.c server: s/max_encdoers/max_encoders/ 2012-08-30 17:08:09 +03:00
glz_encoder_dictionary.h Remove trailing blank lines 2012-01-13 18:11:59 +02:00
glz_encoder.c Remove trailing blank lines 2012-01-13 18:11:59 +02:00
glz_encoder.h Use the spice-common submodule 2012-03-25 18:59:10 +02:00
inputs_channel.c Introduce reds_stream_is_ssl() 2014-01-20 12:15:42 +01:00
inputs_channel.h Remove trailing blank lines 2012-01-13 18:11:59 +02:00
jpeg_encoder.c Use the spice-common logging functions 2012-03-25 19:00:00 +02:00
jpeg_encoder.h Remove trailing whitespace from end of lines 2012-01-13 18:11:59 +02:00
main_channel.c main_channel: monitoring client connection status 2013-08-14 13:36:30 -04:00
main_channel.h Namespace RECEIVE_BUF_SIZE 2013-10-08 19:07:41 +02:00
main_dispatcher.c decouple disconnection of the main channel from client destruction 2013-07-29 11:35:17 -04:00
main_dispatcher.h decouple disconnection of the main channel from client destruction 2013-07-29 11:35:17 -04:00
Makefile.am Add reds_stream.[ch] 2014-01-20 12:15:41 +01:00
migration_protocol.h enable seamless migration and set migration protocol version 2012-08-27 09:13:14 +03:00
mjpeg_encoder.c Fix assert in mjpeg_encoder_adjust_params_to_bit_rate() 2014-05-30 13:45:02 -05:00
mjpeg_encoder.h mjpeg_encoder: add mjpeg_encoder_get_stats 2013-06-24 15:23:34 -04:00
red_bitmap_utils.h Remove trailing blank lines 2012-01-13 18:11:59 +02:00
red_channel.c server: use a warning when disconnecting unresponsive client 2014-05-16 19:20:51 +02:00
red_channel.h Fix test_capability() typo 2014-03-13 17:13:38 +01:00
red_client_cache.h Use the spice-common logging functions 2012-03-25 19:00:00 +02:00
red_client_shared_cache.h Use the spice-common logging functions 2012-03-25 19:00:00 +02:00
red_common.h Move SPICE_GNUC_VISIBLE to red_common.h 2014-01-20 12:15:41 +01:00
red_dispatcher.c dispatcher: lower a monitor-config warning to a debug level 2014-09-08 12:04:15 +02:00
red_dispatcher.h server: set dispatcher before calling attache_worker 2013-10-07 16:33:20 +02:00
red_memslots.c server: remove memslot unused functions 2013-10-01 16:23:59 +02:00
red_memslots.h server: remove memslot unused functions 2013-10-01 16:23:59 +02:00
red_parse_qxl.c Fix indentation in red_get_opaque_ptr 2014-09-18 14:06:55 +02:00
red_parse_qxl.h Add support for QXLComposite to spice server 2012-08-24 13:44:42 -04:00
red_time.h server: move three functions to red_channel 2013-08-14 12:08:04 +03:00
red_worker.c Validate surface bounding box before using it 2014-09-18 14:06:55 +02:00
red_worker.h server: move bit set/clear utilities out of red_worker.h 2013-08-14 12:08:04 +03:00
reds_gl_canvas.c Use the spice-common submodule 2012-03-25 18:59:10 +02:00
reds_gl_canvas.h Use the spice-common submodule 2012-03-25 18:59:10 +02:00
reds_stream.c Add missing buffer (re)allocation to reds_sasl_handle_auth_steplen() 2014-04-16 17:11:38 +02:00
reds_stream.h Make struct AsyncRead/async_read_handler private 2014-04-16 17:11:38 +02:00
reds_sw_canvas.c Use the spice-common submodule 2012-03-25 18:59:10 +02:00
reds_sw_canvas.h Use the spice-common submodule 2012-03-25 18:59:10 +02:00
reds-private.h Fix 'recive' typo throughout the code base 2013-10-08 19:07:42 +02:00
reds.c migration: Don't assert() if MIGRATE_DATA comes before attaching the agent 2014-10-14 15:48:02 +03:00
reds.h clean-up: remove unused function 2014-09-08 14:49:29 +02:00
smartcard.c red_channel: monitor connection latency using MSG_PING 2013-04-22 16:30:54 -04:00
smartcard.h smartcard: use SpiceCharDeviceState for managing reading from the device 2012-07-03 14:13:42 +03:00
snd_worker.c server: don't assert on invalid client message 2014-07-25 17:25:29 +02:00
snd_worker.h snd_worker: support sending SPICE_MSG_PLAYBACK_LATENCY 2013-04-22 16:30:54 -04:00
spice_bitmap_utils.c server: Don't dump the bitmap when the format is invalid 2014-09-12 18:00:30 +02:00
spice_bitmap_utils.h server: move surface_format_to_image_type to spice_bitmap_utils 2013-08-14 12:08:04 +03:00
spice_image_cache.c server: split spice_image_cache from red_worker 2013-08-14 12:08:04 +03:00
spice_image_cache.h server: split spice_image_cache from red_worker 2013-08-14 12:08:04 +03:00
spice_server_utils.h server: move bit set/clear utilities out of red_worker.h 2013-08-14 12:08:04 +03:00
spice_timer_queue.c Don't truncate large 'now' values in _spice_timer_set 2014-03-20 11:34:49 +01:00
spice_timer_queue.h server: spice_timer_queue 2013-04-22 16:30:54 -04:00
spice-experimental.h Remove trailing blank lines 2012-01-13 18:11:59 +02:00
spice-server.syms Add support for the Opus codec 2014-01-02 12:36:59 +01:00
spice.h spice.h: Don't use 48kHz for playback/recording rates 2014-08-20 16:12:31 +02:00
spicevmc.c red_channel: monitor connection latency using MSG_PING 2013-04-22 16:30:54 -04:00
stat.h Remove trailing blank lines 2012-01-13 18:11:59 +02:00
zlib_encoder.c Use the spice-common logging functions 2012-03-25 19:00:00 +02:00
zlib_encoder.h applying zlib compression over glz on WAN connection 2010-06-21 15:05:37 +02:00