From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47994) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z5CSj-0004OK-CP for qemu-devel@nongnu.org; Wed, 17 Jun 2015 08:29:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Z5CSe-0007N2-28 for qemu-devel@nongnu.org; Wed, 17 Jun 2015 08:29:01 -0400 Received: from mx1.redhat.com ([209.132.183.28]:51045) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z5CSd-0007Ms-U3 for qemu-devel@nongnu.org; Wed, 17 Jun 2015 08:28:56 -0400 From: Juan Quintela In-Reply-To: <1434450415-11339-12-git-send-email-dgilbert@redhat.com> (David Alan Gilbert's message of "Tue, 16 Jun 2015 11:26:24 +0100") References: <1434450415-11339-1-git-send-email-dgilbert@redhat.com> <1434450415-11339-12-git-send-email-dgilbert@redhat.com> Date: Wed, 17 Jun 2015 14:28:53 +0200 Message-ID: <87r3pa4iyi.fsf@neno.neno> MIME-Version: 1.0 Content-Type: text/plain Subject: Re: [Qemu-devel] [PATCH v7 11/42] Return path: socket_writev_buffer: Block even on non-blocking fd's Reply-To: quintela@redhat.com List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: "Dr. David Alan Gilbert (git)" Cc: aarcange@redhat.com, yamahata@private.email.ne.jp, liang.z.li@intel.com, qemu-devel@nongnu.org, luis@cs.umu.se, amit.shah@redhat.com, pbonzini@redhat.com, david@gibson.dropbear.id.au "Dr. David Alan Gilbert (git)" wrote: > From: "Dr. David Alan Gilbert" > > The destination sets the fd to non-blocking on incoming migrations; > this also affects the return path from the destination, and thus we > need to make sure we can safely write to the return path. > > Signed-off-by: Dr. David Alan Gilbert Reviewed-by: Juan Quintela > migration/qemu-file-unix.c | 41 ++++++++++++++++++++++++++++++++++++----- > 1 file changed, 36 insertions(+), 5 deletions(-) > > diff --git a/migration/qemu-file-unix.c b/migration/qemu-file-unix.c > index 561621e..b6c55ab 100644 > --- a/migration/qemu-file-unix.c > +++ b/migration/qemu-file-unix.c > @@ -39,12 +39,43 @@ static ssize_t socket_writev_buffer(void *opaque, struct iovec *iov, int iovcnt, > QEMUFileSocket *s = opaque; > ssize_t len; > ssize_t size = iov_size(iov, iovcnt); > + ssize_t offset = 0; > + int err; > > - len = iov_send(s->fd, iov, iovcnt, 0, size); > - if (len < size) { > - len = -socket_error(); > - } > - return len; > + while (size > 0) { > + len = iov_send(s->fd, iov, iovcnt, offset, size); > + > + if (len > 0) { > + size -= len; > + offset += len; > + } ion_send() can return -1 on error This looks a "hacky way" to look for it, althoght my understanding is that it is correct, so the review-by > + > + if (size > 0) { > + err = socket_error(); > + > + if (err != EAGAIN && err != EWOULDBLOCK) { > + error_report("socket_writev_buffer: Got err=%d for (%zd/%zd)", > + err, size, len); > + /* > + * If I've already sent some but only just got the error, I > + * could return the amount validly sent so far and wait for the > + * next call to report the error, but I'd rather flag the error > + * immediately. > + */ > + return -err; > + } > + > + /* Emulate blocking */ > + GPollFD pfd; > + > + pfd.fd = s->fd; > + pfd.events = G_IO_OUT | G_IO_ERR; > + pfd.revents = 0; > + g_poll(&pfd, 1 /* 1 fd */, -1 /* no timeout */); > + } > + } > + > + return offset; > } > > static int socket_get_fd(void *opaque)