From: Vladimir Sementsov-Ogievskiy Date: Wed, 10 Sep 2025 19:31:11 +0000 (+0300) Subject: migration/qemu-file: don't make incoming fds blocking again X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7bc2cbe3306899559c4da1b05e410235d994e22d;p=thirdparty%2Fqemu.git migration/qemu-file: don't make incoming fds blocking again In migration we want to pass fd "as is", not changing its blocking status. The only current user of these fds is CPR state (through VMSTATE_FD), which of-course doesn't want to modify fds on target when source is still running and use these fds. Suggested-by: Daniel P. Berrangé Reviewed-by: Peter Xu Reviewed-by: Daniel P. Berrangé Signed-off-by: Vladimir Sementsov-Ogievskiy Signed-off-by: Daniel P. Berrangé --- diff --git a/include/io/channel.h b/include/io/channel.h index 234e5db70dd..12266256a8f 100644 --- a/include/io/channel.h +++ b/include/io/channel.h @@ -36,6 +36,7 @@ OBJECT_DECLARE_TYPE(QIOChannel, QIOChannelClass, #define QIO_CHANNEL_READ_FLAG_MSG_PEEK 0x1 #define QIO_CHANNEL_READ_FLAG_RELAXED_EOF 0x2 +#define QIO_CHANNEL_READ_FLAG_FD_PRESERVE_BLOCKING 0x4 typedef enum QIOChannelFeature QIOChannelFeature; diff --git a/io/channel-socket.c b/io/channel-socket.c index 3b7ca924ff3..21f8f2e0c54 100644 --- a/io/channel-socket.c +++ b/io/channel-socket.c @@ -464,7 +464,8 @@ static void qio_channel_socket_finalize(Object *obj) #ifndef WIN32 static void qio_channel_socket_copy_fds(struct msghdr *msg, - int **fds, size_t *nfds) + int **fds, size_t *nfds, + bool preserve_blocking) { struct cmsghdr *cmsg; @@ -497,8 +498,10 @@ static void qio_channel_socket_copy_fds(struct msghdr *msg, continue; } - /* O_NONBLOCK is preserved across SCM_RIGHTS so reset it */ - qemu_socket_set_block(fd); + if (!preserve_blocking) { + /* O_NONBLOCK is preserved across SCM_RIGHTS so reset it */ + qemu_socket_set_block(fd); + } #ifndef MSG_CMSG_CLOEXEC qemu_set_cloexec(fd); @@ -556,7 +559,9 @@ static ssize_t qio_channel_socket_readv(QIOChannel *ioc, } if (fds && nfds) { - qio_channel_socket_copy_fds(&msg, fds, nfds); + qio_channel_socket_copy_fds( + &msg, fds, nfds, + flags & QIO_CHANNEL_READ_FLAG_FD_PRESERVE_BLOCKING); } return ret; diff --git a/migration/qemu-file.c b/migration/qemu-file.c index b6ac190034f..d5c6e7ec619 100644 --- a/migration/qemu-file.c +++ b/migration/qemu-file.c @@ -340,7 +340,8 @@ static ssize_t coroutine_mixed_fn qemu_fill_buffer(QEMUFile *f) do { struct iovec iov = { f->buf + pending, IO_BUF_SIZE - pending }; - len = qio_channel_readv_full(f->ioc, &iov, 1, pfds, pnfd, 0, + len = qio_channel_readv_full(f->ioc, &iov, 1, pfds, pnfd, + QIO_CHANNEL_READ_FLAG_FD_PRESERVE_BLOCKING, &local_error); if (len == QIO_CHANNEL_ERR_BLOCK) { if (qemu_in_coroutine()) {