[Spice-devel] [PATCH] server/vdi_port (virtserial): always read data

Hans de Goede hdegoede at redhat.com
Mon Dec 6 02:15:36 PST 2010


Hi,

Good catch, ack!

Regards,

Hans


On 12/05/2010 03:27 PM, Alon Levy wrote:
> We erronously ignored data from guest on the serial channel if no client is
> connected. This leads to an assert when the guest writes a second time, since
> there is still data unconsumed by us (the host).
> Fix by reading data anyway, and discarding it after parsing (and reading) whole
> messages from the guest.
> Net affect is that any messages the agent sends while no client is connected
> get discarded, but only full messages are discarded.
> This fixes an abort if booting a winxp guest with vdagent without a connected
> client.
> ---
>   server/reds.c |   19 +++++++++++++------
>   1 files changed, 13 insertions(+), 6 deletions(-)
>
> diff --git a/server/reds.c b/server/reds.c
> index 728778c..c7181ee 100644
> --- a/server/reds.c
> +++ b/server/reds.c
> @@ -1213,11 +1213,16 @@ static void dispatch_vdi_port_data(int port, VDIReadBuf *buf)
>
>       switch (port) {
>       case VDP_CLIENT_PORT: {
> -        item = new_out_item(SPICE_MSG_MAIN_AGENT_DATA);
> +        if (reds->agent_state.connected) {
> +            item = new_out_item(SPICE_MSG_MAIN_AGENT_DATA);
>
> -        spice_marshaller_add_ref_full(item->m, buf->data, buf->len,
> -                                      vdi_read_buf_release, buf);
> -        reds_push_pipe_item(item);
> +            spice_marshaller_add_ref_full(item->m, buf->data, buf->len,
> +                                          vdi_read_buf_release, buf);
> +            reds_push_pipe_item(item);
> +        } else {
> +            red_printf("throwing away, no client: %d", buf->len);
> +            vdi_read_buf_release(buf->data, buf);
> +        }
>           break;
>       }
>       case VDP_SERVER_PORT:
> @@ -1254,13 +1259,15 @@ static int read_from_vdi_port(void)
>       }
>       inside_call = 1;
>
> -    if (!reds->agent_state.connected || reds->mig_target) {
> +    if (reds->mig_target || !vdagent) {
> +        // discard data only if we are migrating or vdagent has not been
> +        // initialized.
>           inside_call = 0;
>           return 0;
>       }
>
>       sif = SPICE_CONTAINEROF(vdagent->base.sif, SpiceCharDeviceInterface, base);
> -    while (!quit_loop&&  reds->agent_state.connected) {
> +    while (!quit_loop) {
>           switch (state->read_state) {
>           case VDI_PORT_READ_STATE_READ_HADER:
>               n = sif->read(vdagent, state->recive_pos, state->recive_len);


More information about the Spice-devel mailing list