Blame SOURCES/kvm-io-Add-support-for-MSG_PEEK-for-socket-channel.patch

bf143f
From 88b5e059462a72ca758d84c0d4d0895a03baac50 Mon Sep 17 00:00:00 2001
bf143f
From: "manish.mishra" <manish.mishra@nutanix.com>
bf143f
Date: Tue, 20 Dec 2022 18:44:17 +0000
bf143f
Subject: [PATCH 1/3] io: Add support for MSG_PEEK for socket channel
bf143f
MIME-Version: 1.0
bf143f
Content-Type: text/plain; charset=UTF-8
bf143f
Content-Transfer-Encoding: 8bit
bf143f
bf143f
RH-Author: Peter Xu <peterx@redhat.com>
bf143f
RH-MergeRequest: 258: migration: Fix multifd crash due to channel disorder
bf143f
RH-Bugzilla: 2137740
bf143f
RH-Acked-by: quintela1 <quintela@redhat.com>
bf143f
RH-Acked-by: Leonardo BrĂ¡s <leobras@redhat.com>
bf143f
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
bf143f
RH-Commit: [1/2] 04fc6fae358599b8509f5355469d2e8720f01903
bf143f
bf143f
Conflicts:
bf143f
	io/channel-null.c
bf143f
	migration/channel-block.c
bf143f
bf143f
        Because these two files do not exist in rhel8.8 tree, dropping the
bf143f
        changes.
bf143f
bf143f
MSG_PEEK peeks at the channel, The data is treated as unread and
bf143f
the next read shall still return this data. This support is
bf143f
currently added only for socket class. Extra parameter 'flags'
bf143f
is added to io_readv calls to pass extra read flags like MSG_PEEK.
bf143f
bf143f
Reviewed-by: Peter Xu <peterx@redhat.com>
bf143f
Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
bf143f
Reviewed-by: Juan Quintela <quintela@redhat.com>
bf143f
Suggested-by: Daniel P. Berrange <berrange@redhat.com>
bf143f
Signed-off-by: manish.mishra <manish.mishra@nutanix.com>
bf143f
Signed-off-by: Juan Quintela <quintela@redhat.com>
bf143f
(cherry picked from commit 84615a19ddf2bfb38d7b3a0d487d2397ee55e4f3)
bf143f
Signed-off-by: Peter Xu <peterx@redhat.com>
bf143f
---
bf143f
 chardev/char-socket.c               |  4 ++--
bf143f
 include/io/channel.h                |  6 ++++++
bf143f
 io/channel-buffer.c                 |  1 +
bf143f
 io/channel-command.c                |  1 +
bf143f
 io/channel-file.c                   |  1 +
bf143f
 io/channel-socket.c                 | 19 ++++++++++++++++++-
bf143f
 io/channel-tls.c                    |  1 +
bf143f
 io/channel-websock.c                |  1 +
bf143f
 io/channel.c                        | 16 ++++++++++++----
bf143f
 migration/rdma.c                    |  1 +
bf143f
 scsi/qemu-pr-helper.c               |  2 +-
bf143f
 tests/qtest/tpm-emu.c               |  2 +-
bf143f
 tests/unit/test-io-channel-socket.c |  1 +
bf143f
 util/vhost-user-server.c            |  2 +-
bf143f
 14 files changed, 48 insertions(+), 10 deletions(-)
bf143f
bf143f
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
bf143f
index 836cfa0bc2..4cdf79e0c2 100644
bf143f
--- a/chardev/char-socket.c
bf143f
+++ b/chardev/char-socket.c
bf143f
@@ -339,11 +339,11 @@ static ssize_t tcp_chr_recv(Chardev *chr, char *buf, size_t len)
bf143f
     if (qio_channel_has_feature(s->ioc, QIO_CHANNEL_FEATURE_FD_PASS)) {
bf143f
         ret = qio_channel_readv_full(s->ioc, &iov, 1,
bf143f
                                      &msgfds, &msgfds_num,
bf143f
-                                     NULL);
bf143f
+                                     0, NULL);
bf143f
     } else {
bf143f
         ret = qio_channel_readv_full(s->ioc, &iov, 1,
bf143f
                                      NULL, NULL,
bf143f
-                                     NULL);
bf143f
+                                     0, NULL);
bf143f
     }
bf143f
 
bf143f
     if (ret == QIO_CHANNEL_ERR_BLOCK) {
bf143f
diff --git a/include/io/channel.h b/include/io/channel.h
bf143f
index c680ee7480..716235d496 100644
bf143f
--- a/include/io/channel.h
bf143f
+++ b/include/io/channel.h
bf143f
@@ -34,6 +34,8 @@ OBJECT_DECLARE_TYPE(QIOChannel, QIOChannelClass,
bf143f
 
bf143f
 #define QIO_CHANNEL_WRITE_FLAG_ZERO_COPY 0x1
bf143f
 
bf143f
+#define QIO_CHANNEL_READ_FLAG_MSG_PEEK 0x1
bf143f
+
bf143f
 typedef enum QIOChannelFeature QIOChannelFeature;
bf143f
 
bf143f
 enum QIOChannelFeature {
bf143f
@@ -41,6 +43,7 @@ enum QIOChannelFeature {
bf143f
     QIO_CHANNEL_FEATURE_SHUTDOWN,
bf143f
     QIO_CHANNEL_FEATURE_LISTEN,
bf143f
     QIO_CHANNEL_FEATURE_WRITE_ZERO_COPY,
bf143f
+    QIO_CHANNEL_FEATURE_READ_MSG_PEEK,
bf143f
 };
bf143f
 
bf143f
 
bf143f
@@ -114,6 +117,7 @@ struct QIOChannelClass {
bf143f
                         size_t niov,
bf143f
                         int **fds,
bf143f
                         size_t *nfds,
bf143f
+                        int flags,
bf143f
                         Error **errp);
bf143f
     int (*io_close)(QIOChannel *ioc,
bf143f
                     Error **errp);
bf143f
@@ -188,6 +192,7 @@ void qio_channel_set_name(QIOChannel *ioc,
bf143f
  * @niov: the length of the @iov array
bf143f
  * @fds: pointer to an array that will received file handles
bf143f
  * @nfds: pointer filled with number of elements in @fds on return
bf143f
+ * @flags: read flags (QIO_CHANNEL_READ_FLAG_*)
bf143f
  * @errp: pointer to a NULL-initialized error object
bf143f
  *
bf143f
  * Read data from the IO channel, storing it in the
bf143f
@@ -224,6 +229,7 @@ ssize_t qio_channel_readv_full(QIOChannel *ioc,
bf143f
                                size_t niov,
bf143f
                                int **fds,
bf143f
                                size_t *nfds,
bf143f
+                               int flags,
bf143f
                                Error **errp);
bf143f
 
bf143f
 
bf143f
diff --git a/io/channel-buffer.c b/io/channel-buffer.c
bf143f
index bf52011be2..8096180f85 100644
bf143f
--- a/io/channel-buffer.c
bf143f
+++ b/io/channel-buffer.c
bf143f
@@ -54,6 +54,7 @@ static ssize_t qio_channel_buffer_readv(QIOChannel *ioc,
bf143f
                                         size_t niov,
bf143f
                                         int **fds,
bf143f
                                         size_t *nfds,
bf143f
+                                        int flags,
bf143f
                                         Error **errp)
bf143f
 {
bf143f
     QIOChannelBuffer *bioc = QIO_CHANNEL_BUFFER(ioc);
bf143f
diff --git a/io/channel-command.c b/io/channel-command.c
bf143f
index 5ff1691bad..2834413b3a 100644
bf143f
--- a/io/channel-command.c
bf143f
+++ b/io/channel-command.c
bf143f
@@ -230,6 +230,7 @@ static ssize_t qio_channel_command_readv(QIOChannel *ioc,
bf143f
                                          size_t niov,
bf143f
                                          int **fds,
bf143f
                                          size_t *nfds,
bf143f
+                                         int flags,
bf143f
                                          Error **errp)
bf143f
 {
bf143f
     QIOChannelCommand *cioc = QIO_CHANNEL_COMMAND(ioc);
bf143f
diff --git a/io/channel-file.c b/io/channel-file.c
bf143f
index 348a48545e..490f0e5d84 100644
bf143f
--- a/io/channel-file.c
bf143f
+++ b/io/channel-file.c
bf143f
@@ -86,6 +86,7 @@ static ssize_t qio_channel_file_readv(QIOChannel *ioc,
bf143f
                                       size_t niov,
bf143f
                                       int **fds,
bf143f
                                       size_t *nfds,
bf143f
+                                      int flags,
bf143f
                                       Error **errp)
bf143f
 {
bf143f
     QIOChannelFile *fioc = QIO_CHANNEL_FILE(ioc);
bf143f
diff --git a/io/channel-socket.c b/io/channel-socket.c
bf143f
index 6010ad7017..ca8b180b69 100644
bf143f
--- a/io/channel-socket.c
bf143f
+++ b/io/channel-socket.c
bf143f
@@ -174,6 +174,9 @@ int qio_channel_socket_connect_sync(QIOChannelSocket *ioc,
bf143f
     }
bf143f
 #endif
bf143f
 
bf143f
+    qio_channel_set_feature(QIO_CHANNEL(ioc),
bf143f
+                            QIO_CHANNEL_FEATURE_READ_MSG_PEEK);
bf143f
+
bf143f
     return 0;
bf143f
 }
bf143f
 
bf143f
@@ -407,6 +410,9 @@ qio_channel_socket_accept(QIOChannelSocket *ioc,
bf143f
     }
bf143f
 #endif /* WIN32 */
bf143f
 
bf143f
+    qio_channel_set_feature(QIO_CHANNEL(cioc),
bf143f
+                            QIO_CHANNEL_FEATURE_READ_MSG_PEEK);
bf143f
+
bf143f
     trace_qio_channel_socket_accept_complete(ioc, cioc, cioc->fd);
bf143f
     return cioc;
bf143f
 
bf143f
@@ -497,6 +503,7 @@ static ssize_t qio_channel_socket_readv(QIOChannel *ioc,
bf143f
                                         size_t niov,
bf143f
                                         int **fds,
bf143f
                                         size_t *nfds,
bf143f
+                                        int flags,
bf143f
                                         Error **errp)
bf143f
 {
bf143f
     QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
bf143f
@@ -518,6 +525,10 @@ static ssize_t qio_channel_socket_readv(QIOChannel *ioc,
bf143f
 
bf143f
     }
bf143f
 
bf143f
+    if (flags & QIO_CHANNEL_READ_FLAG_MSG_PEEK) {
bf143f
+        sflags |= MSG_PEEK;
bf143f
+    }
bf143f
+
bf143f
  retry:
bf143f
     ret = recvmsg(sioc->fd, &msg, sflags);
bf143f
     if (ret < 0) {
bf143f
@@ -625,11 +636,17 @@ static ssize_t qio_channel_socket_readv(QIOChannel *ioc,
bf143f
                                         size_t niov,
bf143f
                                         int **fds,
bf143f
                                         size_t *nfds,
bf143f
+                                        int flags,
bf143f
                                         Error **errp)
bf143f
 {
bf143f
     QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
bf143f
     ssize_t done = 0;
bf143f
     ssize_t i;
bf143f
+    int sflags = 0;
bf143f
+
bf143f
+    if (flags & QIO_CHANNEL_READ_FLAG_MSG_PEEK) {
bf143f
+        sflags |= MSG_PEEK;
bf143f
+    }
bf143f
 
bf143f
     for (i = 0; i < niov; i++) {
bf143f
         ssize_t ret;
bf143f
@@ -637,7 +654,7 @@ static ssize_t qio_channel_socket_readv(QIOChannel *ioc,
bf143f
         ret = recv(sioc->fd,
bf143f
                    iov[i].iov_base,
bf143f
                    iov[i].iov_len,
bf143f
-                   0);
bf143f
+                   sflags);
bf143f
         if (ret < 0) {
bf143f
             if (errno == EAGAIN) {
bf143f
                 if (done) {
bf143f
diff --git a/io/channel-tls.c b/io/channel-tls.c
bf143f
index 4ce890a538..c730cb8ec5 100644
bf143f
--- a/io/channel-tls.c
bf143f
+++ b/io/channel-tls.c
bf143f
@@ -260,6 +260,7 @@ static ssize_t qio_channel_tls_readv(QIOChannel *ioc,
bf143f
                                      size_t niov,
bf143f
                                      int **fds,
bf143f
                                      size_t *nfds,
bf143f
+                                     int flags,
bf143f
                                      Error **errp)
bf143f
 {
bf143f
     QIOChannelTLS *tioc = QIO_CHANNEL_TLS(ioc);
bf143f
diff --git a/io/channel-websock.c b/io/channel-websock.c
bf143f
index 035dd6075b..13c94f2afe 100644
bf143f
--- a/io/channel-websock.c
bf143f
+++ b/io/channel-websock.c
bf143f
@@ -1081,6 +1081,7 @@ static ssize_t qio_channel_websock_readv(QIOChannel *ioc,
bf143f
                                          size_t niov,
bf143f
                                          int **fds,
bf143f
                                          size_t *nfds,
bf143f
+                                         int flags,
bf143f
                                          Error **errp)
bf143f
 {
bf143f
     QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(ioc);
bf143f
diff --git a/io/channel.c b/io/channel.c
bf143f
index 0640941ac5..a8c7f11649 100644
bf143f
--- a/io/channel.c
bf143f
+++ b/io/channel.c
bf143f
@@ -52,6 +52,7 @@ ssize_t qio_channel_readv_full(QIOChannel *ioc,
bf143f
                                size_t niov,
bf143f
                                int **fds,
bf143f
                                size_t *nfds,
bf143f
+                               int flags,
bf143f
                                Error **errp)
bf143f
 {
bf143f
     QIOChannelClass *klass = QIO_CHANNEL_GET_CLASS(ioc);
bf143f
@@ -63,7 +64,14 @@ ssize_t qio_channel_readv_full(QIOChannel *ioc,
bf143f
         return -1;
bf143f
     }
bf143f
 
bf143f
-    return klass->io_readv(ioc, iov, niov, fds, nfds, errp);
bf143f
+    if ((flags & QIO_CHANNEL_READ_FLAG_MSG_PEEK) &&
bf143f
+        !qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_READ_MSG_PEEK)) {
bf143f
+        error_setg_errno(errp, EINVAL,
bf143f
+                         "Channel does not support peek read");
bf143f
+        return -1;
bf143f
+    }
bf143f
+
bf143f
+    return klass->io_readv(ioc, iov, niov, fds, nfds, flags, errp);
bf143f
 }
bf143f
 
bf143f
 
bf143f
@@ -146,7 +154,7 @@ int qio_channel_readv_full_all_eof(QIOChannel *ioc,
bf143f
     while ((nlocal_iov > 0) || local_fds) {
bf143f
         ssize_t len;
bf143f
         len = qio_channel_readv_full(ioc, local_iov, nlocal_iov, local_fds,
bf143f
-                                     local_nfds, errp);
bf143f
+                                     local_nfds, 0, errp);
bf143f
         if (len == QIO_CHANNEL_ERR_BLOCK) {
bf143f
             if (qemu_in_coroutine()) {
bf143f
                 qio_channel_yield(ioc, G_IO_IN);
bf143f
@@ -284,7 +292,7 @@ ssize_t qio_channel_readv(QIOChannel *ioc,
bf143f
                           size_t niov,
bf143f
                           Error **errp)
bf143f
 {
bf143f
-    return qio_channel_readv_full(ioc, iov, niov, NULL, NULL, errp);
bf143f
+    return qio_channel_readv_full(ioc, iov, niov, NULL, NULL, 0, errp);
bf143f
 }
bf143f
 
bf143f
 
bf143f
@@ -303,7 +311,7 @@ ssize_t qio_channel_read(QIOChannel *ioc,
bf143f
                          Error **errp)
bf143f
 {
bf143f
     struct iovec iov = { .iov_base = buf, .iov_len = buflen };
bf143f
-    return qio_channel_readv_full(ioc, &iov, 1, NULL, NULL, errp);
bf143f
+    return qio_channel_readv_full(ioc, &iov, 1, NULL, NULL, 0, errp);
bf143f
 }
bf143f
 
bf143f
 
bf143f
diff --git a/migration/rdma.c b/migration/rdma.c
bf143f
index 54acd2000e..dcf98bd7f8 100644
bf143f
--- a/migration/rdma.c
bf143f
+++ b/migration/rdma.c
bf143f
@@ -2917,6 +2917,7 @@ static ssize_t qio_channel_rdma_readv(QIOChannel *ioc,
bf143f
                                       size_t niov,
bf143f
                                       int **fds,
bf143f
                                       size_t *nfds,
bf143f
+                                      int flags,
bf143f
                                       Error **errp)
bf143f
 {
bf143f
     QIOChannelRDMA *rioc = QIO_CHANNEL_RDMA(ioc);
bf143f
diff --git a/scsi/qemu-pr-helper.c b/scsi/qemu-pr-helper.c
bf143f
index f281daeced..12ec8e9368 100644
bf143f
--- a/scsi/qemu-pr-helper.c
bf143f
+++ b/scsi/qemu-pr-helper.c
bf143f
@@ -612,7 +612,7 @@ static int coroutine_fn prh_read(PRHelperClient *client, void *buf, int sz,
bf143f
         iov.iov_base = buf;
bf143f
         iov.iov_len = sz;
bf143f
         n_read = qio_channel_readv_full(QIO_CHANNEL(client->ioc), &iov, 1,
bf143f
-                                        &fds, &nfds, errp);
bf143f
+                                        &fds, &nfds, 0, errp);
bf143f
 
bf143f
         if (n_read == QIO_CHANNEL_ERR_BLOCK) {
bf143f
             qio_channel_yield(QIO_CHANNEL(client->ioc), G_IO_IN);
bf143f
diff --git a/tests/qtest/tpm-emu.c b/tests/qtest/tpm-emu.c
bf143f
index 2994d1cf42..3cf1acaf7d 100644
bf143f
--- a/tests/qtest/tpm-emu.c
bf143f
+++ b/tests/qtest/tpm-emu.c
bf143f
@@ -106,7 +106,7 @@ void *tpm_emu_ctrl_thread(void *data)
bf143f
         int *pfd = NULL;
bf143f
         size_t nfd = 0;
bf143f
 
bf143f
-        qio_channel_readv_full(ioc, &iov, 1, &pfd, &nfd, &error_abort);
bf143f
+        qio_channel_readv_full(ioc, &iov, 1, &pfd, &nfd, 0, &error_abort);
bf143f
         cmd = be32_to_cpu(cmd);
bf143f
         g_assert_cmpint(cmd, ==, CMD_SET_DATAFD);
bf143f
         g_assert_cmpint(nfd, ==, 1);
bf143f
diff --git a/tests/unit/test-io-channel-socket.c b/tests/unit/test-io-channel-socket.c
bf143f
index 6713886d02..de2930f203 100644
bf143f
--- a/tests/unit/test-io-channel-socket.c
bf143f
+++ b/tests/unit/test-io-channel-socket.c
bf143f
@@ -452,6 +452,7 @@ static void test_io_channel_unix_fd_pass(void)
bf143f
                            G_N_ELEMENTS(iorecv),
bf143f
                            &fdrecv,
bf143f
                            &nfdrecv,
bf143f
+                           0,
bf143f
                            &error_abort);
bf143f
 
bf143f
     g_assert(nfdrecv == G_N_ELEMENTS(fdsend));
bf143f
diff --git a/util/vhost-user-server.c b/util/vhost-user-server.c
bf143f
index 783d847a6d..e6a9ef72b7 100644
bf143f
--- a/util/vhost-user-server.c
bf143f
+++ b/util/vhost-user-server.c
bf143f
@@ -102,7 +102,7 @@ vu_message_read(VuDev *vu_dev, int conn_fd, VhostUserMsg *vmsg)
bf143f
          * qio_channel_readv_full may have short reads, keeping calling it
bf143f
          * until getting VHOST_USER_HDR_SIZE or 0 bytes in total
bf143f
          */
bf143f
-        rc = qio_channel_readv_full(ioc, &iov, 1, &fds, &nfds, &local_err);
bf143f
+        rc = qio_channel_readv_full(ioc, &iov, 1, &fds, &nfds, 0, &local_err);
bf143f
         if (rc < 0) {
bf143f
             if (rc == QIO_CHANNEL_ERR_BLOCK) {
bf143f
                 assert(local_err == NULL);
bf143f
-- 
bf143f
2.37.3
bf143f