From 1723d6b1cfe6572881f578bce3aa25185b81b148 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Fri, 22 Dec 2017 11:04:30 +0000 Subject: sockets: allow SocketAddress 'fd' to reference numeric file descriptors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SocketAddress 'fd' kind accepts the name of a file descriptor passed to the monitor with the 'getfd' command. This makes it impossible to use the 'fd' kind in cases where a monitor is not available. This can apply in handling command line argv at startup, or simply if internal code wants to use SocketAddress and pass a numeric FD it has acquired from elsewhere. Fortunately the 'getfd' command mandated that the FD names must not start with a leading digit. We can thus safely extend semantics of the SocketAddress 'fd' kind, to allow a purely numeric name to reference an file descriptor that QEMU already has open. There will be restrictions on when each kind can be used. In codepaths where we are handling a monitor command (ie cur_mon != NULL), we will only support use of named file descriptors as before. Use of FD numbers is still not permitted for monitor commands. In codepaths where we are not handling a monitor command (ie cur_mon == NULL), we will not support named file descriptors. Instead we can reference FD numers explicitly. This allows the app spawning QEMU to intentionally "leak" a pre-opened socket to QEMU and reference that in a SocketAddress definition, or for code inside QEMU to pass pre-opened FDs around. Reviewed-by: Eric Blake Reviewed-by: Marc-André Lureau Signed-off-by: Daniel P. Berrange --- util/qemu-sockets.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'util') diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c index 6dc4613855..8bd8bb64eb 100644 --- a/util/qemu-sockets.c +++ b/util/qemu-sockets.c @@ -1044,9 +1044,19 @@ fail: static int socket_get_fd(const char *fdstr, Error **errp) { - int fd = monitor_get_fd(cur_mon, fdstr, errp); - if (fd < 0) { - return -1; + int fd; + if (cur_mon) { + fd = monitor_get_fd(cur_mon, fdstr, errp); + if (fd < 0) { + return -1; + } + } else { + if (qemu_strtoi(fdstr, NULL, 10, &fd) < 0) { + error_setg_errno(errp, errno, + "Unable to parse FD number %s", + fdstr); + return -1; + } } if (!fd_is_socket(fd)) { error_setg(errp, "File descriptor '%s' is not a socket", fdstr); -- cgit v1.2.1