We will add a qemu call to spice_server_migrate_start when migration starts.
For now, it does nothing, but we may need this notification in the future.
(1) not sending anything to the client till we recieve SPICE_MSGC_MIGRATE_END
(2) start a new migration (handle client_migrate_info) only after SPICE_MSGC_MIGRATE_END
from the previous migration has been received
(3) use the correct ticket
Note: we assume the same channles are linked before and ater migration. i.e.,
SPICE_MSGC_MAIN_ATTACH_CHANNELS is not sent from the client.
(1) send SPICE_MSG_MAIN_MIGRATE_BEGIN upon spice_server_migrate_connect
(2) wait for SPICE_MSGC_MAIN_MIGRATE_(CONNECTED|CONNECT_ERROR), or a timeout, in order
to complete client_migrate_info monitor command
semi-seamless migration details:
migration source side
---------------------
(1) spice_server_migrate_connect (*): tell client to link
to the target side - send SPICE_MSG_MAIN_MIGRATE_BEGIN.
This should be called upon client_migrate_info cmd.
client_migrate_info is asynchronous.
(2) Complete spice_server_migrate_connect only when the client has been connected
to the target - wait for SPICE_MSGC_MAIN_MIGRATE_(CONNECTED|CONNECT_ERROR) or a timeout.
(3) spice_server_migrate_end: tell client migration it can switch to the target - send
SPICE_MSG_MAIN_MIGRATE_END.
(4) client cleans up all data related to the connection to the source and switches to the target.
It sends SPICE_MSGC_MAIN_MIGRATE_END.
migration target side
---------------------
(1) the server identifies itself as a migraiton target since the client is linked with (connection_id != 0)
(2) server doesn't start the channels' logic (channel->link) till it receives SPICE_MSGC_MAIN_MIGRATE_END
from the client.
* After migration starts, the target qemu is blocked and cannot accept new spice client
connections. Thus, we trigger the connection to the target upon client_migrate_info
command.
In a Xinerama setup, when X starts up and creates one of the
secondary screens, first a non-primary surface is created on the
secondary screen, and then the primary surface for this screen is
created.
This causes a crash when the guest uses Xinerama and the client
is attached to the VM before X starts (ie while the guest is
booting).
This happens because DisplayChannel::create_canvas (which is called
when creating a non-primary surface) assumes a screen has already been
set for the DisplayChannel while this only happens upon primary surface
creation. However, it uses the screen for non important stuff, so we
can test if screen() is non NULL before using it. This is what is done
in other parts of this file.
Fixes rhbz #732423
After hours of investigation, I am a bit clueless.. It seems XRR is sending
us spurious ScreenChangeNotify in a loop. So we keep calling
init_monitors(), which creates new platform_win etc.. Although none of the
clients seems to be resetting the screen (checked all XRRSet..). The fact
that we create many platform_win looks like a bug to me, and indeed, it
seems to help if we reuse the same platform_win over the various
init_monitors() calls.
Fixes rhbz #692833
Even if VDAgentDisplayConfig::depth will be unused if the
VD_AGENT_DISPLAY_CONFIG_FLAG_SET_COLOR_DEPTH isn't set, it's
better to initialize it anyway to avoid warnings from valgrind.
They were trying to convert the destination pointer to an integer before
trying to dereference it. The initial conversion was meant to be a cast
to a pointer of the right size, not to an integer.
It was sending the wrong data, the memory right after the VCSMsgHeader
which was actually not where the data was.
Fixed by having the header and data (VSCError, 4 bytes of the error code)
embedded in the ErrorItem pipe item.
when changing resolutions due to the new async code paths the surface
creation command was kept by reference, and later, when the red_worker
signaled completion by calling async_complete the mouse mode was updated
using the reference. This caused the wrong values to be read resulting in wrong
resolutions set and a non working mouse pointer. Fix this by keeping a copy of
the surface creation command instead of a reference.
No bz. Found in testing.
Changelog from Arnon Gilboa, patch from me:
Commit eb6f554094 caused the following regression:
When client runs without the auto-conf or disable-effects options
(either from CLI or controller), which is the case when using Spice
from Admin Portal, the client will unecessarily wait for 30sec before
connecting to a Windows guest with an agent running (this won't happen
with linux guests or without an agent running).
The mentioned patch assumed that on_agent_reply() of
VD_AGENT_DISPLAY_CONFIG will call send_main_attach_channels() and
connect. However, when auto-conf or disable-effects are not used,
on_agent_reply() will ignore the reply and not call
send_main_attach_channels(). Therefore, send_main_attach_channels()
will only be called on agent timeout.
The solution is to activate agent timer only if auto-conf or
disable-effects. Otherwise, simply call send_main_attach_channels().
Fixes rhbz #726441
On migration, destroy_surfaces is called from qxl (qxl_hard_reset), before the device was loaded (on destination).
handle_dev_destroy_surfaces led to red_process_commands, which read the qxl command ring
(which appeared to be not empty), and then when processing the command
it accessed unmapped memory.
When the client connects to a spice VM, if an agent is detected,
there will be a few messages exchanged to exchange capabilities,
display resolutions, ... This exchange has a timeout in case
something goes wrong. However, when it fires, the client dies.
This commit changes this and lets the client connects to the
guest when the timeout happens.
rhbz #673973
492f7a9b fixed unwanted timeouts during initial client startup,
but it also caused a bad regression when connecting to
RHEL6+agent guests: the SPICE_MSGS_MAIN_ATTACH_CHANNELS message
was sent multiple times, once in RedClient::handle_init, then
once again in RedClient::on_agent_announce_capabilities (which
can even be triggered multiple times). Sending this message multiple
times is a big NO and causes the server to close the client connection,
and the client to die. Add a _msg_attach_message_sent boolean to
make sure we only send this message once.
rhbz #712938
I changed RedScreen::resize not to call rearrange_monitors. Instead,
the monitor should be configured correctly from Application, before
calling resize.
In addition, I made some cleanups to allow reusing rearrange_monitors code.
This does the following, all to remove any referenced memory on the pci bars:
flush_all_qxl_commands(worker);
flush_all_surfaces(worker);
red_wait_outgoing_item((RedChannel *)worker->display_channel);
red_wait_outgoing_item((RedChannel *)worker->cursor_channel);
The added api is specifically async, i.e. it calls async_complete
when done.
(cherry picked from commit 2a4d97fb78)
The new _ASYNC io's in qxl_dev listed at the end get six new api
functions, and an additional callback function "async_complete". When
the async version of a specific io is used, completion is notified by
calling async_complete, and no READY message is written or expected by
the dispatcher.
update_area has been changed to push QXLRects to the worker thread, where
the conversion to SpiceRect takes place.
A cookie has been added to each async call to QXLWorker, and is passed back via
async_complete.
Added api:
QXLWorker:
update_area_async
add_memslot_async
destroy_surfaces_async
destroy_primary_surface_async
create_primary_surface_async
destroy_surface_wait_async
QXLInterface:
async_complete
(cherry picked from commit 096f49afbf)
In addition (1) make handle_dev_destroy_surfaces call red_release_cursor
(2) call red_wait_outgoing_item(cursor_channel) only after adding msgs to pipe
[3d3066b175 cherry-pick with modifications]
In C, the latter isn't a prototype for a function with no arg,
but declares a function with an undefined number of args.
[picked from master with changes since no main_channel, spice_common,
and a bunch of functions aren't there yet]
For each callback in QXLWorker, for example QXLWorker::update_area, add
a direct call named spice_qxl_update_area.
This will (a) remove the pointless indirection and (b) make shared
library versioning alot easier as we'll get new linker symbols which
we can tag with the version they appeared in the shared library.
[cherry-picked from master]
Both connect_secure() and connect_unsecure() call connect_to_peer().
Prior to this commit spicec.log reported all connections as unsecure,
as connect_secure() called connect_unsecure() to make the connection.
This fixes RH bug #653545
When qemu creates a channel, reds.c contains code to check the
minor/major channel versions known to QEMU (ie the ones that were
current in spice-server when QEMU was compiled) and to compare these
versions against the current ones the currently installed spice-server
version.
According to kraxel [1], the rules for these interface numbers are:
"The purpose of the versions is exactly to avoid the need for a new
soname. The rules are basically:
(1) You add stuff to the interface, strictly append-only to not break
binary compatibility.
(2) You bump the minor version of the interface.
(3) You check the minor version at runtime to figure whenever the
added fields contain valid stuff or not.
An example is here (core interface, minor goes from 2 to 3, new
channel_event callback):
http://cgit.freedesktop.org/spice/spice/commit/?id=97f33fa86aa6edd25111b173dc0d9599ac29f879
"
The code currently refuses to create a channel if QEMU minor version is
less than the current spice-server version. This does not correspond
to the intended behaviour, this patch changes to fail is qemu was compiled
with a spice-server that is *newer* than the one currently installed. This
case is something we cannot support nicely.
[1] http://lists.freedesktop.org/archives/spice-devel/2011-July/004440.html
If you try to connect to a linux guest with WAN options, SPICE window opens up
and is blank - it then fails with vdagent timeout message. It should give a
warning that this is only applicable for windows guest and still connect to
guest.
It all starts in RedClient::handle_init
This function checks whether we have an agent or not, because if we have an
agent, there will be some kind of handshake to check both sides capabilities
before all the spice channels are created.
When there is no agent running, the startup process goes on with
SPICE_MSGC_MAIN_ATTACH_CHANNELS
When there is a windows agent running, VD_AGENT_ANNOUNCE_CAPABILITIES and
VD_AGENT_DISPLAY_CONFIG messages are sent to the agent, and when processing the
agent answer to the VD_AGENT_DISPLAY_CONFIG message,
SPICE_MSGC_MAIN_ATTACH_CHANNELS will be sent and the startup process will go
on.
However, when there is no agent running but --color-depth was used, handle_init
won't send the SPICE_MSGC_MAIN_ATTACH_CHANNELS message but will wait for the
agent handshake to proceed to its end, which won't happen, so it will timeout
waiting for agent answers.
Similarly, the linux agent handles VD_AGENT_ANNOUNCE_CAPABILITIES messages, but
it doesn't handle VD_AGENT_DISPLAY_CONFIG messages, so we'll never reach the
point where a SPICE_MSGC_MAIN_ATTACH_CHANNELS will be sent.
This commit fixes this in 2 places:
- unconditionnally send SPICE_MSGC_ATTACH_CHANNELS when no agent is running in
handle_init
- send SPICE_MSGC_MAIN_ATTACH_CHANNELS in
RedClient::on_agent_announce_capabilities if the agent doesn't have the
VD_AGENT_CAP_DISPLAY_CONFIG capability
This fixes RH bug #712938
The WAN options (--color-depth and --disable-effects) need
support from the guest agent to be working. Currently they are
only supported on Windows. While I don't want to explicitly
mention Windows in --help output, we can hint that it won't
work with all guests in --help. This fixes RH bug #712941
There is a double free in client/x11/platform.cpp.
In get_selection(), in the exit: case with ret_val == -1 and data != NULL,
*data_ret (which is returned to the caller) has already been
assigned "data", so it will be pointing to freed memory when "data" is
XFree'd'. Then in handle_selection_notify, get_selection_free is called on
this pointer, which causes a double free.
When the length of the read data = 0, set the returned value to NULL,
this way subsequent free attempts will be a noop.
Fixes RH bug #710461