As documented, for "local", the migration channel must be direct UNIX
socket connection from source to target (except for CPR_EXEC mode). We
can't check for it being "direct", but let's at least check that we deal
with UNIX socket.

Signed-off-by: Vladimir Sementsov-Ogievskiy <[email protected]>
---
 migration/fd.c        | 14 ++++++++++++++
 migration/migration.c | 13 +++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/migration/fd.c b/migration/fd.c
index 78a27caca22..4a891e814a4 100644
--- a/migration/fd.c
+++ b/migration/fd.c
@@ -39,6 +39,20 @@ static bool fd_is_pipe(int fd)
 
 static bool migration_fd_valid(int fd, Error **errp)
 {
+    if (migrate_local() && migrate_mode() != MIG_MODE_CPR_EXEC) {
+        struct sockaddr_storage ss;
+        socklen_t sslen = sizeof(ss);
+
+        if (getsockname(fd, (struct sockaddr *)&ss, &sslen) < 0 ||
+            ss.ss_family != AF_UNIX) {
+            error_setg(errp,
+                       "local migration requires a UNIX domain socket 
channel");
+            return false;
+        }
+
+        return true;
+    }
+
     if (fd_is_socket(fd) || fd_is_pipe(fd)) {
         return true;
     }
diff --git a/migration/migration.c b/migration/migration.c
index 9df6da131ce..e30fce30a56 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -260,6 +260,19 @@ 
migration_capabilities_and_transport_compatible(MigrationAddress *addr,
                                        errp);
     }
 
+    if (migrate_local() && migrate_mode() != MIG_MODE_CPR_EXEC &&
+        (addr->transport != MIGRATION_ADDRESS_TYPE_SOCKET ||
+         (addr->u.socket.type != SOCKET_ADDRESS_TYPE_UNIX &&
+          addr->u.socket.type != SOCKET_ADDRESS_TYPE_FD))) {
+        /*
+         * For SOCKET_ADDRESS_TYPE_FD we do check the fd itself later
+         * in migration_fd_valid().
+         */
+        error_setg(errp,
+                   "local migration requires a UNIX domain socket channel");
+        return false;
+    }
+
     return true;
 }
 
-- 
2.43.0


Reply via email to