client migration: switch host

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@redhat.com>
This commit is contained in:
Gerd Hoffmann 2010-12-13 23:08:57 +01:00
parent 5d2aa8084e
commit 4b1ea4e102
2 changed files with 59 additions and 11 deletions

View File

@ -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;
}

View File

@ -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__