From: Nikolay Borisov <nbori...@suse.com>

This is a counterpart to the 'file:' uri support for source migration,
now a file can also serve as the source of an incoming migration.

Unlike other migration protocol backends, the 'file' protocol cannot
honour non-blocking mode. POSIX file/block storage will always report
ready to read/write, regardless of how slow the underlying storage
will be at servicing the request.

For incoming migration this limitation may result in the main event
loop not being fully responsive while loading the VM state. This
won't impact the VM since it is not running at this phase, however,
it may impact management applications.

Reviewed-by: Daniel P. Berrangé <berra...@redhat.com>
Signed-off-by: Nikolay Borisov <nbori...@suse.com>
Signed-off-by: Fabiano Rosas <faro...@suse.de>
---
 docs/devel/migration.rst |  2 ++
 migration/file.c         | 15 +++++++++++++++
 migration/file.h         |  1 +
 migration/migration.c    |  2 ++
 4 files changed, 20 insertions(+)

diff --git a/docs/devel/migration.rst b/docs/devel/migration.rst
index 6f65c23b47..1080211f8e 100644
--- a/docs/devel/migration.rst
+++ b/docs/devel/migration.rst
@@ -39,6 +39,8 @@ over any transport.
 - exec migration: do the migration using the stdin/stdout through a process.
 - fd migration: do the migration using a file descriptor that is
   passed to QEMU.  QEMU doesn't care how this file descriptor is opened.
+- file migration: do the migration using a file that is passed by name
+  to QEMU.
 
 In addition, support is included for migration using RDMA, which
 transports the page data using ``RDMA``, where the hardware takes care of
diff --git a/migration/file.c b/migration/file.c
index 36d6178c75..ab4e12926c 100644
--- a/migration/file.c
+++ b/migration/file.c
@@ -19,3 +19,18 @@ void file_start_outgoing_migration(MigrationState *s, const 
char *fname, Error *
     migration_channel_connect(s, QIO_CHANNEL(ioc), NULL, NULL);
     object_unref(OBJECT(ioc));
 }
+
+void file_start_incoming_migration(const char *fname, Error **errp)
+{
+    QIOChannelFile *ioc;
+
+    ioc = qio_channel_file_new_path(fname, O_RDONLY, 0, errp);
+    if (!ioc) {
+        error_report("Error creating a channel");
+        return;
+    }
+
+    qio_channel_set_name(QIO_CHANNEL(ioc), "migration-file-incoming");
+    migration_channel_process_incoming(QIO_CHANNEL(ioc));
+    object_unref(OBJECT(ioc));
+}
diff --git a/migration/file.h b/migration/file.h
index d476eb1157..cdbd291322 100644
--- a/migration/file.h
+++ b/migration/file.h
@@ -5,5 +5,6 @@ void file_start_outgoing_migration(MigrationState *s,
                                    const char *filename,
                                    Error **errp);
 
+void file_start_incoming_migration(const char *fname, Error **errp);
 #endif
 
diff --git a/migration/migration.c b/migration/migration.c
index 58ff0cb7c7..5408d87453 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -527,6 +527,8 @@ static void qemu_start_incoming_migration(const char *uri, 
Error **errp)
         exec_start_incoming_migration(p, errp);
     } else if (strstart(uri, "fd:", &p)) {
         fd_start_incoming_migration(p, errp);
+    } else if (strstart(uri, "file:", &p)) {
+        file_start_incoming_migration(p, errp);
     } else {
         error_setg(errp, "unknown migration protocol: %s", uri);
     }
-- 
2.35.3


Reply via email to