<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
<HTML>
<HEAD>
  <META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=UTF-8">
  <META NAME="GENERATOR" CONTENT="GtkHTML/3.28.3">
</HEAD>
<BODY>
I got the cause,see the following,<BR>
welcome comments.<BR>
<BR>
static int read_from_vdi_port(void)<BR>
{<BR>
&nbsp;&nbsp;&nbsp; /* There are 2 scenarios where we can get called recursively:<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1) spice-vmc vmc_read triggering flush of throttled data, recalling us<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2) the buf we push to the client may be send immediately without<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; blocking, in which case its free function will recall us<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; This messes up the state machine, so ignore recursive calls.<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; This is why we always must be called in a loop. */<BR>
&nbsp;&nbsp;&nbsp; static int inside_call = 0;<BR>
&nbsp;&nbsp;&nbsp; int quit_loop = 0;<BR>
&nbsp;&nbsp;&nbsp; VDIPortState *state = &amp;reds-&gt;agent_state;<BR>
&nbsp;&nbsp;&nbsp; SpiceCharDeviceInterface *sif;<BR>
&nbsp;&nbsp;&nbsp; VDIReadBuf *dispatch_buf;<BR>
&nbsp;&nbsp;&nbsp; int total = 0;<BR>
&nbsp;&nbsp;&nbsp; int n;<BR>
&nbsp;&nbsp;&nbsp; if (inside_call) {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<BR>
&nbsp;&nbsp;&nbsp; }<BR>
&nbsp;&nbsp;&nbsp; inside_call = 1;<BR>
<BR>
&nbsp;&nbsp;&nbsp; sif = SPICE_CONTAINEROF(vdagent-&gt;base.sif, SpiceCharDeviceInterface, base);<BR>
&nbsp;&nbsp;&nbsp; if (!reds-&gt;agent_state.connected || reds-&gt;mig_target) {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inside_call = 0;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT COLOR="#ff0000">//root cause is here,it should call read function to consume the spice_vmc data,if not,&quot;virtio_serial_throttle_port(&amp;svc-&gt;port, false);&quot; will not execute,so spice_vmc will block something</FONT><BR>
<FONT COLOR="#ff0000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //the following 2 lines code is ugly,but it resolved the issue.</FONT><BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT COLOR="#ff0000">uint8_t a[2048];</FONT><BR>
<FONT COLOR="#ff0000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sif-&gt;read(vdagent, a, 2048);</FONT><BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<BR>
&nbsp;&nbsp;&nbsp; }<BR>
<BR>
&nbsp;&nbsp;&nbsp; while (!quit_loop &amp;&amp; reds-&gt;agent_state.connected) {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch (state-&gt;read_state) {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case VDI_PORT_READ_STATE_READ_HADER:<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; n = sif-&gt;read(vdagent, state-&gt;recive_pos, state-&gt;recive_len);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!n) {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; quit_loop = 1;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; total += n;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((state-&gt;recive_len -= n)) {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; state-&gt;recive_pos += n;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; quit_loop = 1;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; state-&gt;message_recive_len = state-&gt;vdi_chunk_header.size;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; state-&gt;read_state = VDI_PORT_READ_STATE_GET_BUFF;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case VDI_PORT_READ_STATE_GET_BUFF: {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RingItem *item;<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!(item = ring_get_head(&amp;state-&gt;read_bufs))) {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; quit_loop = 1;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ring_remove(item);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; state-&gt;current_read_buf = (VDIReadBuf *)item;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; state-&gt;recive_pos = state-&gt;current_read_buf-&gt;data;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; state-&gt;recive_len = MIN(state-&gt;message_recive_len,<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sizeof(state-&gt;current_read_buf-&gt;data));<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; state-&gt;current_read_buf-&gt;len = state-&gt;recive_len;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; state-&gt;message_recive_len -= state-&gt;recive_len;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; state-&gt;read_state = VDI_PORT_READ_STATE_READ_DATA;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case VDI_PORT_READ_STATE_READ_DATA:<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; n = sif-&gt;read(vdagent, state-&gt;recive_pos, state-&gt;recive_len);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!n) {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; quit_loop = 1;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; total += n;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((state-&gt;recive_len -= n)) {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; state-&gt;recive_pos += n;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dispatch_buf = state-&gt;current_read_buf;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; state-&gt;current_read_buf = NULL;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; state-&gt;recive_pos = NULL;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (state-&gt;message_recive_len == 0) {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; state-&gt;read_state = VDI_PORT_READ_STATE_READ_HADER;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; state-&gt;recive_pos = (uint8_t *)&amp;state-&gt;vdi_chunk_header;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; state-&gt;recive_len = sizeof(state-&gt;vdi_chunk_header);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; state-&gt;read_state = VDI_PORT_READ_STATE_GET_BUFF;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dispatch_vdi_port_data(state-&gt;vdi_chunk_header.port, dispatch_buf);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&nbsp;&nbsp;&nbsp; }<BR>
&nbsp;&nbsp;&nbsp; inside_call = 0;<BR>
&nbsp;&nbsp;&nbsp; return total;<BR>
}<BR>
<BR>
On Tue, 2010-11-02 at 16:03 +0800, Alon Levy wrote:
<BLOCKQUOTE TYPE=CITE>
<PRE>
On Tue, Nov 02, 2010 at 12:48:22PM +0800, Coolper Chen wrote:
&gt; If spice client keeps connecting Windows XP(vdservice running on
&gt; it),reboot XP remotely or locally,it's ok.
&gt; when XP hung-up,use spice client connecting to XP,XP will continue
&gt; reboot.

Nice workaround. We need to fix this bug.

&gt; 
&gt; On Mon, 2010-11-01 at 17:47 +0800, Coolper Chen wrote:
&gt; &gt; If no vdservice,there's no this issue.
&gt; &gt; 
&gt; &gt; On Mon, 2010-11-01 at 17:26 +0800, Arnon Gilboa wrote:
&gt; &gt; &gt; Please uninstall vdservice &amp; vioser driver, try to reproduce it without 
&gt; &gt; &gt; them, and update us with the results.
&gt; &gt; &gt; Thanks,
&gt; &gt; &gt; Arnon
&gt; &gt; &gt; 
&gt; &gt; &gt; Coolper Chen wrote:
&gt; &gt; &gt; &gt; hi,
&gt; &gt; &gt; &gt; I'm testing spice.I found an issue about vd_agent,when there's no spice
&gt; &gt; &gt; &gt; client connected to the Windows XP guest,I can't remotely reboot Windows
&gt; &gt; &gt; &gt; XP more than 3 times,in the third time,the Windows XP guest will hung up
&gt; &gt; &gt; &gt; in shutting down process,then wait a long time,there's no change(I have
&gt; &gt; &gt; &gt; a monitor in guest,I can know when the guest OS is ready).If I use
&gt; &gt; &gt; &gt; spicec to connect windows xp,I see windows xp shut down and then start.
&gt; &gt; &gt; &gt;
&gt; &gt; &gt; &gt; I compare the normal process of spicec connecting guest with it,I found
&gt; &gt; &gt; &gt; vd_agent sends some messages(VD_AGENT_ANNOUNCE_CAPABILITIES, 3 messages)
&gt; &gt; &gt; &gt; to spice client when Windows XP restart 3 times.
&gt; &gt; &gt; &gt;
&gt; &gt; &gt; &gt; What causes Windows XP not reboot?
&gt; &gt; &gt; &gt;
&gt; &gt; &gt; &gt; I'm using spice 0.6.3 and Windows XP.
&gt; &gt; &gt; &gt;
&gt; &gt; &gt; &gt; Coolper
&gt; &gt; &gt; &gt;
&gt; &gt; &gt; &gt; _______________________________________________
&gt; &gt; &gt; &gt; Spice-devel mailing list
&gt; &gt; &gt; &gt; <A HREF="mailto:Spice-devel@lists.freedesktop.org">Spice-devel@lists.freedesktop.org</A>
&gt; &gt; &gt; &gt; <A HREF="http://lists.freedesktop.org/mailman/listinfo/spice-devel">http://lists.freedesktop.org/mailman/listinfo/spice-devel</A>
&gt; &gt; &gt; &gt;   
&gt; &gt; &gt; 
&gt; &gt; 
&gt; &gt; 
&gt; &gt; _______________________________________________
&gt; &gt; Spice-devel mailing list
&gt; &gt; <A HREF="mailto:Spice-devel@lists.freedesktop.org">Spice-devel@lists.freedesktop.org</A>
&gt; &gt; <A HREF="http://lists.freedesktop.org/mailman/listinfo/spice-devel">http://lists.freedesktop.org/mailman/listinfo/spice-devel</A>
&gt; 
&gt; 
&gt; _______________________________________________
&gt; Spice-devel mailing list
&gt; <A HREF="mailto:Spice-devel@lists.freedesktop.org">Spice-devel@lists.freedesktop.org</A>
&gt; <A HREF="http://lists.freedesktop.org/mailman/listinfo/spice-devel">http://lists.freedesktop.org/mailman/listinfo/spice-devel</A>
</PRE>
</BLOCKQUOTE>
<BR>
</BODY>
</HTML>