On Wed, Feb 25, 2015 at 04:51:31PM +0000, Dr. David Alan Gilbert (git) wrote: > From: "Dr. David Alan Gilbert" > > The return path uses a non-blocking fd so as not to block waiting > for the (possibly broken) destination to finish returning a message, > however we still want outbound data to behave in the same way and block. It's not clear to me from this description exactly where the situation is that you need to write to the non-blocking socket. Is it on the source or the destination? If the source, why are you writing to the return path? If the destination, why are you marking the outgoing return path as non-blocking? > Signed-off-by: Dr. David Alan Gilbert > --- > 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 50291cf..218dbd0 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; > + } > + > + if (size > 0) { > + err = socket_error(); > + > + if (err != EAGAIN) { > + 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) -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson