原始邮件
发件人: <marcandre.lur...@gmail.com> 收件人:彭浩10096742 <pbonz...@redhat.com> 抄送人:王业超10154425 <qemu-devel@nongnu.org> 日 期 :2017年07月10日 17:17 主 题 :Re: [Qemu-devel] [PATCH] chardev: fix parallel device can't be reconnect. Hi On Mon, Jul 10, 2017 at 10:36 AM Peng Hao <peng.h...@zte.com.cn> wrote: Parallel device don't register be->chr_can_read function, but remote disconnect event is handled in chr_read. So connected parallel device can not detect remote disconnect event. What is it that you call a parallel device? you are modifying the socket code here. Could you describe a test setup? even better would be to write a test in test-char.c. Signed-off-by: Peng Hao <peng.h...@zte.com.cn> Reviewed-by: Wang Yechao <wang.yechao...@zte.com.cn> --- chardev/char-socket.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/chardev/char-socket.c b/chardev/char-socket.c index ccc499c..59509d4 100644 --- a/chardev/char-socket.c +++ b/chardev/char-socket.c @@ -131,6 +131,14 @@ static int tcp_chr_write(Chardev *chr, const uint8_t *buf, int len) } } +static gboolean is_parallel_device(Chardev *chr) +{ + if (chr && chr->label && strstr(chr->label, "charparallel")) { + return TRUE What guarantees that a parallel device will have "charparallel" in its label? /////I use libvirt command to create vm ,so charparallel is from libvirt.this is a problem. + } + return FALSE +} + static int tcp_chr_read_poll(void *opaque) { Chardev *chr = CHARDEV(opaque) @@ -138,6 +146,8 @@ static int tcp_chr_read_poll(void *opaque) if (!s->connected) { return 0 } + if (is_parallel_device(chr)) { + return 1 That means 1 byte can be read, but s->max_size isn't updated, this will confuse tcp_chr_read(). //////for parallel device s->max_size is always 0,because s->max_size = qemu_chr_be_can_write(chr) but qemu_chr_be_can_write need be->chr_can_read and parallel device has no be->chr_can_read. tcp_chr_read_poll as fd_can_read function ,reurn 1 just means can_read. + } s->max_size = qemu_chr_be_can_write(chr) return s->max_size } @@ -422,6 +432,15 @@ static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque) uint8_t buf[CHR_READ_BUF_LEN] int len, size + /* for parallel-device handle the socket close event here*/ + if (!s->max_size && is_parallel_device(chr)) { + size = tcp_chr_recv(chr, (void *)buf, CHR_READ_BUF_LEN) + if (size == 0 || size == -1) { + tcp_chr_disconnect(chr) I don't understand why that condition wouldn't be reached by the following tcp_chr_recv() handling. Furthermore, you may read more that s->max_size, which will likely break qemu_chr_be_write() in various cases. ///////for parallel device s->max_size is always 0. + } + return TRUE + } + if (!s->connected || s->max_size <= 0) { return TRUE } -- 1.8.3.1 qemu command : -chardev socket,id=charparallel0,host=0.0.0.0,port=5900,server,nowait -device isa-parallel,chardev=charparallel0,id=parallel0guset:front <---->qemu:backend <----->remote tcp socket . when remote tcp socket disconected,qemu can not detect the disconnet from remote.I think all the chardevs without CharBackend->chr_can_read has the same problem. reproduce the problem:create vm with a parallel port ,and connect the parallel port ,then disconnect at the remote.Try to reconnect the parallel port,you can find that you can't connect again. Marc-André Lureau