Hi all,

The issue is easy to reproduce when we confiugred multi-queue function for 
vhost-user nics.

The main backtrace is as follows:

vhost_user_write  ==>  0)  sets s->write_msgfds_num to 8
        qemu_chr_fe_write_all
                qemu_chr_fe_write_buffer  ==> 4) rewrite because (ret <0 && 
errno is EAGAIN)
                        tcp_chr_write  ==> 3) clear resource about 
s->write_msgfds and set s->write_msgfds_num to 0
                                io_channel_send_full  ==>  2) errno = EAGAIN 
and return -1
                                        qio_channel_socket_writev  ==> 1) 
returns QIO_CHANNEL_ERR_BLOCK when ret <0 && errno == EAGAIN

Then at the above step 4) may cause undefined behaviors on the vhost-user 
server side because null control message is sent. 

So, we submit a patch to fix it. What's your opinion?

Regards,
-Gonglei

> -----Original Message-----
> From: linzhecheng
> Sent: Tuesday, May 29, 2018 4:20 PM
> To: qemu-devel@nongnu.org
> Cc: pbonz...@redhat.com; wangxin (U) <wangxinxin.w...@huawei.com>;
> berra...@redhat.com; pet...@redhat.com; marcandre.lur...@redhat.com;
> ebl...@redhat.com; Gonglei (Arei) <arei.gong...@huawei.com>
> Subject: RE: [PATCH] socket: dont't free msgfds if error equals EAGAIN
> 
> CC'ing Daniel P. Berrangé , Peter Xu, Marc-André Lureau, Eric Blake, Gonglei
> 
> > -----邮件原件-----
> > 发件人: linzhecheng
> > 发送时间: 2018年5月29日 10:53
> > 收件人: qemu-devel@nongnu.org
> > 抄送: pbonz...@redhat.com; wangxin (U)
> <wangxinxin.w...@huawei.com>;
> > linzhecheng <linzhech...@huawei.com>
> > 主题: [PATCH] socket: dont't free msgfds if error equals EAGAIN
> >
> > Signed-off-by: linzhecheng <linzhech...@huawei.com>
> >
> > diff --git a/chardev/char-socket.c b/chardev/char-socket.c index
> > 159e69c3b1..17519ec589 100644
> > --- a/chardev/char-socket.c
> > +++ b/chardev/char-socket.c
> > @@ -134,8 +134,8 @@ static int tcp_chr_write(Chardev *chr, const uint8_t
> > *buf, int len)
> >                                          s->write_msgfds,
> >                                          s->write_msgfds_num);
> >
> > -        /* free the written msgfds, no matter what */
> > -        if (s->write_msgfds_num) {
> > +        /* free the written msgfds in any cases other than errno==EAGAIN
> */
> > +        if (EAGAIN != errno && s->write_msgfds_num) {
> >              g_free(s->write_msgfds);
> >              s->write_msgfds = 0;
> >              s->write_msgfds_num = 0;
> > --
> > 2.12.2.windows.2
> >

Reply via email to