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
