From: "Daniel P. Berrange" <berrange@redhat.com>
To: "Denis V. Lunev" <den@openvz.org>
Cc: qemu-devel@nongnu.org,
Anton Nefedov <anton.nefedov@virtuozzo.com>,
Paolo Bonzini <pbonzini@redhat.com>
Subject: Re: [Qemu-devel] [PATCH 1/1] qemu_char: socket backend: disconnect on EPIPE
Date: Wed, 1 Feb 2017 13:53:06 +0000 [thread overview]
Message-ID: <20170201135306.GI3232@redhat.com> (raw)
In-Reply-To: <1485954928-22287-1-git-send-email-den@openvz.org>
On Wed, Feb 01, 2017 at 04:15:28PM +0300, Denis V. Lunev wrote:
> From: Anton Nefedov <anton.nefedov@virtuozzo.com>
>
> Socket backend read handler should normally perform a disconnect, however
> the read handler may not get a chance to run if the frontend is not ready
> (qemu_chr_be_can_write == 0).
>
> This means that in virtio-serial frontend case if
> - the host has disconnected (giving EPIPE on socket write)
> - and the guest has disconnected (-> frontend not ready -> backend
> will not read)
> - and there is still data (frontend->backend) to flush (has to be a really
> tricky timing but nevertheless, we have observed the case in production)
>
> This results in virtio-serial trying to flush this data continiously forming
> a busy loop.
>
> Solution: react on EPIPE in the socket write handler. We must not disconnect
> right away though, there still may be data to read (see 4bf1cb0).
>
> Signed-off-by: Anton Nefedov <anton.nefedov@virtuozzo.com>
> Signed-off-by: Denis V. Lunev <den@openvz.org>
> CC: Paolo Bonzini <pbonzini@redhat.com>
> CC: Daniel P. Berrange <berrange@redhat.com>
> ---
> qemu-char.c | 12 +++++++++++-
> 1 file changed, 11 insertions(+), 1 deletion(-)
>
> diff --git a/qemu-char.c b/qemu-char.c
> index 6b4a299..f1f7a07 100644
> --- a/qemu-char.c
> +++ b/qemu-char.c
> @@ -1202,7 +1202,7 @@ static int io_channel_send_full(QIOChannel *ioc,
> errno = EAGAIN;
> return -1;
> } else if (ret < 0) {
> - errno = EINVAL;
> + errno = errno == EPIPE ? EPIPE : EINVAL;
You can't rely on 'errno' being valid after qio_channel_writev_full().
The 'Error **errp' arg to that function is the only error reporting
mechanism that's supported. In particular since the TCP channel can
be wrapped in TLS, the errno can easily have been clobbered by time
you get here.
> @@ -2854,6 +2854,9 @@ static gboolean tcp_chr_accept(QIOChannel *chan,
> GIOCondition cond,
> void *opaque);
>
> +static int tcp_chr_read_poll(void *opaque);
> +static void tcp_chr_disconnect(Chardev *chr);
> +
> /* Called with chr_write_lock held. */
> static int tcp_chr_write(Chardev *chr, const uint8_t *buf, int len)
> {
> @@ -2871,6 +2874,13 @@ static int tcp_chr_write(Chardev *chr, const uint8_t *buf, int len)
> s->write_msgfds_num = 0;
> }
>
> + if (ret < 0 && errno == EPIPE) {
IMHO you should just remove "&& errno == EPIPE" and it'd be fine.
> + if (tcp_chr_read_poll(chr) <= 0) {
> + tcp_chr_disconnect(chr);
> + return len;
> + } /* else let the read handler finish it properly */
> + }
> +
> return ret;
> } else {
> /* XXX: indicate an error ? */
Regards,
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://entangle-photo.org -o- http://search.cpan.org/~danberr/ :|
next prev parent reply other threads:[~2017-02-01 13:53 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-02-01 13:15 [Qemu-devel] [PATCH 1/1] qemu_char: socket backend: disconnect on EPIPE Denis V. Lunev
2017-02-01 13:53 ` Daniel P. Berrange [this message]
2017-02-02 0:54 ` Paolo Bonzini
2017-02-02 9:49 ` Daniel P. Berrange
2017-02-02 8:59 ` Denis V. Lunev
2017-02-02 9:47 ` Daniel P. Berrange
2017-02-02 11:43 ` Denis V. Lunev
2017-02-02 11:46 ` Daniel P. Berrange
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=20170201135306.GI3232@redhat.com \
--to=berrange@redhat.com \
--cc=anton.nefedov@virtuozzo.com \
--cc=den@openvz.org \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
/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.