mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2025-12-26 22:48:19 +00:00
client: support semi-seamless migration between spice servers with different protocols.
It can't actually happen right now, since switch-host migration scheme will take place if the src/target server has protocol 1.
This commit is contained in:
parent
010b22cd77
commit
4b2bf4d88c
@ -295,6 +295,20 @@ bool RedChannelBase::test_capability(uint32_t cap)
|
||||
return test_capability(_remote_caps, cap);
|
||||
}
|
||||
|
||||
void RedChannelBase::swap(RedChannelBase* other)
|
||||
{
|
||||
int tmp_ver;
|
||||
|
||||
RedPeer::swap(other);
|
||||
tmp_ver = _remote_major;
|
||||
_remote_major = other->_remote_major;
|
||||
other->_remote_major = tmp_ver;
|
||||
|
||||
tmp_ver = _remote_minor;
|
||||
_remote_minor = other->_remote_minor;
|
||||
other->_remote_minor = tmp_ver;
|
||||
}
|
||||
|
||||
SendTrigger::SendTrigger(RedChannel& channel)
|
||||
: _channel (channel)
|
||||
{
|
||||
@ -490,6 +504,12 @@ void RedChannel::do_migration_disconnect_src()
|
||||
void RedChannel::do_migration_connect_target()
|
||||
{
|
||||
LOG_INFO("");
|
||||
ASSERT(get_client().get_protocol() != 0);
|
||||
if (get_client().get_protocol() == 1) {
|
||||
_marshallers = spice_message_marshallers_get1();
|
||||
} else {
|
||||
_marshallers = spice_message_marshallers_get();
|
||||
}
|
||||
_loop.add_socket(*this);
|
||||
_socket_in_loop = true;
|
||||
on_connect_mig_target();
|
||||
|
||||
@ -66,6 +66,8 @@ public:
|
||||
uint32_t get_peer_major() { return _remote_major;}
|
||||
uint32_t get_peer_minor() { return _remote_minor;}
|
||||
|
||||
virtual void swap(RedChannelBase* other);
|
||||
|
||||
protected:
|
||||
void set_common_capability(uint32_t cap);
|
||||
void set_capability(uint32_t cap);
|
||||
|
||||
@ -133,6 +133,7 @@ Migrate::Migrate(RedClient& client)
|
||||
, _connected (false)
|
||||
, _thread (NULL)
|
||||
, _pending_con (0)
|
||||
, _protocol (0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -189,7 +190,7 @@ void Migrate::swap_peer(RedChannelBase& other)
|
||||
curr->set_valid(false);
|
||||
if (!--_pending_con) {
|
||||
lock.unlock();
|
||||
_client.set_target(_host.c_str(), _port, _sport);
|
||||
_client.set_target(_host.c_str(), _port, _sport, _protocol);
|
||||
abort();
|
||||
}
|
||||
return;
|
||||
@ -212,6 +213,13 @@ void Migrate::connect_one(MigChannel& channel, const RedPeer::ConnectionOptions&
|
||||
channel.connect(options, connection_id, _host.c_str(), _password);
|
||||
++_pending_con;
|
||||
channel.set_valid(true);
|
||||
if (_protocol == 0) {
|
||||
if (channel.get_peer_major() == 1) {
|
||||
_protocol = 1;
|
||||
} else {
|
||||
_protocol = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Migrate::run()
|
||||
@ -232,7 +240,7 @@ void Migrate::run()
|
||||
for (++iter; iter != _channels.end(); ++iter) {
|
||||
conn_type = _client.get_connection_options((*iter)->get_type());
|
||||
con_opt = RedPeer::ConnectionOptions(conn_type, _port, _sport,
|
||||
_client.get_protocol(),
|
||||
_protocol,
|
||||
_auth_options, _con_ciphers);
|
||||
connect_one(**iter, con_opt, connection_id);
|
||||
}
|
||||
@ -440,11 +448,16 @@ RedClient::~RedClient()
|
||||
delete[] _agent_caps;
|
||||
}
|
||||
|
||||
void RedClient::set_target(const std::string& host, int port, int sport)
|
||||
void RedClient::set_target(const std::string& host, int port, int sport, int protocol)
|
||||
{
|
||||
if (protocol != get_protocol()) {
|
||||
LOG_INFO("old protocol %d, new protocol %d", get_protocol(), protocol);
|
||||
}
|
||||
|
||||
_port = port;
|
||||
_sport = sport;
|
||||
_host.assign(host);
|
||||
set_protocol(protocol);
|
||||
}
|
||||
|
||||
void RedClient::push_event(Event* event)
|
||||
@ -679,10 +692,8 @@ void RedClient::on_channel_disconnect_mig_src_completed(RedChannel& channel)
|
||||
_pixmap_cache.clear();
|
||||
_glz_window.clear();
|
||||
memset(_sync_info, 0, sizeof(_sync_info));
|
||||
|
||||
LOG_INFO("calling main to connect and wait for handle_init to tell all the other channels to connect");
|
||||
RedChannel::connect_migration_target();
|
||||
|
||||
AutoRef<MigrateEndEvent> mig_end_event(new MigrateEndEvent());
|
||||
get_process_loop().push_event(*mig_end_event);
|
||||
}
|
||||
|
||||
@ -82,6 +82,7 @@ private:
|
||||
Mutex _lock;
|
||||
Condition _cond;
|
||||
int _pending_con;
|
||||
int _protocol;
|
||||
};
|
||||
|
||||
class ChannelFactory {
|
||||
@ -238,7 +239,7 @@ public:
|
||||
void activate_interval_timer(Timer* timer, unsigned int millisec);
|
||||
void deactivate_interval_timer(Timer* timer);
|
||||
|
||||
void set_target(const std::string& host, int port, int sport);
|
||||
void set_target(const std::string& host, int port, int sport, int protocol = 0);
|
||||
void set_password(const std::string& password) { _password = password;}
|
||||
void set_auto_display_res(bool auto_display_res) { _auto_display_res = auto_display_res;}
|
||||
void set_display_setting(DisplaySetting& setting) { _display_setting = setting;}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user