The unit tests 'test-io-channel-file' and 'test-io-channel-socket'
currently fail on Solaris, because we try to perform vectored I/O with
a batch of 250 (CHUNK_COUNT) iovs. This exceeds MAX_IOV on Solaris
(only 16, much lower than Linux's 1024), and so results in an EINVAL
for file operations, and EMSGSIZE for sockets.

To fix this, make qio_channel_readv_full and qio_channel_writev_full
only use the first IOV_MAX iovs passed in, and we'll return the number
of bytes actually processed like always.

Signed-off-by: Andrew Deason <adea...@sinenomine.net>
---
These aren't the only tests that fail on Solaris right now, but this
seemed easy to fix (assuming this is correct), so I'm just submitting
something while I'm looking at it.

 io/channel.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/io/channel.c b/io/channel.c
index e8b019dc36..cb9d85a30d 100644
--- a/io/channel.c
+++ b/io/channel.c
@@ -56,40 +56,44 @@ ssize_t qio_channel_readv_full(QIOChannel *ioc,
 {
     QIOChannelClass *klass = QIO_CHANNEL_GET_CLASS(ioc);
 
     if ((fds || nfds) &&
         !qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_FD_PASS)) {
         error_setg_errno(errp, EINVAL,
                          "Channel does not support file descriptor passing");
         return -1;
     }
 
+    niov = MIN(niov, IOV_MAX);
+
     return klass->io_readv(ioc, iov, niov, fds, nfds, errp);
 }
 
 
 ssize_t qio_channel_writev_full(QIOChannel *ioc,
                                 const struct iovec *iov,
                                 size_t niov,
                                 int *fds,
                                 size_t nfds,
                                 Error **errp)
 {
     QIOChannelClass *klass = QIO_CHANNEL_GET_CLASS(ioc);
 
     if ((fds || nfds) &&
         !qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_FD_PASS)) {
         error_setg_errno(errp, EINVAL,
                          "Channel does not support file descriptor passing");
         return -1;
     }
 
+    niov = MIN(niov, IOV_MAX);
+
     return klass->io_writev(ioc, iov, niov, fds, nfds, errp);
 }
 
 
 int qio_channel_readv_all_eof(QIOChannel *ioc,
                               const struct iovec *iov,
                               size_t niov,
                               Error **errp)
 {
     return qio_channel_readv_full_all_eof(ioc, iov, niov, NULL, NULL, errp);
-- 
2.11.0


Reply via email to