All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Daniel P. Berrangé" <berrange@redhat.com>
To: Yongji Xie <elohimes@gmail.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>,
	"Marc-André Lureau" <marcandre.lureau@redhat.com>,
	"Jason Wang" <jasowang@redhat.com>,
	"Coquelin, Maxime" <maxime.coquelin@redhat.com>,
	"Yury Kotov" <yury-kotov@yandex-team.ru>,
	"Евгений Яковлев" <wrfsh@yandex-team.ru>,
	qemu-devel <qemu-devel@nongnu.org>,
	zhangyu31@baidu.com, chaiwen@baidu.com, nixun@baidu.com,
	lilin24@baidu.com, "Xie Yongji" <xieyongji@baidu.com>
Subject: Re: [Qemu-devel] [PATCH v4 for-4.0 1/7] char-socket: Enable "nowait" option on client sockets
Date: Thu, 10 Jan 2019 16:41:25 +0000	[thread overview]
Message-ID: <20190110164125.GS2178@redhat.com> (raw)
In-Reply-To: <CAONzpcY8LdzEEqourAjw5mZR9fjtjv20HqvyOvaWVoriD4Cbjg@mail.gmail.com>

On Thu, Jan 10, 2019 at 10:29:20PM +0800, Yongji Xie wrote:
> On Thu, 10 Jan 2019 at 22:11, Daniel P. Berrangé <berrange@redhat.com> wrote:
> >
> > On Thu, Jan 10, 2019 at 10:08:54PM +0800, Yongji Xie wrote:
> > > On Thu, 10 Jan 2019 at 21:24, Daniel P. Berrangé <berrange@redhat.com> wrote:
> > > >
> > > > On Thu, Jan 10, 2019 at 09:19:41PM +0800, Yongji Xie wrote:
> > > > > On Thu, 10 Jan 2019 at 20:50, Daniel P. Berrangé <berrange@redhat.com> wrote:
> > > > > >
> > > > > > On Wed, Jan 09, 2019 at 07:27:22PM +0800, elohimes@gmail.com wrote:
> > > > > > > From: Xie Yongji <xieyongji@baidu.com>
> > > > > > >
> > > > > > > Enable "nowait" option to make QEMU not do a connect
> > > > > > > on client sockets during initialization of the chardev.
> > > > > > > Then we can use qemu_chr_fe_wait_connected() to connect
> > > > > > > when necessary. Now it would be used for unix domain
> > > > > > > socket of vhost-user-blk device to support reconnect.
> > > > > > >
> > > > > > > Signed-off-by: Xie Yongji <xieyongji@baidu.com>
> > > > > > > Signed-off-by: Zhang Yu <zhangyu31@baidu.com>
> > > > > > > ---
> > > > > > >  chardev/char-socket.c | 56 +++++++++++++++++++++----------------------
> > > > > > >  qapi/char.json        |  3 +--
> > > > > > >  qemu-options.hx       |  9 ++++---
> > > > > > >  3 files changed, 35 insertions(+), 33 deletions(-)
> > > > > > >
> > > > > > > diff --git a/chardev/char-socket.c b/chardev/char-socket.c
> > > > > > > index eaa8e8b68f..f803f4f7d3 100644
> > > > > > > --- a/chardev/char-socket.c
> > > > > > > +++ b/chardev/char-socket.c
> > > > > > > @@ -1072,37 +1072,37 @@ static void qmp_chardev_open_socket(Chardev *chr,
> > > > > > >          s->reconnect_time = reconnect;
> > > > > > >      }
> > > > > > >
> > > > > > > -    if (s->reconnect_time) {
> > > > > > > -        tcp_chr_connect_async(chr);
> > > > > > > -    } else {
> > > > > > > -        if (s->is_listen) {
> > > > > > > -            char *name;
> > > > > > > -            s->listener = qio_net_listener_new();
> > > > > > > +    if (s->is_listen) {
> > > > > > > +        char *name;
> > > > > > > +        s->listener = qio_net_listener_new();
> > > > > > >
> > > > > > > -            name = g_strdup_printf("chardev-tcp-listener-%s", chr->label);
> > > > > > > -            qio_net_listener_set_name(s->listener, name);
> > > > > > > -            g_free(name);
> > > > > > > +        name = g_strdup_printf("chardev-tcp-listener-%s", chr->label);
> > > > > > > +        qio_net_listener_set_name(s->listener, name);
> > > > > > > +        g_free(name);
> > > > > > >
> > > > > > > -            if (qio_net_listener_open_sync(s->listener, s->addr, errp) < 0) {
> > > > > > > -                object_unref(OBJECT(s->listener));
> > > > > > > -                s->listener = NULL;
> > > > > > > -                goto error;
> > > > > > > -            }
> > > > > > > +        if (qio_net_listener_open_sync(s->listener, s->addr, errp) < 0) {
> > > > > > > +            object_unref(OBJECT(s->listener));
> > > > > > > +            s->listener = NULL;
> > > > > > > +            goto error;
> > > > > > > +        }
> > > > > > >
> > > > > > > -            qapi_free_SocketAddress(s->addr);
> > > > > > > -            s->addr = socket_local_address(s->listener->sioc[0]->fd, errp);
> > > > > > > -            update_disconnected_filename(s);
> > > > > > > +        qapi_free_SocketAddress(s->addr);
> > > > > > > +        s->addr = socket_local_address(s->listener->sioc[0]->fd, errp);
> > > > > > > +        update_disconnected_filename(s);
> > > > > > >
> > > > > > > -            if (is_waitconnect &&
> > > > > > > -                qemu_chr_wait_connected(chr, errp) < 0) {
> > > > > > > -                return;
> > > > > > > -            }
> > > > > > > -            if (!s->ioc) {
> > > > > > > -                qio_net_listener_set_client_func_full(s->listener,
> > > > > > > -                                                      tcp_chr_accept,
> > > > > > > -                                                      chr, NULL,
> > > > > > > -                                                      chr->gcontext);
> > > > > > > -            }
> > > > > > > +        if (is_waitconnect &&
> > > > > > > +            qemu_chr_wait_connected(chr, errp) < 0) {
> > > > > > > +            return;
> > > > > > > +        }
> > > > > > > +        if (!s->ioc) {
> > > > > > > +            qio_net_listener_set_client_func_full(s->listener,
> > > > > > > +                                                  tcp_chr_accept,
> > > > > > > +                                                  chr, NULL,
> > > > > > > +                                                  chr->gcontext);
> > > > > > > +        }
> > > > > > > +    } else if (is_waitconnect) {
> > > > > > > +        if (s->reconnect_time) {
> > > > > > > +            tcp_chr_connect_async(chr);
> > > > > > >          } else if (qemu_chr_wait_connected(chr, errp) < 0) {
> > > > > > >              goto error;
> > > > > > >          }
> > > > > >
> > > > > > This skips everything when 'is_waitconnect' is false.
> > > > > >
> > > > > > This combines with a bug in tests/libqtest.c which adds the 'nowait'
> > > > > > flag to the -chardevs it cteates. This mistake was previously ignored
> > > > > > because the chardevs were socket clients, but now we honour it.
> > > > > >
> > > > > > We shoul remove 'nowait' from the qtest chardevs, but separately
> > > > > > from that this code should also still attempt a non-blocking
> > > > > > connect when is_waitconnect is false.
> > > > > >
> > > > >
> > > > > Do you mean we still need to connect server in background with
> > > > > "nowait" option? But my purpose is not to connect server until we
> > > > > manually call qemu_chr_fe_wait_connected() in other place.
> > > >
> > > > I don't see a need to delay the connect. We can start a
> > > > background connect right away. The later code you have
> > > > merely needs to wait for that background connect  to
> > > > finish, which qemu_chr_fe_wait_connected still accomplishes.
> > > > This keeps the chardev code clearer only having 2 distinct
> > > > code paths to worry about - blocking or non-blocking connect.
> > > >
> > >
> > > Now the problem is that we have a server that only accept one
> > > connection. And we want to read something from it during device
> > > initializtion.
> > >
> > > If background connect it before we call qemu_chr_fe_wait_connected()
> > > during device initializtion, qemu_chr_fe_wait_connected() will
> > > accomplish but we can't read anything. And we have no way to release
> > > the background connection. So what I want to do in this patch is to
> > > disable background connect.
> >
> > I'm not seeing the problem here. What I proposed results in
> >
> >   1. chardev starts connect()
> 
> This should be asynchronous with "reconnect" option. Another thread
> may connect before vhost backend?
> 
> >   2. vhost backend waits for connect() to complete
> 
> Sorry, I'm not sure I get your point here. Do you mean vhost backend
> call qemu_chr_fe_wait_connected()? Seems like
> qemu_chr_fe_wait_connected() will connect directly rather than wait
> for connect() to complete?

Ahhhh, yes, you are right.

qemu_chr_fe_wait_connected will potentially cause a second connection to
be established

Looking at it the qemu_chr_fe_wait_connected() I believe it is seriously
broken even before this patch series.

The intended usage is that a device can all qemu_chr_fe_wait_connected
to wait for a new connection to be established, and then do I/O on the
chardev.  This does not in fact work if TLS, websock or telnet modes
are enabled for the socket, due to a mistake introduced when we previously
tried to fix this:

  commit 1dc8a6695c731abb7461c637b2512c3670d82be4
  Author: Marc-André Lureau <marcandre.lureau@redhat.com>
  Date:   Tue Aug 16 12:33:32 2016 +0400

    char: fix waiting for TLS and telnet connection

That commit fixed the problem where we continued to accept() new sockets
when TLS/telnet was enabled, because the 's->connected' flag isn't set
immediately.

Unfortunately what this means is that when qemu_chr_fe_wait_connected
returns, the chardev is *not* ready to read/write data. The TLS/telnet
handshake has not been run, and is still pending in the background.

So we'll end up with device backend trying todo I/O on the chardev
at the same time as it is trying todo the TLS/telnet handshake.

We need to fix qemu_chr_fe_wait_connected so that it does explicit
synchronization wrt to any ongoing background connection process.
It must only return once all TLS/telnet/websock handshakes have
completed.  If we fix that correctly, then I believe it will  also
solve the problem you're trying to address.

Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|

  reply	other threads:[~2019-01-10 16:41 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-09 11:27 [Qemu-devel] [PATCH v4 for-4.0 0/7] vhost-user-blk: Add support for backend reconnecting elohimes
2019-01-09 11:27 ` [Qemu-devel] [PATCH v4 for-4.0 1/7] char-socket: Enable "nowait" option on client sockets elohimes
2019-01-10 12:49   ` Daniel P. Berrangé
2019-01-10 13:19     ` Yongji Xie
2019-01-10 13:24       ` Daniel P. Berrangé
2019-01-10 14:08         ` Yongji Xie
2019-01-10 14:11           ` Daniel P. Berrangé
2019-01-10 14:29             ` Yongji Xie
2019-01-10 16:41               ` Daniel P. Berrangé [this message]
2019-01-11  7:50                 ` Yongji Xie
2019-01-11  8:32                   ` Daniel P. Berrangé
2019-01-11  8:36                     ` Yongji Xie
2019-01-15 15:39                       ` Daniel P. Berrangé
2019-01-15 16:53                         ` Yury Kotov
2019-01-15 17:15                           ` Daniel P. Berrangé
2019-01-16  5:39                         ` Yongji Xie
2019-01-09 11:27 ` [Qemu-devel] [PATCH v4 for-4.0 2/7] vhost-user: Support transferring inflight buffer between qemu and backend elohimes
2019-01-14 22:25   ` Michael S. Tsirkin
2019-01-15  6:46     ` Yongji Xie
2019-01-15 12:54       ` Michael S. Tsirkin
2019-01-15 14:18         ` Yongji Xie
2019-01-18  2:45           ` Yongji Xie
2019-01-09 11:27 ` [Qemu-devel] [PATCH v4 for-4.0 3/7] libvhost-user: Introduce vu_queue_map_desc() elohimes
2019-01-09 11:27 ` [Qemu-devel] [PATCH v4 for-4.0 4/7] libvhost-user: Support tracking inflight I/O in shared memory elohimes
2019-01-11  3:56   ` Jason Wang
2019-01-11  6:10     ` Yongji Xie
2019-01-15  7:52       ` Jason Wang
2019-01-15 14:51         ` Yongji Xie
2019-01-17  9:57           ` Jason Wang
2019-01-17 14:59             ` Michael S. Tsirkin
2019-01-18  3:57               ` Jason Wang
2019-01-18  3:32             ` Yongji Xie
2019-01-18  3:56               ` Michael S. Tsirkin
2019-01-18  3:59               ` Jason Wang
2019-01-18  4:03                 ` Michael S. Tsirkin
2019-01-18  7:01                 ` Yongji Xie
2019-01-18  9:26                   ` Jason Wang
2019-01-19 12:19                     ` Yongji Xie
2019-01-15 15:58         ` Michael S. Tsirkin
2019-01-17 10:01           ` Jason Wang
2019-01-17 15:04             ` Michael S. Tsirkin
2019-01-09 11:27 ` [Qemu-devel] [PATCH v4 for-4.0 5/7] vhost-user-blk: Add support to get/set inflight buffer elohimes
2019-01-09 11:27 ` [Qemu-devel] [PATCH v4 for-4.0 6/7] vhost-user-blk: Add support to reconnect backend elohimes
2019-01-09 11:27 ` [Qemu-devel] [PATCH v4 for-4.0 7/7] contrib/vhost-user-blk: enable inflight I/O tracking elohimes
2019-01-10 10:25 ` [Qemu-devel] [PATCH v4 for-4.0 0/7] vhost-user-blk: Add support for backend reconnecting Stefan Hajnoczi
2019-01-10 10:59   ` Yongji Xie
2019-01-11 15:53     ` Stefan Hajnoczi
2019-01-11 17:24       ` Michael S. Tsirkin
2019-01-12  4:50       ` Yongji Xie
2019-01-14 10:22         ` Stefan Hajnoczi
2019-01-14 10:55           ` Yongji Xie
2019-01-16 14:28             ` Stefan Hajnoczi
2019-01-10 10:39 ` Marc-André Lureau
2019-01-10 11:09   ` Yongji Xie

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190110164125.GS2178@redhat.com \
    --to=berrange@redhat.com \
    --cc=chaiwen@baidu.com \
    --cc=elohimes@gmail.com \
    --cc=jasowang@redhat.com \
    --cc=lilin24@baidu.com \
    --cc=marcandre.lureau@redhat.com \
    --cc=maxime.coquelin@redhat.com \
    --cc=mst@redhat.com \
    --cc=nixun@baidu.com \
    --cc=qemu-devel@nongnu.org \
    --cc=wrfsh@yandex-team.ru \
    --cc=xieyongji@baidu.com \
    --cc=yury-kotov@yandex-team.ru \
    --cc=zhangyu31@baidu.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.