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