summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlon Levy <alevy@redhat.com>2010-12-05 16:27:11 +0200
committerAlon Levy <alevy@redhat.com>2010-12-06 13:20:14 +0200
commitdc8946f9f49a2683748ba42dc6a85a7e68ad69bc (patch)
tree505a7aac3411388819d152687aa63d472ff2b3bb
parent3eac5463092ed0135599137df70479c582ee3bc2 (diff)
downloadspice-dc8946f9f49a2683748ba42dc6a85a7e68ad69bc.tar.gz
spice-dc8946f9f49a2683748ba42dc6a85a7e68ad69bc.tar.xz
spice-dc8946f9f49a2683748ba42dc6a85a7e68ad69bc.zip
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.
-rw-r--r--server/reds.c19
1 files 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);