Commit Graph

960 Commits

Author SHA1 Message Date
Yonit Halperin
b0fb03f0ae server/red_worker: enable latency monitoring in the display channel 2013-04-22 16:30:54 -04:00
Yonit Halperin
86fbcf1ddb red_worker: stream - update periodically the input frame rate
Periodically calculate the rate of frames arriving from the guest to the
server.
2013-04-22 16:30:54 -04:00
Yonit Halperin
9a62a9a809 red_channel: monitor connection latency using MSG_PING 2013-04-22 16:30:54 -04:00
Yonit Halperin
d146ae0d92 server/red_worker: assign timer callbacks to worker_core, using spice_timer_queue
display channel - supplying timeouts interface to red_channel, in order to allow
periodic latency monitoring (see next patch).
2013-04-22 16:30:54 -04:00
Yonit Halperin
e3bc219570 server: spice_timer_queue
Each thread can create a spice_timer_queue, for managing its
own timers.
2013-04-22 16:30:54 -04:00
Yonit Halperin
622d7159c2 mjpeg_encoder: add stream warmup time, in which we avoid server and client drops
The stream starts after lossless frames were sent to the client,
and without rate control (except for pipe congestion). Thus, on the beginning
of the stream, we might observe frame drops on the client and server side which
are not necessarily related to mis-estimation of the bit rate, and we would
like to wait till the stream stabilizes.
2013-04-22 16:30:53 -04:00
Yonit Halperin
ff1bde1d81 mjpeg_encoder: keep the average observed fps similar to the defined fps
The actual frames distribution does not necessarily fit the
condition "at least one frame every (1000/rate_contorl->fps)
milliseconds".
For keeping the average frame rate close to the defined fps, we
periodically measure the current average fps, and modify
rate_control->adjusted_fps accordingly. Then, we use
(1000/rate_control->adjusted_fps) as the interval between the
frames.
2013-04-22 16:30:53 -04:00
Yonit Halperin
6f883d0eb5 mjpeg_encoder: move the control over frame drops to mjpeg_encoder 2013-04-22 16:30:53 -04:00
Yonit Halperin
44ce87b55a mjpeg_encoder: update the client with estimations for the required playback latency
The required client playback latency is assessed based on the current
estimation of the bit rate, the network latency, and the encoding size
of the frames. When the playback delay that is reported by the client
seems too small, or when the stream parameters change, we send the
client an updated playback latency estimation.
2013-04-22 16:30:53 -04:00
Yonit Halperin
3bbde4b3a6 mjpeg_encoder: modify stream bit rate based on server side pipe congestion
Downgrading stream bit rate when the input frame rate in the server
exceeds the output frame rate, and frames are being dropped from the
output pipe.
2013-04-22 16:30:53 -04:00
Yonit Halperin
b490635130 mjpeg_encoder: adjust the stream bit rate based on periodic client feedback
mjpeg_encoder can receive periodic reports about the playback status on
the client side. Then, mjpeg_encoder analyses the report and can
increase or decrease the stream bit rate, depending on the report.
When the bit rate is changed, the quality and frame rate of the stream
are re-evaluated.
2013-04-22 16:30:51 -04:00
Yonit Halperin
2025494af5 mjpeg_encoder: re-configure stream parameters when the frame's encoding size changes
If the encoding size seems to get smaller/bigger, re-evaluate the
stream quality and frame rate.
2013-04-22 11:45:59 -04:00
Yonit Halperin
f68b539d70 mjpeg_encoder: configure mjpeg quality and frame rate according to a given bit rate
Previously, the mjpeg quality was always 70. The frame rate was
tuned according to the frames' congestion in the pipe.
This patch sets the quality and frame rate according to
a given bit rate and the size of the first encoded frames.

The following patches will introduce an adaptive video streaming, in which
the bit rate, the quality, and the frame rate, change in response to
different parameters.

Patches that make red_worker adopt this feature will also follow.
2013-04-22 11:45:59 -04:00
Yonit Halperin
41d7400758 server/red_worker: streams: moving mjpeg_encoder from Stream to StreamAgent
The mjpeg_encoder should be client specific, and not shared between
different clients**, for the following reasons:
(1) Since we use abbreviated jpeg datastream for mjpeg, employing the same
    mjpeg_encoder for different clients might cause errors when the
    clients decode the jpeg data.
(2) The next patch introduces bit rate control to the mjpeg_encoder.
    This feature depends on the bandwidth available, which is client
    specific.

** at least till we change multi-clients not to re-encode the same
   streams.
2013-04-22 11:45:58 -04:00
Yonit Halperin
317471fc0b red_worker: stream agent - fix miscounting of frames
Frames counting was skipped when the previous frame was already
sent completely to the client.
2013-04-22 11:45:58 -04:00
Hans de Goede
38999db39b snd_worker: Make sure we never send an empty volume message
My commit 71315b2e "snd_worker: Don't send empty audio-volume messages",
fixes only one case of sending an empty volume message, if the client connects
to a vm early during its boot sequence, while the snd hardware is being reset
by the guest driver, qemu will call spice_server_playback_set_volume() with
0 channels from the reset handler.

This patch also applies both fixes to the record channel.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2013-04-19 13:57:31 +02:00
Yonit Halperin
c7e8198091 red_worker.c: fix not destroying streams before sending MSG_MIGRATE
When qemu migration completes, we need to stop the streams, and to send
the corresponding upgrade_items to the client.
Otherwise, (1) the client might display lossy regions that we don't track
(streams are not part of the migration data).
(2) streams_timeout may occur after MSG_MIGRATE has been sent, leading
to messages being sent to the client after MSG_MIGRATE and before
MSG_MIGRATE_DATA (e.g., STREAM_CLIP, STREAM_DESTROY, DRAW_COPY).
No message besides MSG_MIGRATE_DATA should be sent after
MSG_MIGRATE.

When a msg other than MIGRATE_DATA reached spice-gtk after MSG_MIGRATE,
spice-gtk sent it to dest server as the migration data, and the dest
server crashed with a "bad message size" assert.
2013-04-08 16:16:05 -04:00
Yonit Halperin
21123f34e7 red_worker.c: s/red_display_destroy_streams/red_display_destroy_streams_agents
In order not to confuse it with red_destroy_streams in the following
patch.
2013-04-08 16:15:27 -04:00
Hans de Goede
71315b2e09 snd_worker: Don't send empty audio-volume messages
If no volume has been set it, we end up sending a volume message with
audio-volume for 0 channels (iow an empty message). This is not useful
and triggers the following warning in spice-gtk:

(remote-viewer:8726): GSpice-WARNING **: set_sink_input_volume() failed:
Invalid argument

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2013-04-01 22:10:55 +02:00
Hans de Goede
baa7cab700 char_device: Don't set active when stopped and don't access dev after unref
2 closely related changes in one:
1) When leaving the read or write loop because the chardev has been stopped
active should not be updated. It has been set to FALSE by
spice_char_device_stop and should stay FALSE
2) The updating of dev->active should be done *before* unref-ing dev

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2013-03-29 10:07:26 +01:00
Hans de Goede
3d775594b5 char_device: Don't set the write-retry timer when not running
The write-retry timer should not be set when we're leaving
spice_char_device_write_to_device because the char-dev has been stopped.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2013-03-29 10:05:24 +01:00
Hans de Goede
e3c6f793f7 char_device: Properly update buffer status when leaving the write loop on stop
Before this patch the write-loop in spice_char_device_write_to_device would
break on running becoming 0, after having written some data, without updating
the buffer status, causing the same data to be written *again* when started.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2013-03-29 10:05:11 +01:00
Hans de Goede
25f84a2d6e inputs-channel: Don't send insecure keyb notify to in migrate client
This fixes spice-gtk printing message like these on migration:
(remote-viewer:18402): GSpice-CRITICAL **: spice_channel_iterate_read: assertion `c->state != SPICE_CHANNEL_STATE_MIGRATING' failed

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2013-03-15 09:44:50 +01:00
Hans de Goede
8d44aa0328 inputs-channel: Handle printing of insecure keyboard notify
This is clearly something which should be handled in the inputs_channel code,
rather then having a special case for it in the generic channel handling
code in reds.c. Moving it here also fixes the TODO we had on only sending
this message to new clients.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2013-03-15 09:44:50 +01:00
Hans de Goede
0711a4a464 main-channel: Add a main_channel_client_push_notify function
Sometimes we want to send a notify to a single client, rather then to
all of them.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2013-03-15 09:44:50 +01:00
Hans de Goede
3a2f42555d main-channel: Make main_channel_push_notify deal with dynamic memory
Currently main_channel_push_notify only gets passed a static string, but
chances are in the future it may get passed dynamically allocated strings,
prepare it for this.

While at it also make clear that its argument is a string, and simplify
things a bit by making use of this knowledge (pushing the strlen call down).

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2013-03-15 09:44:26 +01:00
Hans de Goede
89d2a68cb7 server/reds: Send the agent a CLIENT_DISCONNECTED msg on client disconnect
Client -> agent messages can spawn multiple VDIChunks. When this happens
the agent re-assembles the chunks into a complete VDAgentMessage before
processing it. The server only guarentees coherency at the chunk level,
so it is not possible for a partial chunk to get delivered to the agent.

But it is possible for some chunks of a VDAgentMessage to be delivered to
the agent followed by a client to disconnect without the rest of the
VDAgentMessage being delivered!

This will leave the agent in a wrong state, and the first messages send to it
by the next client to connect will get seen as the rest of the VDAgentMessage
from the previous client.

This patch sends the agent a new VD_AGENT_CLIENT_DISCONNECTED message from the
VDP_SERVER_PORT, on which the agent can then reset its VDP_CLIENT_PORT state.

Note that no capability check is done for this, since the capabilities are
something negotiated between client and agent. The server will simply always
send this message on client disconnect, relying on older agents discarding the
message since it has an unknown type (which both the windows and linux agents
already do).

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2013-03-07 11:52:23 +01:00
Hans de Goede
4476c99452 char_device: Add spice_char_device_write_buffer_get_server_no_token()
To allow the server to send agent messages without needing to wait for a
self-token. IE for sending VD_AGENT_CLIENT_DISCONNECTED messages.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2013-03-07 11:52:23 +01:00
Hans de Goede
b42f2e1fc9 Silence __spice_char_device_write_buffer_get: internal buf is not available
These messages are printed when the server tries to push a mouse event to
the agent before the previous one has been flushed. This is a normal condition
(which gets tracked by the reds->pending_mouse_event boolean), and as such
it should *not* trigger the printing of error messages.

I've seen these messages occasionally before, but with agent file-xfer they
are trivial to trigger, simply send a large file to the agent and while it
is transferring move the mouse over the client window. Note that due to the
client tokens not allowing the client to completely saturate the agent
channel mouse events do still get send to the agent, just with a slightly
larger interval. So everything is working as designed and this spice_printerr
is just leading to people chasing ghosts.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2013-03-04 16:35:54 +01:00
Hans de Goede
50efe1e48d worker_update_monitors_config: Drop bogus real_count accounting
1) This does not buy us much, as red_marshall_monitors_config() also
   removes 0x0 sized monitors and does a much better job at it
   (also removing intermediate ones, not only tailing ones)
2) The code is wrong, as it allocs space for real_count heads, where
   real_count always <= monitors_config->count and then stores
   monitors_config->count in worker->monitors_config->count, causing
   red_marshall_monitors_config to potentially walk
   worker->monitors_config->heads past its boundaries.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2013-01-15 14:30:59 +01:00
Hans de Goede
d2e1f939fe server: Fix SpiceWorker-CRITICAL **: red_worker.c:10968:red_push_monitors_config: condition `monitors_config != NULL' failed
During my dynamic monitor support testing today, I hit the following assert
in red_worker.c:
"red_push_monitors_config: condition `monitors_config != NULL' failed"

This is caused by the following scenario:
1) Guest causes handle_dev_monitors_config_async() to be called
2) handle_dev_monitors_config_async() calls worker_update_monitors_config()
3) handle_dev_monitors_config_async() pushes worker->monitors_config, this
   takes a ref on the current monitors_config
4) Guest causes handle_dev_monitors_config_async() to be called *again*
5) handle_dev_monitors_config_async() calls worker_update_monitors_config()
6) worker_update_monitors_config() does a decref on worker->monitors_config,
   releasing the workers reference, this monitor_config from step 2 is
   not yet free-ed though as the pipe-item still holds a ref
7) worker_update_monitors_config() creates a new monitors_config with an
   initial ref-count of 1 and stores that in worker->monitors_config
8) The pipe-item of the *first* monitors_config is send, upon completion
   a decref is done on the monitors_config, and monitors_config_decref not
   only frees the monitor_config, but *also* sets worker->monitors_config
   to NULL, even though worker->monitors_config no longer refers to the
   monitor_config being freed, it refers to the 2nd monitor_config!
9) The client which was connected when this all happened disconnects
10) A new client connects, leading to the assert:
    at red_worker.c:9519
    num_common_caps=1, common_caps=0x5555569b6f60, migrate=0,
    stream=<optimized out>, client=<optimized out>, worker=<optimized out>)
    at red_worker.c:10423
    at red_worker.c:11301

Note that red_worker.c:9519 is:
        red_push_monitors_config(dcc);
gdb does not point to the actual line of the assert because the function gets
inlined.

The fix is easy and obvious, don't set worker->monitors_config to NULL in
monitors_config_decref. I'm a bit baffled as to why that code is there in
the first place, the whole point of ref-counting is to not have one single
unique place to store the reference...

This fix should not have any adverse side-effects as the 4 callers of
monitors_config_decref fall into 2 categories:
1) Code which immediately after the decref replaces worker->monitors_config
   with a new monitors_config:
   worker_update_monitors_config()
   set_monitors_config_to_primary()
2) pipe-item freeing code, which should not touch the worker state at all
   to being with

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2013-01-15 14:30:59 +01:00
Michael Tokarev
cf8ebbc484 link libspice server with libm libpthread
server/Makefile apparently forgot to link libspice-server
with -lm -lpthread, but it uses symbols from these libraries
directly.  These libs are detected by configure and stored in
$(SPICE_NONPKGCONFIG_LIBS) make variable, but this variable
is never referenced at link time.  Add it to server/Makefile.am,
to libspice_server_la_LIBADD variable.

Signed-off-By: Michael Tokarev <mjt@tls.msk.ru>
2013-01-14 18:54:22 +02:00
Yonit Halperin
4eb172f6fe red_worker.c: clearing the stream vis_region, after it has been detached
The stream vis_region should be cleared after the stream region was sent
to the client losslessly. Otherwise, we might send redundant stream upgrades
if we process more drawables that are dependent on the stream region.
2013-01-08 10:51:26 -05:00
Yonit Halperin
b22e82ad57 red_worker.c: insert a drawable to its position in the current tree before calling red_detach_streams_behind
resolves: rhbz#891326

Starting from commit 81fe00b08a, red_detach_streams_behind can
trigger modifications in the current tree (by update_area calls). Thus,
after calling red_detach_streams_behind it is not safe to access tree
entries that were calculated before the call.
This patch inserts the drawable to the tree before the call to
red_detach_streams_behind. This change also requires making sure
that rendering operations that can be triggered by
red_detach_streams_behind will not include this drawable (which is now part of the tree).
2013-01-08 10:47:53 -05:00
Uri Lublin
1ff4234162 server: guest_set_client_capabilities: protect against NULL worker->display_channel
Reported-by: Michal Luscon <mluscon@redhat.com>

Found by a Coverity scan:
  in handle_dev_start -
    Checking "worker->display_channel" implies that "worker->display_channel"
	         might be NULL.
    Passing "worker" to function "guest_set_client_capabilities"
  in guest_set_client_capabilities -
    Directly dereferencing parameter "worker->display_channel"
2013-01-01 12:37:11 +02:00
Hans de Goede
55ebd0a1c0 Release 0.12.2 2012-12-20 20:39:54 +01:00
Yonit Halperin
812b65984d red_parse_qxl: fix throwing away drawables that have masks
Non rgb bitmaps are allowed to not have a palette in case they
are masks (which are 1BIT bitmaps).

Related: rhbz#864982
2012-12-20 10:13:09 -05:00
Christophe Fergeau
07ee267455 reds: Use g_strlcpy instead of strncpy
reds.c is using strncpy with a length one byte less than the
destination buffer size, and is relying on the fact that the
destination buffers are static global variables.
Now that we depend on glib, we can use g_strlcpy instead, which
avoids relying on such a subtle trick to get a nul-terminated
string.
2012-12-12 18:15:48 +01:00
Christophe Fergeau
55495a61bf build: Use glib2
Now that QEMU depends on glib, it won't really hurt if we depend
on it as well, and we won't have to reinvent our own helpers.
2012-12-12 18:15:48 +01:00
Christophe Fergeau
5a31221252 Fail reds_init_socket when getaddrinfo fails
We currently output a warning when getaddrinfo fails, but then
we go on trying to use the information it couldn't read. Make
sure we bail out of reds_init_socket if getaddrinfo fails.
2012-12-12 18:15:47 +01:00
Christophe Fergeau
0b1d268011 Make sure strncpy'ed string are 0-terminated
spice_server_set_ticket and spice_server_set_addr get (library)
user-provided strings as arguments, and copy them to fixed-size
buffers using strncpy. However, if these strings are too long,
the copied string will not be 0-terminated, which will cause issues
later. This commit copies one byte less than the size of the
destination buffer. In both cases, this buffer is a static global
variable, so its memory will be set to 0.
2012-12-12 18:15:47 +01:00
Yonit Halperin
5c91735b2c red_worker: revert 8855438a
red_proccess_commands calls were added after calling
guest_set_client_capabilities in order to cleanup the command ring from
old commands that the client might not be able to handle.
However, calling red_process_commands at this stage does send messages
to the client.
In addition, since setting the client capabilities at the guest is not
synchronized, emptying the command ring is not enough in order to make
sure the following commands will be supported by the client.
The call to red_proccess_commands before initializing the display
streams (the call to red_display_start_streams), caused inconsistencies
related to video streaming upon reconnecting (rhbz#883564).

I'm reverting this patch till another solution for the capabilities
mismatch is introduced.

Resolves: rhbz#883564
2012-12-05 12:49:41 -05:00
Marc-André Lureau
069270f641 server: add "port" channel support
A Spice port channel carry arbitrary data between the Spice client and
the Spice server. It may be used to provide additional services on top
of a Spice connection. For example, a channel can be associated with
the qemu monitor for the client to interact with it, just like any
qemu chardev. Or it may be used with various protocols, such as the
Spice Controller.

A port kind is identified simply by its fqdn, such as org.qemu.monitor,
org.spice.spicy.test or org.ovirt.controller...

The channel is based on Spicevmc which simply tunnels data between
client and server, with a few additional messages.

See the description of the channel protocol in spice-common history.
2012-12-05 11:46:28 +01:00
Marc-André Lureau
616eee84c1 server: bump SPICE_SERVER_VERSION to 0.12.2 2012-12-05 11:46:28 +01:00
Yonit Halperin
655f8c440d agent: fix mishandling of agent data received from the client after agent disconnection
The server can receive from the client agent data even when the agent
is disconnected. This can happen if the client sends the agent data
before it receives the AGENT_DISCONNECTED msg. We should receive and handle such msgs, instead
of disconnecting the client.
This bug can also lead to a server crash if the agent gets reconnected
fast enough, and it receives an agent data msg from the client before MSGC_AGENT_START.

upstream bz#55726
rhbz#881980
2012-11-30 11:15:01 -05:00
Yonit Halperin
7f220304db red_worker: no need to align the stride of internal images
Internal images are just read from the surface, compressed, and sent to the client.
Then, they are destroyed. I can't find any reason for aligning their memory.
2012-11-29 09:56:43 -05:00
Yonit Halperin
1e6f872066 red_worker: fix sending internal images with stride > bpp*width to lz compression
rhbz#876685

The current lz implementation does not support such bitmaps.
The following patch will actually prevent allocating stride > bpp*width
for internal images.
2012-11-28 14:04:11 -05:00
Yonit Halperin
4c1a2ad3f1 red_worker.c: fix memory corruption when data from client is bigger than 1024 bytes
Previously, there was no check for the size of the message received from
the client, and all messages were read into a buffer of size 1024.
However, migration data can be bigger than 1024. In such cases, memory
corruption occurred.
2012-11-26 11:08:11 -05:00
Yonit Halperin
16b38ec84e red_worker.c: fix not sending all pending messages when the device is stopped
red_wait_outgoing_item only waits till the currently outgoing msg is
completely sent.
red_wait_outgoing_items does the same for multi-clients. handle_dev_stop erroneously called
red_wait_outgoing_items, instead of waiting till all the items in the
pipes are sent.
This waiting is necessary because after drawables are sent to the client, we release them from the
device. The device might have been stopped due to moving to the non-live
phase of migration. Accessing the device memory during this phase can lead
to inconsistencies.

Also, MSG_MIGRATE should be the last message sent to the client, before
MSG_MIGRATE_DATA. Due to this bug, msgs were marshalled and sent after
handle_dev_stop and after handle_dev_display_migrate which sometimes led
to the release of surfaces, and inserting MSG_DISPLAY_DESTROY_SURFACE
after MSG_MIGRATE.

This patch also removes the calls to red_wait_outgoing_items, from
dev_flush_surfaces. They were unnecessary.
2012-11-26 11:08:11 -05:00
Yonit Halperin
7785a005d4 smartcard.c: avoid marshalling migration data with reference to a memory that might be released before send has completed
The current solution just copy the buffer. Currently data that is read
from the guest is always copied before sending it to the client. When we
will have ref count for these buffers, we can also use it for marshalling
the migration data.
2012-11-26 11:08:10 -05:00