qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 0/4] monitor: do not rely on O_NONBLOCK for passed file descriptors
@ 2013-03-27  9:10 Stefan Hajnoczi
  2013-03-27  9:10 ` [Qemu-devel] [PATCH v2 1/4] oslib-posix: rename socket_set_nonblock() to qemu_set_nonblock() Stefan Hajnoczi
                   ` (5 more replies)
  0 siblings, 6 replies; 10+ messages in thread
From: Stefan Hajnoczi @ 2013-03-27  9:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: Anthony Liguori, Juan Quintela, mprivozn, coreyb, david.pravec,
	Luiz Capitulino, Stefan Hajnoczi

There are several places where QEMU accidentally relies on the O_NONBLOCK state
of passed file descriptors.  Exposing O_NONBLOCK state makes it part of the QMP
API whenever getfd or fdset_add_fd are used!

Whether or not QEMU will use O_NONBLOCK is an implementation detail and should
be hidden from QMP clients.

This patch series addresses this in 3 steps:

1. Fix callers of monitor_handle_fd_param(), monitor_fdset_get_fd(), and
   monitor_get_fd() that depend on O_NONBLOCK being set.  Luckily there are
   only two instances and they are fixed in Patches 1 & 2.

2. Rename socket_set_nonblock() to qemu_set_nonblock() just like
   qemu_set_cloexec().  This makes code cleaner when working with arbitrary
   file descriptors that may not be sockets.  See Patch 3.

3. Clear O_NONBLOCK when a chardev receives file descriptors.  From now on QEMU
   can assume that passed file descriptors are in blocking mode.  Simply use
   qemu_set_nonblock(fd) if you want to enable O_NONBLOCK.  See Patch 4.

This fixes live migration with recent libvirt.  Libvirt checks if QEMU supports
file descriptor passing and, if yes, hands QEMU a socket with O_NONBLOCK set.
The migrate fd:<foo> code assumes the socket is in blocking mode.  The result
is a corrupted migration stream.  For more info on this bug, see:

https://bugzilla.redhat.com/show_bug.cgi?id=923124

Note that Michal Privoznik <mprivozn@redhat.com> also sent a libvirt patch so
that old QEMUs work with new libvirts:

https://www.redhat.com/archives/libvir-list/2013-March/msg01486.html

My patch series fixes the QMP API and allows old libvirts to work again with
new QEMUs.

v2:
 * Rename socket_set_nonblock() in Patch 1 to avoid code churn [eblake]
 * Avoid qemu_set_block(-1) calls that clobber errno [quintela]

Stefan Hajnoczi (4):
  oslib-posix: rename socket_set_nonblock() to qemu_set_nonblock()
  net: ensure "socket" backend uses non-blocking fds
  qemu-socket: set passed fd non-blocking in socket_connect()
  chardev: clear O_NONBLOCK on SCM_RIGHTS file descriptors

 block/nbd.c            |  2 +-
 block/sheepdog.c       |  2 +-
 include/qemu/sockets.h |  4 ++--
 migration.c            |  2 +-
 nbd.c                  |  8 ++++----
 net/socket.c           | 13 +++++++++----
 qemu-char.c            | 11 +++++++----
 savevm.c               |  2 +-
 slirp/misc.c           |  2 +-
 slirp/tcp_subr.c       |  4 ++--
 ui/vnc.c               |  2 +-
 util/oslib-posix.c     |  4 ++--
 util/oslib-win32.c     |  4 ++--
 util/qemu-sockets.c    |  5 +++--
 14 files changed, 37 insertions(+), 28 deletions(-)

-- 
1.8.1.4

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH v2 1/4] oslib-posix: rename socket_set_nonblock() to qemu_set_nonblock()
  2013-03-27  9:10 [Qemu-devel] [PATCH v2 0/4] monitor: do not rely on O_NONBLOCK for passed file descriptors Stefan Hajnoczi
@ 2013-03-27  9:10 ` Stefan Hajnoczi
  2013-03-27  9:10 ` [Qemu-devel] [PATCH v2 2/4] net: ensure "socket" backend uses non-blocking fds Stefan Hajnoczi
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Stefan Hajnoczi @ 2013-03-27  9:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: Anthony Liguori, Juan Quintela, mprivozn, coreyb, david.pravec,
	Luiz Capitulino, Stefan Hajnoczi

The fcntl(fd, F_SETFL, O_NONBLOCK) flag is not specific to sockets.
Rename to qemu_set_nonblock() just like qemu_set_cloexec().

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 block/nbd.c            | 2 +-
 block/sheepdog.c       | 2 +-
 include/qemu/sockets.h | 4 ++--
 migration.c            | 2 +-
 nbd.c                  | 8 ++++----
 net/socket.c           | 6 +++---
 qemu-char.c            | 8 ++++----
 savevm.c               | 2 +-
 slirp/misc.c           | 2 +-
 slirp/tcp_subr.c       | 4 ++--
 ui/vnc.c               | 2 +-
 util/oslib-posix.c     | 4 ++--
 util/oslib-win32.c     | 4 ++--
 util/qemu-sockets.c    | 4 ++--
 14 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/block/nbd.c b/block/nbd.c
index 3d711b2..eff683c 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -415,7 +415,7 @@ static int nbd_establish_connection(BlockDriverState *bs)
 
     /* Now that we're connected, set the socket to be non-blocking and
      * kick the reply mechanism.  */
-    socket_set_nonblock(sock);
+    qemu_set_nonblock(sock);
     qemu_aio_set_fd_handler(sock, nbd_reply_ready, NULL,
                             nbd_have_request, s);
 
diff --git a/block/sheepdog.c b/block/sheepdog.c
index bb67c4c..987018e 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -471,7 +471,7 @@ static int connect_to_sdog(BDRVSheepdogState *s)
         qerror_report_err(err);
         error_free(err);
     } else {
-        socket_set_nonblock(fd);
+        qemu_set_nonblock(fd);
     }
 
     return fd;
diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h
index d225f6d..c5174d7 100644
--- a/include/qemu/sockets.h
+++ b/include/qemu/sockets.h
@@ -37,8 +37,8 @@ int qemu_socket(int domain, int type, int protocol);
 int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
 int socket_set_cork(int fd, int v);
 int socket_set_nodelay(int fd);
-void socket_set_block(int fd);
-void socket_set_nonblock(int fd);
+void qemu_set_block(int fd);
+void qemu_set_nonblock(int fd);
 int send_all(int fd, const void *buf, int len1);
 int recv_all(int fd, void *buf, int len1, bool single_read);
 
diff --git a/migration.c b/migration.c
index 7fb2147..3b4b467 100644
--- a/migration.c
+++ b/migration.c
@@ -121,7 +121,7 @@ void process_incoming_migration(QEMUFile *f)
     int fd = qemu_get_fd(f);
 
     assert(fd != -1);
-    socket_set_nonblock(fd);
+    qemu_set_nonblock(fd);
     qemu_coroutine_enter(co, f);
 }
 
diff --git a/nbd.c b/nbd.c
index d1a67ee..85187ff 100644
--- a/nbd.c
+++ b/nbd.c
@@ -386,7 +386,7 @@ static int nbd_send_negotiate(NBDClient *client)
         [28 .. 151]   reserved     (0)
      */
 
-    socket_set_block(csock);
+    qemu_set_block(csock);
     rc = -EINVAL;
 
     TRACE("Beginning negotiation.");
@@ -429,7 +429,7 @@ static int nbd_send_negotiate(NBDClient *client)
     TRACE("Negotiation succeeded.");
     rc = 0;
 fail:
-    socket_set_nonblock(csock);
+    qemu_set_nonblock(csock);
     return rc;
 }
 
@@ -443,7 +443,7 @@ int nbd_receive_negotiate(int csock, const char *name, uint32_t *flags,
 
     TRACE("Receiving negotiation.");
 
-    socket_set_block(csock);
+    qemu_set_block(csock);
     rc = -EINVAL;
 
     if (read_sync(csock, buf, 8) != 8) {
@@ -558,7 +558,7 @@ int nbd_receive_negotiate(int csock, const char *name, uint32_t *flags,
     rc = 0;
 
 fail:
-    socket_set_nonblock(csock);
+    qemu_set_nonblock(csock);
     return rc;
 }
 
diff --git a/net/socket.c b/net/socket.c
index 6c3752b..b5c8e65 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -308,7 +308,7 @@ static int net_socket_mcast_create(struct sockaddr_in *mcastaddr, struct in_addr
         }
     }
 
-    socket_set_nonblock(fd);
+    qemu_set_nonblock(fd);
     return fd;
 fail:
     if (fd >= 0)
@@ -519,7 +519,7 @@ static int net_socket_listen_init(NetClientState *peer,
         perror("socket");
         return -1;
     }
-    socket_set_nonblock(fd);
+    qemu_set_nonblock(fd);
 
     /* allow fast reuse */
     val = 1;
@@ -565,7 +565,7 @@ static int net_socket_connect_init(NetClientState *peer,
         perror("socket");
         return -1;
     }
-    socket_set_nonblock(fd);
+    qemu_set_nonblock(fd);
 
     connected = 0;
     for(;;) {
diff --git a/qemu-char.c b/qemu-char.c
index 936150f..500a582 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2564,7 +2564,7 @@ static int tcp_chr_add_client(CharDriverState *chr, int fd)
     if (s->fd != -1)
 	return -1;
 
-    socket_set_nonblock(fd);
+    qemu_set_nonblock(fd);
     if (s->do_nodelay)
         socket_set_nodelay(fd);
     s->fd = fd;
@@ -2716,7 +2716,7 @@ static CharDriverState *qemu_chr_open_socket_fd(int fd, bool do_nodelay,
         printf("QEMU waiting for connection on: %s\n",
                chr->filename);
         tcp_chr_accept(s->listen_chan, G_IO_IN, chr);
-        socket_set_nonblock(s->listen_fd);
+        qemu_set_nonblock(s->listen_fd);
     }
     return chr;
 }
@@ -2758,7 +2758,7 @@ static CharDriverState *qemu_chr_open_socket(QemuOpts *opts)
     }
 
     if (!is_waitconnect)
-        socket_set_nonblock(fd);
+        qemu_set_nonblock(fd);
 
     chr = qemu_chr_open_socket_fd(fd, do_nodelay, is_listen, is_telnet,
                                   is_waitconnect, &local_err);
@@ -3650,7 +3650,7 @@ static CharDriverState *qmp_chardev_open_serial(ChardevHostdev *serial,
     if (error_is_set(errp)) {
         return NULL;
     }
-    socket_set_nonblock(fd);
+    qemu_set_nonblock(fd);
     return qemu_chr_open_tty_fd(fd);
 #else
     error_setg(errp, "character device backend type 'serial' not supported");
diff --git a/savevm.c b/savevm.c
index 406caa9..b1d8988 100644
--- a/savevm.c
+++ b/savevm.c
@@ -422,7 +422,7 @@ QEMUFile *qemu_fopen_socket(int fd, const char *mode)
 
     s->fd = fd;
     if (mode[0] == 'w') {
-        socket_set_block(s->fd);
+        qemu_set_block(s->fd);
         s->file = qemu_fopen_ops(s, &socket_write_ops);
     } else {
         s->file = qemu_fopen_ops(s, &socket_read_ops);
diff --git a/slirp/misc.c b/slirp/misc.c
index 6b9c2c4..8ecced5 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -215,7 +215,7 @@ fork_exec(struct socket *so, const char *ex, int do_pty)
                 qemu_setsockopt(so->s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int));
                 opt = 1;
                 qemu_setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
-		socket_set_nonblock(so->s);
+		qemu_set_nonblock(so->s);
 
 		/* Append the telnet options now */
                 if (so->so_m != NULL && do_pty == 1)  {
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index 84a6bb5..e98ce1a 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -336,7 +336,7 @@ int tcp_fconnect(struct socket *so)
     int opt, s=so->s;
     struct sockaddr_in addr;
 
-    socket_set_nonblock(s);
+    qemu_set_nonblock(s);
     opt = 1;
     qemu_setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
     opt = 1;
@@ -425,7 +425,7 @@ void tcp_connect(struct socket *inso)
         tcp_close(sototcpcb(so)); /* This will sofree() as well */
         return;
     }
-    socket_set_nonblock(s);
+    qemu_set_nonblock(s);
     opt = 1;
     qemu_setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int));
     opt = 1;
diff --git a/ui/vnc.c b/ui/vnc.c
index bbe1e0f..5ddb696 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -2732,7 +2732,7 @@ static void vnc_connect(VncDisplay *vd, int csock, int skipauth, bool websocket)
 
     VNC_DEBUG("New client on socket %d\n", csock);
     vd->dcl.idle = 0;
-    socket_set_nonblock(vs->csock);
+    qemu_set_nonblock(vs->csock);
 #ifdef CONFIG_VNC_WS
     if (websocket) {
         vs->websocket = 1;
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index 433dd68..4e4b819 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -134,14 +134,14 @@ void qemu_vfree(void *ptr)
     free(ptr);
 }
 
-void socket_set_block(int fd)
+void qemu_set_block(int fd)
 {
     int f;
     f = fcntl(fd, F_GETFL);
     fcntl(fd, F_SETFL, f & ~O_NONBLOCK);
 }
 
-void socket_set_nonblock(int fd)
+void qemu_set_nonblock(int fd)
 {
     int f;
     f = fcntl(fd, F_GETFL);
diff --git a/util/oslib-win32.c b/util/oslib-win32.c
index 640194c..dcfa0c2 100644
--- a/util/oslib-win32.c
+++ b/util/oslib-win32.c
@@ -100,14 +100,14 @@ struct tm *localtime_r(const time_t *timep, struct tm *result)
     return p;
 }
 
-void socket_set_block(int fd)
+void qemu_set_block(int fd)
 {
     unsigned long opt = 0;
     WSAEventSelect(fd, NULL, 0);
     ioctlsocket(fd, FIONBIO, &opt);
 }
 
-void socket_set_nonblock(int fd)
+void qemu_set_nonblock(int fd)
 {
     unsigned long opt = 1;
     ioctlsocket(fd, FIONBIO, &opt);
diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index b6b78f5..b632a74 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -277,7 +277,7 @@ static int inet_connect_addr(struct addrinfo *addr, bool *in_progress,
     }
     qemu_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
     if (connect_state != NULL) {
-        socket_set_nonblock(sock);
+        qemu_set_nonblock(sock);
     }
     /* connect to peer */
     do {
@@ -737,7 +737,7 @@ int unix_connect_opts(QemuOpts *opts, Error **errp,
         connect_state = g_malloc0(sizeof(*connect_state));
         connect_state->callback = callback;
         connect_state->opaque = opaque;
-        socket_set_nonblock(sock);
+        qemu_set_nonblock(sock);
     }
 
     memset(&un, 0, sizeof(un));
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH v2 2/4] net: ensure "socket" backend uses non-blocking fds
  2013-03-27  9:10 [Qemu-devel] [PATCH v2 0/4] monitor: do not rely on O_NONBLOCK for passed file descriptors Stefan Hajnoczi
  2013-03-27  9:10 ` [Qemu-devel] [PATCH v2 1/4] oslib-posix: rename socket_set_nonblock() to qemu_set_nonblock() Stefan Hajnoczi
@ 2013-03-27  9:10 ` Stefan Hajnoczi
  2013-03-27  9:10 ` [Qemu-devel] [PATCH v2 3/4] qemu-socket: set passed fd non-blocking in socket_connect() Stefan Hajnoczi
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Stefan Hajnoczi @ 2013-03-27  9:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: Anthony Liguori, Juan Quintela, mprivozn, coreyb, david.pravec,
	Luiz Capitulino, Stefan Hajnoczi

There are several code paths in net_init_socket() depending on how the
socket is created: file descriptor passing, UDP multicast, TCP, or UDP.
Some of these support both listen and connect.

Not all code paths set the socket to non-blocking.  This patch addresses
the file descriptor passing and UDP cases which were missing
socket_set_nonblock(fd) calls.

I considered moving socket_set_nonblock(fd) to a central location but it
turns out the code paths are different enough to require non-blocking at
different places.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 net/socket.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/net/socket.c b/net/socket.c
index b5c8e65..87af1d3 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -674,6 +674,7 @@ static int net_socket_udp_init(NetClientState *peer,
         closesocket(fd);
         return -1;
     }
+    qemu_set_nonblock(fd);
 
     s = net_socket_fd_init(peer, model, name, fd, 0);
     if (!s) {
@@ -712,7 +713,11 @@ int net_init_socket(const NetClientOptions *opts, const char *name,
         int fd;
 
         fd = monitor_handle_fd_param(cur_mon, sock->fd);
-        if (fd == -1 || !net_socket_fd_init(peer, "socket", name, fd, 1)) {
+        if (fd == -1) {
+            return -1;
+        }
+        qemu_set_nonblock(fd);
+        if (!net_socket_fd_init(peer, "socket", name, fd, 1)) {
             return -1;
         }
         return 0;
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH v2 3/4] qemu-socket: set passed fd non-blocking in socket_connect()
  2013-03-27  9:10 [Qemu-devel] [PATCH v2 0/4] monitor: do not rely on O_NONBLOCK for passed file descriptors Stefan Hajnoczi
  2013-03-27  9:10 ` [Qemu-devel] [PATCH v2 1/4] oslib-posix: rename socket_set_nonblock() to qemu_set_nonblock() Stefan Hajnoczi
  2013-03-27  9:10 ` [Qemu-devel] [PATCH v2 2/4] net: ensure "socket" backend uses non-blocking fds Stefan Hajnoczi
@ 2013-03-27  9:10 ` Stefan Hajnoczi
  2013-03-27  9:10 ` [Qemu-devel] [PATCH v2 4/4] chardev: clear O_NONBLOCK on SCM_RIGHTS file descriptors Stefan Hajnoczi
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Stefan Hajnoczi @ 2013-03-27  9:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: Anthony Liguori, Juan Quintela, mprivozn, coreyb, david.pravec,
	Luiz Capitulino, Stefan Hajnoczi

socket_connect() sets non-blocking on TCP or UNIX domain sockets if a
callback function is passed.  Do the same for file descriptor passing,
otherwise we could unexpectedly be using a blocking file descriptor.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 util/qemu-sockets.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index b632a74..94581aa 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -910,6 +910,7 @@ int socket_connect(SocketAddress *addr, Error **errp,
     case SOCKET_ADDRESS_KIND_FD:
         fd = monitor_get_fd(cur_mon, addr->fd->str, errp);
         if (callback) {
+            qemu_set_nonblock(fd);
             callback(fd, opaque);
         }
         break;
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH v2 4/4] chardev: clear O_NONBLOCK on SCM_RIGHTS file descriptors
  2013-03-27  9:10 [Qemu-devel] [PATCH v2 0/4] monitor: do not rely on O_NONBLOCK for passed file descriptors Stefan Hajnoczi
                   ` (2 preceding siblings ...)
  2013-03-27  9:10 ` [Qemu-devel] [PATCH v2 3/4] qemu-socket: set passed fd non-blocking in socket_connect() Stefan Hajnoczi
@ 2013-03-27  9:10 ` Stefan Hajnoczi
  2013-03-27 11:48 ` [Qemu-devel] [PATCH v2 0/4] monitor: do not rely on O_NONBLOCK for passed " Eric Blake
  2013-03-27 13:17 ` Luiz Capitulino
  5 siblings, 0 replies; 10+ messages in thread
From: Stefan Hajnoczi @ 2013-03-27  9:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: Anthony Liguori, Juan Quintela, mprivozn, coreyb, david.pravec,
	Luiz Capitulino, Stefan Hajnoczi

When we receive a file descriptor over a UNIX domain socket the
O_NONBLOCK flag is preserved.  Clear the O_NONBLOCK flag and rely on
QEMU file descriptor users like migration, SPICE, VNC, block layer, and
others to set non-blocking only when necessary.

This change ensures we don't accidentally expose O_NONBLOCK in the QMP
API.  QMP clients should not need to get the non-blocking state
"correct".

A recent real-world example was when libvirt passed a non-blocking TCP
socket for migration where we expected a blocking socket.  The source
QEMU produced a corrupted migration stream since its code did not cope
with non-blocking sockets.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 qemu-char.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/qemu-char.c b/qemu-char.c
index 500a582..091f2dc 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2434,6 +2434,9 @@ static void unix_process_msgfd(CharDriverState *chr, struct msghdr *msg)
         if (fd < 0)
             continue;
 
+        /* O_NONBLOCK is preserved across SCM_RIGHTS so reset it */
+        qemu_set_block(fd);
+
 #ifndef MSG_CMSG_CLOEXEC
         qemu_set_cloexec(fd);
 #endif
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/4] monitor: do not rely on O_NONBLOCK for passed file descriptors
  2013-03-27  9:10 [Qemu-devel] [PATCH v2 0/4] monitor: do not rely on O_NONBLOCK for passed file descriptors Stefan Hajnoczi
                   ` (3 preceding siblings ...)
  2013-03-27  9:10 ` [Qemu-devel] [PATCH v2 4/4] chardev: clear O_NONBLOCK on SCM_RIGHTS file descriptors Stefan Hajnoczi
@ 2013-03-27 11:48 ` Eric Blake
  2013-03-27 13:17 ` Luiz Capitulino
  5 siblings, 0 replies; 10+ messages in thread
From: Eric Blake @ 2013-03-27 11:48 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: Anthony Liguori, david.pravec, Juan Quintela, mprivozn, coreyb,
	qemu-devel, Luiz Capitulino

[-- Attachment #1: Type: text/plain, Size: 1803 bytes --]

On 03/27/2013 03:10 AM, Stefan Hajnoczi wrote:
> There are several places where QEMU accidentally relies on the O_NONBLOCK state
> of passed file descriptors.  Exposing O_NONBLOCK state makes it part of the QMP
> API whenever getfd or fdset_add_fd are used!
> 
> Whether or not QEMU will use O_NONBLOCK is an implementation detail and should
> be hidden from QMP clients.
> 
> This patch series addresses this in 3 steps:
> 
> 1. Fix callers of monitor_handle_fd_param(), monitor_fdset_get_fd(), and
>    monitor_get_fd() that depend on O_NONBLOCK being set.  Luckily there are
>    only two instances and they are fixed in Patches 1 & 2.

Description is now off after rebase, but the cover letter isn't
committed, so no big deal.

> 
> 2. Rename socket_set_nonblock() to qemu_set_nonblock() just like
>    qemu_set_cloexec().  This makes code cleaner when working with arbitrary
>    file descriptors that may not be sockets.  See Patch 3.
> 
> 3. Clear O_NONBLOCK when a chardev receives file descriptors.  From now on QEMU
>    can assume that passed file descriptors are in blocking mode.  Simply use
>    qemu_set_nonblock(fd) if you want to enable O_NONBLOCK.  See Patch 4.

Series: Reviewed-by: Eric Blake <eblake@redhat.com>

> v2:
>  * Rename socket_set_nonblock() in Patch 1 to avoid code churn [eblake]
>  * Avoid qemu_set_block(-1) calls that clobber errno [quintela]
> 
> Stefan Hajnoczi (4):
>   oslib-posix: rename socket_set_nonblock() to qemu_set_nonblock()
>   net: ensure "socket" backend uses non-blocking fds
>   qemu-socket: set passed fd non-blocking in socket_connect()
>   chardev: clear O_NONBLOCK on SCM_RIGHTS file descriptors

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 621 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/4] monitor: do not rely on O_NONBLOCK for passed file descriptors
  2013-03-27  9:10 [Qemu-devel] [PATCH v2 0/4] monitor: do not rely on O_NONBLOCK for passed file descriptors Stefan Hajnoczi
                   ` (4 preceding siblings ...)
  2013-03-27 11:48 ` [Qemu-devel] [PATCH v2 0/4] monitor: do not rely on O_NONBLOCK for passed " Eric Blake
@ 2013-03-27 13:17 ` Luiz Capitulino
  2013-04-03 15:05   ` mdroth
  5 siblings, 1 reply; 10+ messages in thread
From: Luiz Capitulino @ 2013-03-27 13:17 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: Anthony Liguori, david.pravec, Juan Quintela, mprivozn, coreyb,
	qemu-devel

On Wed, 27 Mar 2013 10:10:42 +0100
Stefan Hajnoczi <stefanha@redhat.com> wrote:

> There are several places where QEMU accidentally relies on the O_NONBLOCK state
> of passed file descriptors.  Exposing O_NONBLOCK state makes it part of the QMP
> API whenever getfd or fdset_add_fd are used!
> 
> Whether or not QEMU will use O_NONBLOCK is an implementation detail and should
> be hidden from QMP clients.
> 
> This patch series addresses this in 3 steps:

Nice series:

Applied to the qmp branch, thanks.

> 
> 1. Fix callers of monitor_handle_fd_param(), monitor_fdset_get_fd(), and
>    monitor_get_fd() that depend on O_NONBLOCK being set.  Luckily there are
>    only two instances and they are fixed in Patches 1 & 2.
> 
> 2. Rename socket_set_nonblock() to qemu_set_nonblock() just like
>    qemu_set_cloexec().  This makes code cleaner when working with arbitrary
>    file descriptors that may not be sockets.  See Patch 3.
> 
> 3. Clear O_NONBLOCK when a chardev receives file descriptors.  From now on QEMU
>    can assume that passed file descriptors are in blocking mode.  Simply use
>    qemu_set_nonblock(fd) if you want to enable O_NONBLOCK.  See Patch 4.
> 
> This fixes live migration with recent libvirt.  Libvirt checks if QEMU supports
> file descriptor passing and, if yes, hands QEMU a socket with O_NONBLOCK set.
> The migrate fd:<foo> code assumes the socket is in blocking mode.  The result
> is a corrupted migration stream.  For more info on this bug, see:
> 
> https://bugzilla.redhat.com/show_bug.cgi?id=923124
> 
> Note that Michal Privoznik <mprivozn@redhat.com> also sent a libvirt patch so
> that old QEMUs work with new libvirts:
> 
> https://www.redhat.com/archives/libvir-list/2013-March/msg01486.html
> 
> My patch series fixes the QMP API and allows old libvirts to work again with
> new QEMUs.
> 
> v2:
>  * Rename socket_set_nonblock() in Patch 1 to avoid code churn [eblake]
>  * Avoid qemu_set_block(-1) calls that clobber errno [quintela]
> 
> Stefan Hajnoczi (4):
>   oslib-posix: rename socket_set_nonblock() to qemu_set_nonblock()
>   net: ensure "socket" backend uses non-blocking fds
>   qemu-socket: set passed fd non-blocking in socket_connect()
>   chardev: clear O_NONBLOCK on SCM_RIGHTS file descriptors
> 
>  block/nbd.c            |  2 +-
>  block/sheepdog.c       |  2 +-
>  include/qemu/sockets.h |  4 ++--
>  migration.c            |  2 +-
>  nbd.c                  |  8 ++++----
>  net/socket.c           | 13 +++++++++----
>  qemu-char.c            | 11 +++++++----
>  savevm.c               |  2 +-
>  slirp/misc.c           |  2 +-
>  slirp/tcp_subr.c       |  4 ++--
>  ui/vnc.c               |  2 +-
>  util/oslib-posix.c     |  4 ++--
>  util/oslib-win32.c     |  4 ++--
>  util/qemu-sockets.c    |  5 +++--
>  14 files changed, 37 insertions(+), 28 deletions(-)
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/4] monitor: do not rely on O_NONBLOCK for passed file descriptors
  2013-03-27 13:17 ` Luiz Capitulino
@ 2013-04-03 15:05   ` mdroth
  2013-04-03 15:24     ` Luiz Capitulino
  0 siblings, 1 reply; 10+ messages in thread
From: mdroth @ 2013-04-03 15:05 UTC (permalink / raw)
  To: Luiz Capitulino
  Cc: Anthony Liguori, Juan Quintela, mprivozn, coreyb, mjt,
	david.pravec, qemu-devel, Stefan Hajnoczi

On Wed, Mar 27, 2013 at 09:17:30AM -0400, Luiz Capitulino wrote:
> On Wed, 27 Mar 2013 10:10:42 +0100
> Stefan Hajnoczi <stefanha@redhat.com> wrote:
> 
> > There are several places where QEMU accidentally relies on the O_NONBLOCK state
> > of passed file descriptors.  Exposing O_NONBLOCK state makes it part of the QMP
> > API whenever getfd or fdset_add_fd are used!
> > 
> > Whether or not QEMU will use O_NONBLOCK is an implementation detail and should
> > be hidden from QMP clients.
> > 
> > This patch series addresses this in 3 steps:
> 
> Nice series:
> 
> Applied to the qmp branch, thanks.

Hi Luiz,

Eric/mjt have noted that this series fixes a number of issues in 1.4.0
and have requested it for 1.4.1

http://thread.gmane.org/gmane.comp.emulators.qemu/203851

The cut-off for 1.4.1 is Tuesday. Do you plan to send a pull for these soon?

> 
> > 
> > 1. Fix callers of monitor_handle_fd_param(), monitor_fdset_get_fd(), and
> >    monitor_get_fd() that depend on O_NONBLOCK being set.  Luckily there are
> >    only two instances and they are fixed in Patches 1 & 2.
> > 
> > 2. Rename socket_set_nonblock() to qemu_set_nonblock() just like
> >    qemu_set_cloexec().  This makes code cleaner when working with arbitrary
> >    file descriptors that may not be sockets.  See Patch 3.
> > 
> > 3. Clear O_NONBLOCK when a chardev receives file descriptors.  From now on QEMU
> >    can assume that passed file descriptors are in blocking mode.  Simply use
> >    qemu_set_nonblock(fd) if you want to enable O_NONBLOCK.  See Patch 4.
> > 
> > This fixes live migration with recent libvirt.  Libvirt checks if QEMU supports
> > file descriptor passing and, if yes, hands QEMU a socket with O_NONBLOCK set.
> > The migrate fd:<foo> code assumes the socket is in blocking mode.  The result
> > is a corrupted migration stream.  For more info on this bug, see:
> > 
> > https://bugzilla.redhat.com/show_bug.cgi?id=923124
> > 
> > Note that Michal Privoznik <mprivozn@redhat.com> also sent a libvirt patch so
> > that old QEMUs work with new libvirts:
> > 
> > https://www.redhat.com/archives/libvir-list/2013-March/msg01486.html
> > 
> > My patch series fixes the QMP API and allows old libvirts to work again with
> > new QEMUs.
> > 
> > v2:
> >  * Rename socket_set_nonblock() in Patch 1 to avoid code churn [eblake]
> >  * Avoid qemu_set_block(-1) calls that clobber errno [quintela]
> > 
> > Stefan Hajnoczi (4):
> >   oslib-posix: rename socket_set_nonblock() to qemu_set_nonblock()
> >   net: ensure "socket" backend uses non-blocking fds
> >   qemu-socket: set passed fd non-blocking in socket_connect()
> >   chardev: clear O_NONBLOCK on SCM_RIGHTS file descriptors
> > 
> >  block/nbd.c            |  2 +-
> >  block/sheepdog.c       |  2 +-
> >  include/qemu/sockets.h |  4 ++--
> >  migration.c            |  2 +-
> >  nbd.c                  |  8 ++++----
> >  net/socket.c           | 13 +++++++++----
> >  qemu-char.c            | 11 +++++++----
> >  savevm.c               |  2 +-
> >  slirp/misc.c           |  2 +-
> >  slirp/tcp_subr.c       |  4 ++--
> >  ui/vnc.c               |  2 +-
> >  util/oslib-posix.c     |  4 ++--
> >  util/oslib-win32.c     |  4 ++--
> >  util/qemu-sockets.c    |  5 +++--
> >  14 files changed, 37 insertions(+), 28 deletions(-)
> > 
> 
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/4] monitor: do not rely on O_NONBLOCK for passed file descriptors
  2013-04-03 15:05   ` mdroth
@ 2013-04-03 15:24     ` Luiz Capitulino
  2013-04-03 15:31       ` Luiz Capitulino
  0 siblings, 1 reply; 10+ messages in thread
From: Luiz Capitulino @ 2013-04-03 15:24 UTC (permalink / raw)
  To: mdroth
  Cc: Anthony Liguori, Juan Quintela, mprivozn, coreyb, mjt,
	david.pravec, qemu-devel, Stefan Hajnoczi

On Wed, 3 Apr 2013 10:05:40 -0500
mdroth <mdroth@linux.vnet.ibm.com> wrote:

> On Wed, Mar 27, 2013 at 09:17:30AM -0400, Luiz Capitulino wrote:
> > On Wed, 27 Mar 2013 10:10:42 +0100
> > Stefan Hajnoczi <stefanha@redhat.com> wrote:
> > 
> > > There are several places where QEMU accidentally relies on the O_NONBLOCK state
> > > of passed file descriptors.  Exposing O_NONBLOCK state makes it part of the QMP
> > > API whenever getfd or fdset_add_fd are used!
> > > 
> > > Whether or not QEMU will use O_NONBLOCK is an implementation detail and should
> > > be hidden from QMP clients.
> > > 
> > > This patch series addresses this in 3 steps:
> > 
> > Nice series:
> > 
> > Applied to the qmp branch, thanks.
> 
> Hi Luiz,
> 
> Eric/mjt have noted that this series fixes a number of issues in 1.4.0
> and have requested it for 1.4.1
> 
> http://thread.gmane.org/gmane.comp.emulators.qemu/203851
> 
> The cut-off for 1.4.1 is Tuesday. Do you plan to send a pull for these soon?

Sure, I can do that. And thanks to remind me.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/4] monitor: do not rely on O_NONBLOCK for passed file descriptors
  2013-04-03 15:24     ` Luiz Capitulino
@ 2013-04-03 15:31       ` Luiz Capitulino
  0 siblings, 0 replies; 10+ messages in thread
From: Luiz Capitulino @ 2013-04-03 15:31 UTC (permalink / raw)
  To: Luiz Capitulino
  Cc: Anthony Liguori, Juan Quintela, qemu-devel, mprivozn, coreyb, mjt,
	david.pravec, mdroth, Stefan Hajnoczi

On Wed, 3 Apr 2013 11:24:38 -0400
Luiz Capitulino <lcapitulino@redhat.com> wrote:

> On Wed, 3 Apr 2013 10:05:40 -0500
> mdroth <mdroth@linux.vnet.ibm.com> wrote:
> 
> > On Wed, Mar 27, 2013 at 09:17:30AM -0400, Luiz Capitulino wrote:
> > > On Wed, 27 Mar 2013 10:10:42 +0100
> > > Stefan Hajnoczi <stefanha@redhat.com> wrote:
> > > 
> > > > There are several places where QEMU accidentally relies on the O_NONBLOCK state
> > > > of passed file descriptors.  Exposing O_NONBLOCK state makes it part of the QMP
> > > > API whenever getfd or fdset_add_fd are used!
> > > > 
> > > > Whether or not QEMU will use O_NONBLOCK is an implementation detail and should
> > > > be hidden from QMP clients.
> > > > 
> > > > This patch series addresses this in 3 steps:
> > > 
> > > Nice series:
> > > 
> > > Applied to the qmp branch, thanks.
> > 
> > Hi Luiz,
> > 
> > Eric/mjt have noted that this series fixes a number of issues in 1.4.0
> > and have requested it for 1.4.1
> > 
> > http://thread.gmane.org/gmane.comp.emulators.qemu/203851
> > 
> > The cut-off for 1.4.1 is Tuesday. Do you plan to send a pull for these soon?
> 
> Sure, I can do that. And thanks to remind me.

Actually, I can't cherry-pick it cleanly.

Stefan, would you mind to backport this series to v1.4.1 yourself?

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2013-04-03 15:47 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-03-27  9:10 [Qemu-devel] [PATCH v2 0/4] monitor: do not rely on O_NONBLOCK for passed file descriptors Stefan Hajnoczi
2013-03-27  9:10 ` [Qemu-devel] [PATCH v2 1/4] oslib-posix: rename socket_set_nonblock() to qemu_set_nonblock() Stefan Hajnoczi
2013-03-27  9:10 ` [Qemu-devel] [PATCH v2 2/4] net: ensure "socket" backend uses non-blocking fds Stefan Hajnoczi
2013-03-27  9:10 ` [Qemu-devel] [PATCH v2 3/4] qemu-socket: set passed fd non-blocking in socket_connect() Stefan Hajnoczi
2013-03-27  9:10 ` [Qemu-devel] [PATCH v2 4/4] chardev: clear O_NONBLOCK on SCM_RIGHTS file descriptors Stefan Hajnoczi
2013-03-27 11:48 ` [Qemu-devel] [PATCH v2 0/4] monitor: do not rely on O_NONBLOCK for passed " Eric Blake
2013-03-27 13:17 ` Luiz Capitulino
2013-04-03 15:05   ` mdroth
2013-04-03 15:24     ` Luiz Capitulino
2013-04-03 15:31       ` Luiz Capitulino

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).