used for main_dispatcher only in this patch.
Dispatcher is meant to be used for Main<->any low frequency messages.
It's interface is meant to include the red_dispatcher usage:
fixed size messages per message type
some messages require an ack
Some methods are added to be used by RedDispatcher later:
dispatcher_handle_read - to be called directly by RedDispatcher epoll
based loop
dispatcher_set_opaque - to be set from red_worker pthread
dispatcher_init - allow NULL core as used by red_worker
Read and Write behavior:
Sender: blocking write, blocking read for ack (if any).
Reader: poll for any data, if such then blocking read for a
message_type and following message. repeat until poll returns
with no pending data to read.
FDO Bugzilla: 42463
This is part of the dispatcher update, extracting the dispatcher routine
from red_dispatcher and main_dispatcher into dispatcher.
Supporting multiple async operations will make it natural to support
async monitor commands and async guest io requests that could overlap in
time.
Use a Ring for AsyncCommands.
Free Desktop Bugzilla: 42463
Related FD: 41622
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.
(cherry picked from commit b821316771 branch 0.8)
(1) not sending anything to a migrated client till we recieve SPICE_MSGC_MIGRATE_END
(2) start a new client migration (handle client_migrate_info) only after SPICE_MSGC_MIGRATE_END
from the previous migration was received for this client
(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 clients.
If the migration has completed successfully:
(1) send MSG_MAIN_MIGRATE_END to the clients that are connected to the target
(2) send MSG_MAIN_SWITCH_HOST to all the other clients
If the migration failed, send MSG_MAIN_MIGRATE_CANCEL to clients that are
connected to the target.
(cherry picked from commit 4b82580fc3 branch 0.8;
Was modified to support multiple clients, and the separation of main_channel from reds)
Conflicts:
server/reds.c
(1) send SPICE_MSG_MAIN_MIGRATE_BEGIN upon spice_server_migrate_connect
(to all the clients that support it)
(2) wait for SPICE_MSGC_MAIN_MIGRATE_(CONNECTED|CONNECT_ERROR) from all the relevant clients,
or a timeout, in order to complete client_migrate_info monitor command
(cherry picked from commit 5560c56ef0 branch 0.8;
Was modified to support the separation of main channel from reds, and multiple clients)
Conflicts:
server/reds.c
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.
(cherry picked from commit 6e56bea67c branch 0.8)
Conflicts:
server/spice.h
The code for setting and testing channel capabilities was
unnecessarily duplicated. Now it is in red_channel.
RedsChannel was dropped from Reds; It was used only for holding
the channels common capabilities, which are now held in RedChannel.
add main_dispatcher, a message passing mechanism for sending messages to
the main thread. The main thread is the thread that implements
SpiceCoreInterface, which is assumed to be a single thread.
Similar to the async operation of red_worker, a socket pair is created
and used to pass messages. The messages are a fixed size to ease
parsing. A single message is defined to pass a channel_event.
RHBZ: 746950
FDBZ: 41858
This patch is 0.8 branch only, for the master branch there should be a
better approach to share code with red_dispatcher and ready the way for
later adding more threads.
cherry-pick from 0.8 80caf07e09
Conflicts:
server/reds.c
When running some xinerama tests, I got several
glz_usr_free_image: error
messages. Looking at the code, this error is reported when this
function is called from a different DisplayChannelClient than the
one which created the glz compressed image.
When this happens, the backtrace is
at glz_encoder_dictionary.c:362
0x7fff940b6670) at glz_encoder_dictionary.c:449
image_type=LZ_IMAGE_TYPE_RGB32, image_width=512, image_height=256, image_stride=2048, first_lines=0x0,
num_first_lines=0, usr_image_context=0x7fff7420da40, image_head_dist=0x7fff9b2a3194)
at glz_encoder_dictionary.c:570
top_down=4, lines=0x0, num_lines=0, stride=2048, io_ptr=0x7fff740ea7c0 " ZL", num_io_bytes=65536, usr_context=
0x7fff7420da40, o_enc_dict_context=0x7fff7420da60) at glz_encoder.c:255
drawable=0x7fff9b46bc08, o_comp_data=0x7fff9b2a3350) at red_worker.c:5753
0x7fff9b46bc08, can_lossy=0, o_comp_data=0x7fff9b2a3350) at red_worker.c:6211
0x7fff9b46bc08, can_lossy=0) at red_worker.c:6344
0x7fff74085c50, dpi=0x7fff7445b890, src_allowed_lossy=0) at red_worker.c:7046
0x7fff7445b890) at red_worker.c:7720
at red_worker.c:7964
at red_worker.c:8431
Since the glz dictionary is shared between all the
DisplayChannelClient instances that belong to the same client, it can
happen that the glz dictionary code decides to free an image from one
thread while it was added from another thread (thread ==
DisplayChannelClient), so the error message that is printed is not an
actual error. This commit removes this message and adds a comment
explaining what's going on.
Several functions in server/ were not specifying an argument list,
ie they were declared as void foo(); When compiling with
-Wstrict-prototypes, this leads to:
test_playback.c:93:5: erreur: function declaration isn’t a prototype
[-Werror=strict-prototypes]
red_display_marshall_stream_start initializes a
SpiceMsgDisplayStreamCreate structure before marshalling it and
sending it on the wire. However, it never fills
SpiceMsgDisplayStreamCreate::stamp which then causes a complaint
from valgrind. This patch sets this value to 0, it's not used
by the client so the value shouldn't matter.
create_test_primary_surface::test_display_base.c creates a
QXLDevSurfaceCreate structure and initialize it, but doesn't set
the position field. Moreover, this structure has 4 bytes of padding
to the end (as shown by pahole from dwarves), so initialize the whole
structure to 0 before using it.
Issue found by the Coverity scanner.
HDG: Fixup don't free RGB24_line if it was not allocated by do_jpeg_encode
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
While discussing various things with Alon in Vancouver, it came up that
having a channel which simply passes through data coming out of a qemu
chardev frontend unmodified, like the usbredir channel does, can be used
for a lot of other cases too. To facilitate this the usbredir channel code
will be turned into a generic spicevmc channel, which is just a passthrough
to the client, from the spicevmc chardev.
This patch renames usbredir.c to spicevmc.c and changes the prefix of all
functions / structs to match. This should make clear that the code is not
usbredir specific.
Some examples of why having a generic spicevmc pass through is good:
1) We could add a monitor channel, allowing access to the qemu monitor from
the spice client, since the monitor is a chardev frontend we could re-use
the generic spicevmc channel server code, so all that is needed to add this
(server side) would be reserving a new channel id for this.
2) We could allow users to come up with new channels of their own, without
requiring qemu or server modification. The idea is to allow doing something
like this on the qemu startup cmdline:
-chardev spicevmc,name=generic,channelid=128
To ensure these new "generic" channels cannot conflict with newly added
official types, they must start at the SPICE_CHANNEL_USER_DEFINED_START value
(128).
These new user defined channels could then either be used with a special
modified client, with client plugins (if we add support for those), or
by exporting them on the client side for use by an external ap, see below.
3) We could also add support to the client to make user-defined channels
end in a unix socket / pipe, allowing handling of the data by an external app,
we could for example have a new spice client cmdline argument like this:
--custom-channel unixsocket=/tmp/mysocket,channelid=128
This would allow for something like:
$random app on guest -> virtio-serial -> spicevmc chardev ->
-> spicevmc channel -> unix socket -> $random app on client
4) On hind sight this could also have been used for the smartcard stuff,
with a 1 channel / reader model, rather then the current multiplexing code
where we've our own multiplexing protocol wrapper over the libcacard
smartcard protocol.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Now that the Channel struct is gone and the RedChannel has the same lifetime
as the chardev interface there is no need to have these 2 separate.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Fixes a valgrind discovered possible bug in spice-server - valgrind on
test_playback saw it, didn't see it happen with qemu.
The problem is that the frames buffers returned by spice_server_playback_get_buffer
are part of the malloc'ed SndChannel, whose lifetime is smaller then that of SndWorker.
As a result a pointer to a previously returned spice_server_playback_get_buffer could
remain and be used after SndChannel has been freed because the client disconnected.
Merging the functionality of reds::channel, into RedChannel.
In addition, cleanup and fix disconnection code: before this patch,
red_dispatcher_disconnect_display_client
could have been called from the red_worker thread
(and it must be called only from the io thread).
RedChannel holds only connected channel clients. RedClient holds all the
channel clients that were created till it is destroyed
(and then it destroys them as well).
Note: snd_channel still doesn't use red_channel, however it
creates dummy channel and channel clients, in order to register itself
in reds.
server/red_channel.c: a channel is connected if it holds at least one channel client
Previously I changed RedChannel to hold only connected channel clients and
RedClient, to hold all the channel clients as long as it is not destroyed.
usbredir: multichannel has not been tested, it just compiles.
client_cbs are supposed to be called from client context (reds). This patch will be used
in future patches for relacing reds::Channel with RedChannel in order to eliminate redundancy.
introduces ref_red_drawable and put_red_drawable (rename from free_red_drawable)
RedDrawable is already references by Drawable and RedGlzDrawable, with
a hack to NULL the drawable field in RedGlzDrawable to indicate RedGlzDrawable
is the last reference holder. Using an explicit reference count instead.
CursorPipeItems and their corresponding cursor_item were not
freed when they were removed from the pipe without sending them.
In addition cursor_channel_hold_pipe_item used wrong conversion
to (CursorItem*) for a (CursorPipeItem*).
Required to support multiple clients.
Also changes somewhat the way we produce PIPE_ITEM_TYPE_LOCAL_CURSOR. Btw,
I haven't managed to see when we actually produce such an item during my
tests.
Previously we had a single pipe item per CursorItem, this is impossible
with two pipes, which happens when we have two clients.
Also adds Drawable pipes and glz rings.
main_channel and red_worker had several locations that still accessed rcc
directly, so they had to be touched too, but the changes are minimal.
Most changes are in red_channel: drop the single client reference in RedChannel
and add a ring of channels.
Things missing / not done right in red_worker:
* StreamAgents are in DCC - right/wrong?
* GlzDict is multiplied - multiple compressions.
We still are missing:
* remove the disconnect calls on new connections
There is no inter-client shared dictionary and cache yet.
At this point the display channel can be used by multiple clients.
You can still crash on lack of Drawables or CursorItems due to the slower
clients pipe growing uncontrollably.
This patch compiles but breaks spice.
Split both display and cursor channels to a client part and channel part.
Introduce DisplayChannelClient, CursorChannelClient, CommonChannelClient.
don't disconnect channel on client disconnect.
Move all caches to the ChannelClient's.
Remove reference counting of the channel.
No new functionality introduced.
NOTE: Introduces a crash in disconnections, a regression, resulting from
incorrect thread access, that is fixed in the patch titled:
"server: registering RedChannel in reds, instead of Channel"
each client supplying a smartcard channel gets it's own smartcard. If
there are not enough smartcards provided by the server (read: qemu)
then it will be as though there are none.
currently disabled - later patches that enable smartcard don't make
this channel available to any but the first client.
s/TunnelChannel/TunnelChannelClient/
That's about it. this is probably the wrong way to do it. Not tested
at all. What do we want, a separate interface per client? same interface
for all clients? probably the later. This doesn't do that. Not tested,
so probably doesn't even work.
changes red_channel_pipe_item_is_linked to red_channel_client_pipe_item_is_linked,
since tunnel channel is the only user, must be done in patch to not break compilation.
The main channel deals with connecting new clients, announcing mouse mode
changes, and the agent channel. The implementation is currently done without
any changes to the protocol, so everything has to be either broadcast or
to a specific client.
channels list - specific client
mouse mode - broadcast
agent - broadcast
notify - broadcast (should have two modes, and use the appropriate)
Notable TODOs:
* migration testing
* agent tokens are wrongly sent (or did I fix that? check)
Introduce functions to add (via producer method) the same item to multiple
pipes, all for the same channel.
Note: Right now there is only a single channel, but the next patches will do the
per-channel breakdown to channel and channel_client before actually introducing
a ring in RedChannel, this makes it easier to make smaller changes - the
channel->rcc link will exist until removed in the ring introducing patch.
on red_channel_peer_on_incoming_error, if we are already shutdown, do not
call the channel's error handler. Since the channel has been shutdown, we
assume this is a second or later error, and handling has already occured.
Expose additional api to find a client given a connection_id. The connection_id
is first set when the first channel connects, which is the main channel.
It could also be kept in the RedClient instead, not sure.
TODO:
multiple todo's added for multiclient handling. I don't remember why
I wrote them exactly, and besides if I did any migration tests. So: TODO.
cleanup only. Note that the ping function is half used since the opt parameter
stopped being called with anything but NULL, should be returned at some point,
specifically when we drop the 250kbyte ping on start and do a continuous check
for latency and bandwidth.
See:
81945d897 - server: add new vd interface QTerm2Interface, Yaniv Kamay
introducing the usage of ping with a non NULL opt
3f7ea8e7a - zap qterm interfaces, Gerd Hoffman
removing it
They were globals before. This introduces api for other channels
to query the low bandwidth status. The queries themselves are still done
from the wrong context (channel and not channel client) but that's because
the decoupling of channel and channel client will be done in the following
patches.
Note that snd_worker.c got two copied function declarations that belong to
main_channel.h but can't be easily dragged into snd_worker.c since it still
uses it's own RedChannel struct.
Secondary channels are those that don't support multiple clients. The
support added in this patch just doesn't let the second or more connected
client receive the unsupported channels in the channels list sent by the
server to the client. This doesn't handle the situation where:
client A connects (gets all channels)
client B connects (gets supported multiple client channels)
client A disconnects (Suboptimal 1: B doesn't get new channels at this point)
client C connects (Suboptimal 2: C doesn't get the full list of channels, but
the partial one)
Specifically the channels that only support a single client are:
sound (both playback and record channels)
smartcard
tunnel
That means RedClient tracks a ring of channels. Right now there will be only
a single client because of the disconnection mechanism - whenever a new
client comes we disconnect all existing clients. But this patch adds already
a ring of clients to reds.c (stored in RedServer).
There is a known problem handling many connections and disconnections at the
same time, trigerrable easily by the following script:
export NEW_DISPLAY=:3.0
Xephyr $NEW_DISPLAY -noreset &
for ((i = 0 ; i < 5; ++i)); do
for ((j = 0 ; j < 10; ++j)); do
DISPLAY=$NEW_DISPLAY c_win7x86_qxl_tests &
done
sleep 2;
done
I fixed a few of the problems resulting from this in the same patch. This
required already introducing a few other changes:
* make sure all removal of channels happens in the main thread, for that
two additional dispatcher calls are added to remove a specific channel
client (RED_WORKER_MESSAGE_CURSOR_DISCONNECT_CLIENT and
RED_WORKER_MESSAGE_DISPLAY_DISCONNECT_CLIENT).
* change some asserts in input channel.
* make main channel disconnect not recursive
* introduce disconnect call back to red_channel_create_parser
The remaining abort is from a double free in the main channel, still can't
find it (doesn't happen when running under valgrind - probably due to the
slowness resulting from that), but is easy to see when running under gdb.
use MainChannel* instead of Channel* for a many functions in main_channel.h
(affects main_channel.c and reds.c).
some one liner fixes are hidden in here too.
Another cleanup patch, no change to behavior (still one client, and it
disconnects previous client if any).
The implementation for multiple client is straightforward: the pipe
remains per (channel,client) pair, so it needs to move from the RedChannel
that to RedChannelClient. Implementation using a single pipe with multiple
consumers (to reflect different latencies) doesn't fit well with pipe rewriting
that is used by the display channel. Additionally this approach is much simpler
to verify. Lastly it doesn't add considerable overhead (but see the display
channel changes in a later patch for a real place to rethink).
This patch is just technical, changing signatures to reflect the first
argument (oop style) so red_channel becomes red_channel_client. Some places
may seem odd but they should be fixed with later comits where the channels
grow to support multiple clients.
Sound (playback/record) channels are the only ones not touched - this is
consistent with previous patches, since they have been left out of the
RedChannel refactoring. That is left as future work. (note that they don't use
a pipe, which was the reason for not refactoring).
This commit adds a RedChannelClient that now owns the stream connection,
but still doesn't own the pipe. There is only a single RCC per RC
right now (and RC still means RedChannel, RedClient will be introduced
later). All internal api changes are in server/red_channel.h, hence
the need to update all channels. red_worker.c is affected the most because
it makes use of direct access to some of RedChannel still.
API changes:
1. red_channel_client_create added.
rec_channel_create -> (red_channel_create, red_channel_client_create)
2. two way connection: rcc->channel, channel->rcc (later channel will
hold a list, and there will be a RedClient to hold the list of channels
per client)
3. seperation of channel disconnect and channel_client_disconnect
TODO:
usbredir added untested.
The only difference between them being that the later also does a push.
I don't believe that to be a problem, but if it does I can always introduce
a push'less version.
rename types - we use _proc suffix mostly to indicate function pointer types,
use it for some function pointers that were missing it.
s/channel_handle_migrate_flush_mark/channel_handle_migrate_flush_mark_proc/
s/channel_handle_migrate_data_get_serial/channel_handle_migrate_data_get_serial_proc/
s/channel_handle_migrate_data/channel_handle_migrate_data_proc/
and spice_server_playback_put_samples. The former retrieves a buffer from a free
list with spice_server_playback_get_buffer, and should be used once via
spice_server_playback_put_samples. The tester previously reused the same buffer
a number of times.
After the changes to add libjpeg-turbo support to spice-server mjpeg
compression code, it's relatively easy to hit an assertion from
libjpeg in spice-server about "too few scanlines transferred" when
the mjpeg streaming code triggers. This assertion brings down qemu,
which is bad :)
This is because when we first initialize the mjpeg encoder, we do:
stream_width = SPICE_ALIGN(src_rect->right - src_rect->left, 2);
stream_height = SPICE_ALIGN(src_rect->bottom - src_rect->top, 2);
stream->mjpeg_encoder = mjpeg_encoder_new(stream_width, stream_height);
and then when we iterate over the image scanlines to feed them to
libjpeg, we do:
const int image_height = src->bottom - src->top;
const int image_width = src->right - src->left;
for (i = 0; i < image_height; i++) {
mjpeg_encoder_encode_scanline(...);
}
mjpeg_encoder_end_frame(...);
When stream_height is odd, the mjpeg_encoder will be created with
an height that is 1 more than the number of lines we encode. Then
libjpeg asserts when we tell it we're done with the compression
while it's still waiting for one more scanline.
Looking through git history, this rounding seems to be an artifact
from when we were using ffmpeg for the mjpeg encoding. Since
spicec and spicy (the latter needs a few fixes) can handle streams
with odd height/width, the best way to solve this issue is to stop
rounding up the height and width of the streams we create. This
even saves some bandwidth :)
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.
It is a bit early to bump, since a 0.9.1 release is not happening yet,
but this allows me to test if the vdagent SpiceCharInterface state callback
fixes are present or not in qemu code, and thus disabling the ugly vdagent
specific workaround from spice-qemu-char.c when compiling against a new
enough spice-server.
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.
It's not used when we use jpeg-turbo colorspaces, so it's better
to allocate it when we know we'll need it rather than always
allocating it even if it won't be used.
After the refactoring to optionally use libjpeg-turbo, some
of the functions that mjpeg-encoder used to provide are now no
longer used. This commit removes them.
When libjpeg-turbo is available, we can use the BGR and BGRX
colorspaces that it provides to avoid extra conversions of the
data we want to compress to mjpeg
The main point is to move the pixel conversion code into
the MjpegEncoder class to be able to make use libjpeg-turbo
additional pixel formats without the reds_worker code noticing.
This API is meant to allow us to move the pixel format conversion
into MjpegEncoder. This will allow us to be able to use the
additional pixel formats from libjpeg-turbo when available.
It takes a lot of arguments, "id" is unused, "frame" and
"frame_size" can be obtained from the "stream" argument, so
can get rid of 3 arguments to make things more readable.