05bba0
From 24a9e4d46608ccdcec53eeccc40b7a5d3fb7c9c8 Mon Sep 17 00:00:00 2001
05bba0
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
05bba0
Date: Fri, 16 Jan 2015 17:35:36 +0100
05bba0
Subject: [PATCH 04/16] Handle bi-directional communication for fd migration
05bba0
05bba0
Message-id: <1421429737-23581-3-git-send-email-dgilbert@redhat.com>
05bba0
Patchwork-id: 63333
05bba0
O-Subject: [RHEL-7.2 qemu-kvm PATCH 2/3] Handle bi-directional communication for fd migration
05bba0
Bugzilla: 1086168
05bba0
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
05bba0
RH-Acked-by: Amit Shah <amit.shah@redhat.com>
05bba0
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
05bba0
05bba0
From: Cristian Klein <cristian.klein@cs.umu.se>
05bba0
05bba0
libvirt prefers opening the TCP connection itself, for two reasons.
05bba0
First, connection failed errors can be detected easier, without having
05bba0
to parse qemu's error output.
05bba0
Second, libvirt might be asked to secure the transfer by tunnelling the
05bba0
communication through an TLS layer.
05bba0
Therefore, libvirt opens the TCP connection itself and passes an FD to qemu
05bba0
using QMP and a POSIX-specific mechanism.
05bba0
05bba0
Hence, in order to make the reverse-path work in such cases, qemu needs to
05bba0
distinguish if the transmitted FD is a socket (reverse-path available)
05bba0
or not (reverse-path might not be available) and use the corresponding
05bba0
abstraction.
05bba0
05bba0
Signed-off-by: Cristian Klein <cristian.klein@cs.umu.se>
05bba0
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
05bba0
Reviewed-by: Amit Shah <amit.shah@redhat.com>
05bba0
Signed-off-by: Amit Shah <amit.shah@redhat.com>
05bba0
(cherry picked from commit 131fe9b843f9a1e55fcbf2457c9cb25c3711b9d8)
05bba0
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
05bba0
---
05bba0
 migration-fd.c | 24 ++++++++++++++++++++++--
05bba0
 1 file changed, 22 insertions(+), 2 deletions(-)
05bba0
05bba0
diff --git a/migration-fd.c b/migration-fd.c
05bba0
index 3d4613c..3c98c3c 100644
05bba0
--- a/migration-fd.c
05bba0
+++ b/migration-fd.c
05bba0
@@ -30,13 +30,29 @@
05bba0
     do { } while (0)
05bba0
 #endif
05bba0
 
05bba0
+static bool fd_is_socket(int fd)
05bba0
+{
05bba0
+    struct stat stat;
05bba0
+    int ret = fstat(fd, &stat;;
05bba0
+    if (ret == -1) {
05bba0
+        /* When in doubt say no */
05bba0
+        return false;
05bba0
+    }
05bba0
+    return S_ISSOCK(stat.st_mode);
05bba0
+}
05bba0
+
05bba0
 void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **errp)
05bba0
 {
05bba0
     int fd = monitor_get_fd(cur_mon, fdname, errp);
05bba0
     if (fd == -1) {
05bba0
         return;
05bba0
     }
05bba0
-    s->file = qemu_fdopen(fd, "wb");
05bba0
+
05bba0
+    if (fd_is_socket(fd)) {
05bba0
+        s->file = qemu_fopen_socket(fd, "wb");
05bba0
+    } else {
05bba0
+        s->file = qemu_fdopen(fd, "wb");
05bba0
+    }
05bba0
 
05bba0
     migrate_fd_connect(s);
05bba0
 }
05bba0
@@ -57,7 +73,11 @@ void fd_start_incoming_migration(const char *infd, Error **errp)
05bba0
     DPRINTF("Attempting to start an incoming migration via fd\n");
05bba0
 
05bba0
     fd = strtol(infd, NULL, 0);
05bba0
-    f = qemu_fdopen(fd, "rb");
05bba0
+    if (fd_is_socket(fd)) {
05bba0
+        f = qemu_fopen_socket(fd, "rb");
05bba0
+    } else {
05bba0
+        f = qemu_fdopen(fd, "rb");
05bba0
+    }
05bba0
     if(f == NULL) {
05bba0
         error_setg_errno(errp, errno, "failed to open the source descriptor");
05bba0
         return;
05bba0
-- 
05bba0
1.8.3.1
05bba0