diff options
author | Yonit Halperin <yhalperi@redhat.com> | 2012-08-14 14:47:49 +0300 |
---|---|---|
committer | Yonit Halperin <yhalperi@redhat.com> | 2012-08-27 09:13:00 +0300 |
commit | 275e4312df6c0f13ca2253ceac3976cee7d700e9 (patch) | |
tree | 7b49c3f4b54d7382c0a79ecc5cf71cd282362e08 /server/reds.c | |
parent | eb4c95b08b6848ee604497bb66392636341ad1fe (diff) | |
download | spice-275e4312df6c0f13ca2253ceac3976cee7d700e9.tar.gz spice-275e4312df6c0f13ca2253ceac3976cee7d700e9.tar.xz spice-275e4312df6c0f13ca2253ceac3976cee7d700e9.zip |
seamless migration: migration completion on the destination side
Tracking the channels that wait for migration data. If there
is a new migration process pending, when all the channels have
restored their state, we begin the new migration.
Diffstat (limited to 'server/reds.c')
-rw-r--r-- | server/reds.c | 42 |
1 files changed, 33 insertions, 9 deletions
diff --git a/server/reds.c b/server/reds.c index 19e72bd0..c957b5da 100644 --- a/server/reds.c +++ b/server/reds.c @@ -1440,6 +1440,21 @@ static void reds_mig_target_client_disconnect_all(void) } } +static int reds_find_client(RedClient *client) +{ + RingItem *item; + + RING_FOREACH(item, &reds->clients) { + RedClient *list_client; + + list_client = SPICE_CONTAINEROF(item, RedClient, link); + if (list_client == client) { + return TRUE; + } + } + return FALSE; +} + // TODO: now that main is a separate channel this should // actually be joined with reds_handle_other_links, become reds_handle_link static void reds_handle_main_link(RedLinkInfo *link) @@ -1625,18 +1640,26 @@ int reds_on_migrate_dst_set_seamless(MainChannelClient *mcc, uint32_t src_versio if (reds->allow_multiple_clients || src_version > SPICE_MIGRATION_PROTOCOL_VERSION) { reds->dst_do_seamless_migrate = FALSE; } else { - RedClient *client; + RedChannelClient *rcc = main_channel_client_get_base(mcc); - client = main_channel_client_get_base(mcc)->client; - reds->dst_do_seamless_migrate = reds_link_mig_target_channels(client); + red_client_set_migration_seamless(rcc->client); /* linking all the channels that have been connected before migration handshake */ - reds->dst_do_seamless_migrate = reds_link_mig_target_channels(client); + reds->dst_do_seamless_migrate = reds_link_mig_target_channels(rcc->client); } return reds->dst_do_seamless_migrate; } -/* semi seamless */ -void reds_on_client_migrate_complete(RedClient *client) +void reds_on_client_seamless_migrate_complete(RedClient *client) +{ + spice_debug(NULL); + if (!reds_find_client(client)) { + spice_info("client no longer exists"); + return; + } + main_channel_migrate_dst_complete(red_client_get_main(client)); +} + +void reds_on_client_semi_seamless_migrate_complete(RedClient *client) { MainChannelClient *mcc; @@ -1649,6 +1672,7 @@ void reds_on_client_migrate_complete(RedClient *client) reds_get_mm_time() - MM_TIME_DELTA, red_dispatcher_qxl_ram_size()); reds_link_mig_target_channels(client); + main_channel_migrate_dst_complete(mcc); } static void reds_handle_other_links(RedLinkInfo *link) @@ -3202,7 +3226,7 @@ static void reds_mig_finished(int completed) if (reds->src_do_seamless_migrate && completed) { reds_migrate_channels_seamless(); } else { - main_channel_migrate_complete(reds->main_channel, completed); + main_channel_migrate_src_complete(reds->main_channel, completed); } if (completed) { @@ -4067,8 +4091,8 @@ SPICE_GNUC_VISIBLE int spice_server_migrate_connect(SpiceServer *s, const char* spice_assert(reds == s); if (reds->expect_migrate) { - spice_error("consecutive calls without migration. Canceling previous call"); - main_channel_migrate_complete(reds->main_channel, FALSE); + spice_info("consecutive calls without migration. Canceling previous call"); + main_channel_migrate_src_complete(reds->main_channel, FALSE); } sif = SPICE_CONTAINEROF(migration_interface->base.sif, SpiceMigrateInterface, base); |