If we receive a file descriptor that points to a regular file, there's nothing stopping us from doing multifd migration with fixed-ram to that file.
Enable the fd: URI to work with multifd + fixed-ram. Signed-off-by: Fabiano Rosas <faro...@suse.de> --- migration/fd.c | 30 ++++++++++++++++++++++++++++++ migration/fd.h | 1 + migration/file.c | 12 +++++++++--- migration/migration.c | 4 ++++ 4 files changed, 44 insertions(+), 3 deletions(-) diff --git a/migration/fd.c b/migration/fd.c index 0eb677dcae..b7e4d071a4 100644 --- a/migration/fd.c +++ b/migration/fd.c @@ -19,14 +19,28 @@ #include "fd.h" #include "migration.h" #include "monitor/monitor.h" +#include "io/channel-file.h" #include "io/channel-util.h" +#include "options.h" #include "trace.h" +static struct FdOutgoingArgs { + int fd; +} outgoing_args; + +int fd_args_get_fd(void) +{ + return outgoing_args.fd; +} + void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **errp) { QIOChannel *ioc; int fd = monitor_get_fd(monitor_cur(), fdname, errp); + + outgoing_args.fd = -1; + if (fd == -1) { return; } @@ -38,6 +52,8 @@ void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error ** return; } + outgoing_args.fd = fd; + qio_channel_set_name(ioc, "migration-fd-outgoing"); migration_channel_connect(s, ioc, NULL, NULL); object_unref(OBJECT(ioc)); @@ -73,4 +89,18 @@ void fd_start_incoming_migration(const char *fdname, Error **errp) fd_accept_incoming_migration, NULL, NULL, g_main_context_get_thread_default()); + + if (migrate_multifd()) { + int channels = migrate_multifd_channels(); + + while (channels--) { + ioc = QIO_CHANNEL(qio_channel_file_new_fd(fd)); + + qio_channel_set_name(ioc, "migration-fd-incoming"); + qio_channel_add_watch_full(ioc, G_IO_IN, + fd_accept_incoming_migration, + NULL, NULL, + g_main_context_get_thread_default()); + } + } } diff --git a/migration/fd.h b/migration/fd.h index b901bc014e..1be980c130 100644 --- a/migration/fd.h +++ b/migration/fd.h @@ -20,4 +20,5 @@ void fd_start_incoming_migration(const char *fdname, Error **errp); void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **errp); +int fd_args_get_fd(void); #endif diff --git a/migration/file.c b/migration/file.c index 1a18e608fc..27ccfc6a1d 100644 --- a/migration/file.c +++ b/migration/file.c @@ -11,6 +11,7 @@ #include "qemu/error-report.h" #include "qapi/error.h" #include "channel.h" +#include "fd.h" #include "file.h" #include "migration.h" #include "io/channel-file.h" @@ -58,10 +59,15 @@ bool file_send_channel_create(gpointer opaque, Error **errp) { QIOChannelFile *ioc; int flags = O_WRONLY; + int fd = fd_args_get_fd(); - ioc = qio_channel_file_new_path(outgoing_args.fname, flags, 0, errp); - if (!ioc) { - return false; + if (fd && fd != -1) { + ioc = qio_channel_file_new_fd(fd); + } else { + ioc = qio_channel_file_new_path(outgoing_args.fname, flags, 0, errp); + if (!ioc) { + return false; + } } if (!multifd_channel_connect(opaque, QIO_CHANNEL(ioc), errp)) { diff --git a/migration/migration.c b/migration/migration.c index 32b291a282..ce7e6f5065 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -134,6 +134,10 @@ static bool transport_supports_multi_channels(MigrationAddress *addr) if (addr->transport == MIGRATION_ADDRESS_TYPE_SOCKET) { SocketAddress *saddr = &addr->u.socket; + if (saddr->type == SOCKET_ADDRESS_TYPE_FD) { + return migrate_fixed_ram(); + } + return (saddr->type == SOCKET_ADDRESS_TYPE_INET || saddr->type == SOCKET_ADDRESS_TYPE_UNIX || saddr->type == SOCKET_ADDRESS_TYPE_VSOCK); -- 2.35.3