From dc8946f9f49a2683748ba42dc6a85a7e68ad69bc Mon Sep 17 00:00:00 2001 From: Alon Levy Date: Sun, 5 Dec 2010 16:27:11 +0200 Subject: [PATCH] server/vdi_port (virtserial): always read data 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 file changed, 13 insertions(+), 6 deletions(-) diff --git a/server/reds.c b/server/reds.c index 728778cf..c7181ee5 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);