diff mbox series

[V4,1/2] migration: file URI

Message ID 1688135108-316997-2-git-send-email-steven.sistare@oracle.com
State New
Headers show
Series migration file URI | expand

Commit Message

Steve Sistare June 30, 2023, 2:25 p.m. UTC
Extend the migration URI to support file:<filename>.  This can be used for
any migration scenario that does not require a reverse path.  It can be
used as an alternative to 'exec:cat > file' in minimized containers that
do not contain /bin/sh, and it is easier to use than the fd:<fdname> URI.
It can be used in HMP commands, and as a qemu command-line parameter.

For best performance, guest ram should be shared and x-ignore-shared
should be true, so guest pages are not written to the file, in which case
the guest may remain running.  If ram is not so configured, then the user
is advised to stop the guest first.  Otherwise, a busy guest may re-dirty
the same page, causing it to be appended to the file multiple times,
and the file may grow unboundedly.  That issue is being addressed in the
"fixed-ram" patch series.

Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Peter Xu <peterx@redhat.com>
---
 migration/file.c       | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++
 migration/file.h       | 14 ++++++++++++
 migration/meson.build  |  1 +
 migration/migration.c  |  5 ++++
 migration/trace-events |  4 ++++
 qemu-options.hx        |  6 ++++-
 6 files changed, 91 insertions(+), 1 deletion(-)
 create mode 100644 migration/file.c
 create mode 100644 migration/file.h

Comments

Daniel P. Berrangé Aug. 30, 2023, 1:16 p.m. UTC | #1
On Fri, Jun 30, 2023 at 07:25:07AM -0700, Steve Sistare wrote:
> Extend the migration URI to support file:<filename>.  This can be used for
> any migration scenario that does not require a reverse path.  It can be
> used as an alternative to 'exec:cat > file' in minimized containers that
> do not contain /bin/sh, and it is easier to use than the fd:<fdname> URI.
> It can be used in HMP commands, and as a qemu command-line parameter.
> 
> For best performance, guest ram should be shared and x-ignore-shared
> should be true, so guest pages are not written to the file, in which case
> the guest may remain running.  If ram is not so configured, then the user
> is advised to stop the guest first.  Otherwise, a busy guest may re-dirty
> the same page, causing it to be appended to the file multiple times,
> and the file may grow unboundedly.  That issue is being addressed in the
> "fixed-ram" patch series.
> 
> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
> Reviewed-by: Fabiano Rosas <farosas@suse.de>
> Reviewed-by: Peter Xu <peterx@redhat.com>
> ---
>  migration/file.c       | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  migration/file.h       | 14 ++++++++++++
>  migration/meson.build  |  1 +
>  migration/migration.c  |  5 ++++
>  migration/trace-events |  4 ++++
>  qemu-options.hx        |  6 ++++-
>  6 files changed, 91 insertions(+), 1 deletion(-)
>  create mode 100644 migration/file.c
>  create mode 100644 migration/file.h
> 
> diff --git a/migration/file.c b/migration/file.c
> new file mode 100644
> index 0000000..8e35827
> --- /dev/null
> +++ b/migration/file.c
> @@ -0,0 +1,62 @@
> +/*
> + * Copyright (c) 2021-2023 Oracle and/or its affiliates.
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2.

Was it an intentional decision to assign this under the version 2 *only* ?

QEMU's LICENSE file states

[quote]
As of July 2013, contributions under version 2 of the GNU General Public
License (and no later version) are only accepted for the following files
or directories: bsd-user/, linux-user/, hw/vfio/, hw/xen/xen_pt*.
[/quote]

Thus we'd expect this new file to be version 2, or later.

> + * See the COPYING file in the top-level directory.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "channel.h"
> +#include "file.h"
> +#include "migration.h"
> +#include "io/channel-file.h"
> +#include "io/channel-util.h"
> +#include "trace.h"
> +
> +void file_start_outgoing_migration(MigrationState *s, const char *filename,
> +                                   Error **errp)
> +{
> +    g_autoptr(QIOChannelFile) fioc = NULL;
> +    QIOChannel *ioc;
> +
> +    trace_migration_file_outgoing(filename);
> +
> +    fioc = qio_channel_file_new_path(filename, O_CREAT | O_WRONLY | O_TRUNC,
> +                                     0600, errp);
> +    if (!fioc) {
> +        return;
> +    }
> +
> +    ioc = QIO_CHANNEL(fioc);
> +    qio_channel_set_name(ioc, "migration-file-outgoing");
> +    migration_channel_connect(s, ioc, NULL, NULL);
> +}
> +
> +static gboolean file_accept_incoming_migration(QIOChannel *ioc,
> +                                               GIOCondition condition,
> +                                               gpointer opaque)
> +{
> +    migration_channel_process_incoming(ioc);
> +    object_unref(OBJECT(ioc));
> +    return G_SOURCE_REMOVE;
> +}
> +
> +void file_start_incoming_migration(const char *filename, Error **errp)
> +{
> +    QIOChannelFile *fioc = NULL;
> +    QIOChannel *ioc;
> +
> +    trace_migration_file_incoming(filename);
> +
> +    fioc = qio_channel_file_new_path(filename, O_RDONLY, 0, errp);
> +    if (!fioc) {
> +        return;
> +    }
> +
> +    ioc = QIO_CHANNEL(fioc);
> +    qio_channel_set_name(QIO_CHANNEL(ioc), "migration-file-incoming");
> +    qio_channel_add_watch_full(ioc, G_IO_IN,
> +                               file_accept_incoming_migration,
> +                               NULL, NULL,
> +                               g_main_context_get_thread_default());
> +}
> diff --git a/migration/file.h b/migration/file.h
> new file mode 100644
> index 0000000..841b94a
> --- /dev/null
> +++ b/migration/file.h
> @@ -0,0 +1,14 @@
> +/*
> + * Copyright (c) 2021-2023 Oracle and/or its affiliates.
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2.
> + * See the COPYING file in the top-level directory.
> + */
> +
> +#ifndef QEMU_MIGRATION_FILE_H
> +#define QEMU_MIGRATION_FILE_H
> +void file_start_incoming_migration(const char *filename, Error **errp);
> +
> +void file_start_outgoing_migration(MigrationState *s, const char *filename,
> +                                   Error **errp);
> +#endif
> diff --git a/migration/meson.build b/migration/meson.build
> index 1ae2852..92b1cc4 100644
> --- a/migration/meson.build
> +++ b/migration/meson.build
> @@ -16,6 +16,7 @@ system_ss.add(files(
>    'dirtyrate.c',
>    'exec.c',
>    'fd.c',
> +  'file.c',
>    'global_state.c',
>    'migration-hmp-cmds.c',
>    'migration.c',
> diff --git a/migration/migration.c b/migration/migration.c
> index dc05c6f..cfbde86 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -20,6 +20,7 @@
>  #include "migration/blocker.h"
>  #include "exec.h"
>  #include "fd.h"
> +#include "file.h"
>  #include "socket.h"
>  #include "sysemu/runstate.h"
>  #include "sysemu/sysemu.h"
> @@ -442,6 +443,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);
>      }
> @@ -1662,6 +1665,8 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk,
>          exec_start_outgoing_migration(s, p, &local_err);
>      } else if (strstart(uri, "fd:", &p)) {
>          fd_start_outgoing_migration(s, p, &local_err);
> +    } else if (strstart(uri, "file:", &p)) {
> +        file_start_outgoing_migration(s, p, &local_err);
>      } else {
>          if (!(has_resume && resume)) {
>              yank_unregister_instance(MIGRATION_YANK_INSTANCE);

This section will clash with the other pending reviewed series
that introduces a formall QAPI schema for migration addresses.

Either this or that series will need an update depending on
which Juan decides to merge first.  The changes should be
fairly simple to resolve so not a big deal.

> diff --git a/migration/trace-events b/migration/trace-events
> index cdaef7a..c8c1771 100644
> --- a/migration/trace-events
> +++ b/migration/trace-events
> @@ -307,6 +307,10 @@ migration_exec_incoming(const char *cmd) "cmd=%s"
>  migration_fd_outgoing(int fd) "fd=%d"
>  migration_fd_incoming(int fd) "fd=%d"
>  
> +# file.c
> +migration_file_outgoing(const char *filename) "filename=%s"
> +migration_file_incoming(const char *filename) "filename=%s"
> +
>  # socket.c
>  migration_socket_incoming_accepted(void) ""
>  migration_socket_outgoing_connected(const char *hostname) "hostname=%s"
> diff --git a/qemu-options.hx b/qemu-options.hx
> index b57489d..5aab8fb 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -4622,6 +4622,7 @@ DEF("incoming", HAS_ARG, QEMU_OPTION_incoming, \
>      "                prepare for incoming migration, listen on\n" \
>      "                specified protocol and socket address\n" \
>      "-incoming fd:fd\n" \
> +    "-incoming file:filename\n" \
>      "-incoming exec:cmdline\n" \
>      "                accept incoming migration on given file descriptor\n" \
>      "                or from given external command\n" \
> @@ -4638,7 +4639,10 @@ SRST
>      Prepare for incoming migration, listen on a given unix socket.
>  
>  ``-incoming fd:fd``
> -    Accept incoming migration from a given filedescriptor.
> +    Accept incoming migration from a given file descriptor.
> +
> +``-incoming file:filename``
> +    Accept incoming migration from a given file.
>  
>  ``-incoming exec:cmdline``
>      Accept incoming migration as an output from specified external
> -- 
> 1.8.3.1
> 

With regards,
Daniel
Steve Sistare Aug. 30, 2023, 2:15 p.m. UTC | #2
On 8/30/2023 9:16 AM, Daniel P. Berrangé wrote:
> On Fri, Jun 30, 2023 at 07:25:07AM -0700, Steve Sistare wrote:
>> Extend the migration URI to support file:<filename>.  This can be used for
>> any migration scenario that does not require a reverse path.  It can be
>> used as an alternative to 'exec:cat > file' in minimized containers that
>> do not contain /bin/sh, and it is easier to use than the fd:<fdname> URI.
>> It can be used in HMP commands, and as a qemu command-line parameter.
>>
>> For best performance, guest ram should be shared and x-ignore-shared
>> should be true, so guest pages are not written to the file, in which case
>> the guest may remain running.  If ram is not so configured, then the user
>> is advised to stop the guest first.  Otherwise, a busy guest may re-dirty
>> the same page, causing it to be appended to the file multiple times,
>> and the file may grow unboundedly.  That issue is being addressed in the
>> "fixed-ram" patch series.
>>
>> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
>> Reviewed-by: Fabiano Rosas <farosas@suse.de>
>> Reviewed-by: Peter Xu <peterx@redhat.com>
>> ---
>>  migration/file.c       | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++
>>  migration/file.h       | 14 ++++++++++++
>>  migration/meson.build  |  1 +
>>  migration/migration.c  |  5 ++++
>>  migration/trace-events |  4 ++++
>>  qemu-options.hx        |  6 ++++-
>>  6 files changed, 91 insertions(+), 1 deletion(-)
>>  create mode 100644 migration/file.c
>>  create mode 100644 migration/file.h
>>
>> diff --git a/migration/file.c b/migration/file.c
>> new file mode 100644
>> index 0000000..8e35827
>> --- /dev/null
>> +++ b/migration/file.c
>> @@ -0,0 +1,62 @@
>> +/*
>> + * Copyright (c) 2021-2023 Oracle and/or its affiliates.
>> + *
>> + * This work is licensed under the terms of the GNU GPL, version 2.
> 
> Was it an intentional decision to assign this under the version 2 *only* ?
> 
> QEMU's LICENSE file states
> 
> [quote]
> As of July 2013, contributions under version 2 of the GNU General Public
> License (and no later version) are only accepted for the following files
> or directories: bsd-user/, linux-user/, hw/vfio/, hw/xen/xen_pt*.
> [/quote]
> 
> Thus we'd expect this new file to be version 2, or later.

My mistake, sorry.  It should say "GNU GPL, version 2 or later"

- Steve

>> + * See the COPYING file in the top-level directory.
>> + */
>> +
>> +#include "qemu/osdep.h"
>> +#include "channel.h"
>> +#include "file.h"
>> +#include "migration.h"
>> +#include "io/channel-file.h"
>> +#include "io/channel-util.h"
>> +#include "trace.h"
>> +
>> +void file_start_outgoing_migration(MigrationState *s, const char *filename,
>> +                                   Error **errp)
>> +{
>> +    g_autoptr(QIOChannelFile) fioc = NULL;
>> +    QIOChannel *ioc;
>> +
>> +    trace_migration_file_outgoing(filename);
>> +
>> +    fioc = qio_channel_file_new_path(filename, O_CREAT | O_WRONLY | O_TRUNC,
>> +                                     0600, errp);
>> +    if (!fioc) {
>> +        return;
>> +    }
>> +
>> +    ioc = QIO_CHANNEL(fioc);
>> +    qio_channel_set_name(ioc, "migration-file-outgoing");
>> +    migration_channel_connect(s, ioc, NULL, NULL);
>> +}
>> +
>> +static gboolean file_accept_incoming_migration(QIOChannel *ioc,
>> +                                               GIOCondition condition,
>> +                                               gpointer opaque)
>> +{
>> +    migration_channel_process_incoming(ioc);
>> +    object_unref(OBJECT(ioc));
>> +    return G_SOURCE_REMOVE;
>> +}
>> +
>> +void file_start_incoming_migration(const char *filename, Error **errp)
>> +{
>> +    QIOChannelFile *fioc = NULL;
>> +    QIOChannel *ioc;
>> +
>> +    trace_migration_file_incoming(filename);
>> +
>> +    fioc = qio_channel_file_new_path(filename, O_RDONLY, 0, errp);
>> +    if (!fioc) {
>> +        return;
>> +    }
>> +
>> +    ioc = QIO_CHANNEL(fioc);
>> +    qio_channel_set_name(QIO_CHANNEL(ioc), "migration-file-incoming");
>> +    qio_channel_add_watch_full(ioc, G_IO_IN,
>> +                               file_accept_incoming_migration,
>> +                               NULL, NULL,
>> +                               g_main_context_get_thread_default());
>> +}
>> diff --git a/migration/file.h b/migration/file.h
>> new file mode 100644
>> index 0000000..841b94a
>> --- /dev/null
>> +++ b/migration/file.h
>> @@ -0,0 +1,14 @@
>> +/*
>> + * Copyright (c) 2021-2023 Oracle and/or its affiliates.
>> + *
>> + * This work is licensed under the terms of the GNU GPL, version 2.
>> + * See the COPYING file in the top-level directory.
>> + */
>> +
>> +#ifndef QEMU_MIGRATION_FILE_H
>> +#define QEMU_MIGRATION_FILE_H
>> +void file_start_incoming_migration(const char *filename, Error **errp);
>> +
>> +void file_start_outgoing_migration(MigrationState *s, const char *filename,
>> +                                   Error **errp);
>> +#endif
>> diff --git a/migration/meson.build b/migration/meson.build
>> index 1ae2852..92b1cc4 100644
>> --- a/migration/meson.build
>> +++ b/migration/meson.build
>> @@ -16,6 +16,7 @@ system_ss.add(files(
>>    'dirtyrate.c',
>>    'exec.c',
>>    'fd.c',
>> +  'file.c',
>>    'global_state.c',
>>    'migration-hmp-cmds.c',
>>    'migration.c',
>> diff --git a/migration/migration.c b/migration/migration.c
>> index dc05c6f..cfbde86 100644
>> --- a/migration/migration.c
>> +++ b/migration/migration.c
>> @@ -20,6 +20,7 @@
>>  #include "migration/blocker.h"
>>  #include "exec.h"
>>  #include "fd.h"
>> +#include "file.h"
>>  #include "socket.h"
>>  #include "sysemu/runstate.h"
>>  #include "sysemu/sysemu.h"
>> @@ -442,6 +443,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);
>>      }
>> @@ -1662,6 +1665,8 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk,
>>          exec_start_outgoing_migration(s, p, &local_err);
>>      } else if (strstart(uri, "fd:", &p)) {
>>          fd_start_outgoing_migration(s, p, &local_err);
>> +    } else if (strstart(uri, "file:", &p)) {
>> +        file_start_outgoing_migration(s, p, &local_err);
>>      } else {
>>          if (!(has_resume && resume)) {
>>              yank_unregister_instance(MIGRATION_YANK_INSTANCE);
> 
> This section will clash with the other pending reviewed series
> that introduces a formall QAPI schema for migration addresses.
> 
> Either this or that series will need an update depending on
> which Juan decides to merge first.  The changes should be
> fairly simple to resolve so not a big deal.
> 
>> diff --git a/migration/trace-events b/migration/trace-events
>> index cdaef7a..c8c1771 100644
>> --- a/migration/trace-events
>> +++ b/migration/trace-events
>> @@ -307,6 +307,10 @@ migration_exec_incoming(const char *cmd) "cmd=%s"
>>  migration_fd_outgoing(int fd) "fd=%d"
>>  migration_fd_incoming(int fd) "fd=%d"
>>  
>> +# file.c
>> +migration_file_outgoing(const char *filename) "filename=%s"
>> +migration_file_incoming(const char *filename) "filename=%s"
>> +
>>  # socket.c
>>  migration_socket_incoming_accepted(void) ""
>>  migration_socket_outgoing_connected(const char *hostname) "hostname=%s"
>> diff --git a/qemu-options.hx b/qemu-options.hx
>> index b57489d..5aab8fb 100644
>> --- a/qemu-options.hx
>> +++ b/qemu-options.hx
>> @@ -4622,6 +4622,7 @@ DEF("incoming", HAS_ARG, QEMU_OPTION_incoming, \
>>      "                prepare for incoming migration, listen on\n" \
>>      "                specified protocol and socket address\n" \
>>      "-incoming fd:fd\n" \
>> +    "-incoming file:filename\n" \
>>      "-incoming exec:cmdline\n" \
>>      "                accept incoming migration on given file descriptor\n" \
>>      "                or from given external command\n" \
>> @@ -4638,7 +4639,10 @@ SRST
>>      Prepare for incoming migration, listen on a given unix socket.
>>  
>>  ``-incoming fd:fd``
>> -    Accept incoming migration from a given filedescriptor.
>> +    Accept incoming migration from a given file descriptor.
>> +
>> +``-incoming file:filename``
>> +    Accept incoming migration from a given file.
>>  
>>  ``-incoming exec:cmdline``
>>      Accept incoming migration as an output from specified external
>> -- 
>> 1.8.3.1
>>
> 
> With regards,
> Daniel
Daniel P. Berrangé Sept. 8, 2023, 10:52 a.m. UTC | #3
On Wed, Aug 30, 2023 at 10:15:43AM -0400, Steven Sistare wrote:
> On 8/30/2023 9:16 AM, Daniel P. Berrangé wrote:
> > On Fri, Jun 30, 2023 at 07:25:07AM -0700, Steve Sistare wrote:
> >> Extend the migration URI to support file:<filename>.  This can be used for
> >> any migration scenario that does not require a reverse path.  It can be
> >> used as an alternative to 'exec:cat > file' in minimized containers that
> >> do not contain /bin/sh, and it is easier to use than the fd:<fdname> URI.
> >> It can be used in HMP commands, and as a qemu command-line parameter.
> >>
> >> For best performance, guest ram should be shared and x-ignore-shared
> >> should be true, so guest pages are not written to the file, in which case
> >> the guest may remain running.  If ram is not so configured, then the user
> >> is advised to stop the guest first.  Otherwise, a busy guest may re-dirty
> >> the same page, causing it to be appended to the file multiple times,
> >> and the file may grow unboundedly.  That issue is being addressed in the
> >> "fixed-ram" patch series.
> >>
> >> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
> >> Reviewed-by: Fabiano Rosas <farosas@suse.de>
> >> Reviewed-by: Peter Xu <peterx@redhat.com>
> >> ---
> >>  migration/file.c       | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++
> >>  migration/file.h       | 14 ++++++++++++
> >>  migration/meson.build  |  1 +
> >>  migration/migration.c  |  5 ++++
> >>  migration/trace-events |  4 ++++
> >>  qemu-options.hx        |  6 ++++-
> >>  6 files changed, 91 insertions(+), 1 deletion(-)
> >>  create mode 100644 migration/file.c
> >>  create mode 100644 migration/file.h
> >>
> >> diff --git a/migration/file.c b/migration/file.c
> >> new file mode 100644
> >> index 0000000..8e35827
> >> --- /dev/null
> >> +++ b/migration/file.c
> >> @@ -0,0 +1,62 @@
> >> +/*
> >> + * Copyright (c) 2021-2023 Oracle and/or its affiliates.
> >> + *
> >> + * This work is licensed under the terms of the GNU GPL, version 2.
> > 
> > Was it an intentional decision to assign this under the version 2 *only* ?
> > 
> > QEMU's LICENSE file states
> > 
> > [quote]
> > As of July 2013, contributions under version 2 of the GNU General Public
> > License (and no later version) are only accepted for the following files
> > or directories: bsd-user/, linux-user/, hw/vfio/, hw/xen/xen_pt*.
> > [/quote]
> > 
> > Thus we'd expect this new file to be version 2, or later.
> 
> My mistake, sorry.  It should say "GNU GPL, version 2 or later"

Could you re-post, as aside from that, this series looks
ready for merge.


With regards,
Daniel
Steve Sistare Sept. 8, 2023, 2:23 p.m. UTC | #4
On 9/8/2023 6:52 AM, Daniel P. Berrangé wrote:
> On Wed, Aug 30, 2023 at 10:15:43AM -0400, Steven Sistare wrote:
>> On 8/30/2023 9:16 AM, Daniel P. Berrangé wrote:
>>> On Fri, Jun 30, 2023 at 07:25:07AM -0700, Steve Sistare wrote:
>>>> Extend the migration URI to support file:<filename>.  This can be used for
>>>> any migration scenario that does not require a reverse path.  It can be
>>>> used as an alternative to 'exec:cat > file' in minimized containers that
>>>> do not contain /bin/sh, and it is easier to use than the fd:<fdname> URI.
>>>> It can be used in HMP commands, and as a qemu command-line parameter.
>>>>
>>>> For best performance, guest ram should be shared and x-ignore-shared
>>>> should be true, so guest pages are not written to the file, in which case
>>>> the guest may remain running.  If ram is not so configured, then the user
>>>> is advised to stop the guest first.  Otherwise, a busy guest may re-dirty
>>>> the same page, causing it to be appended to the file multiple times,
>>>> and the file may grow unboundedly.  That issue is being addressed in the
>>>> "fixed-ram" patch series.
>>>>
>>>> Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
>>>> Reviewed-by: Fabiano Rosas <farosas@suse.de>
>>>> Reviewed-by: Peter Xu <peterx@redhat.com>
>>>> ---
>>>>  migration/file.c       | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++
>>>>  migration/file.h       | 14 ++++++++++++
>>>>  migration/meson.build  |  1 +
>>>>  migration/migration.c  |  5 ++++
>>>>  migration/trace-events |  4 ++++
>>>>  qemu-options.hx        |  6 ++++-
>>>>  6 files changed, 91 insertions(+), 1 deletion(-)
>>>>  create mode 100644 migration/file.c
>>>>  create mode 100644 migration/file.h
>>>>
>>>> diff --git a/migration/file.c b/migration/file.c
>>>> new file mode 100644
>>>> index 0000000..8e35827
>>>> --- /dev/null
>>>> +++ b/migration/file.c
>>>> @@ -0,0 +1,62 @@
>>>> +/*
>>>> + * Copyright (c) 2021-2023 Oracle and/or its affiliates.
>>>> + *
>>>> + * This work is licensed under the terms of the GNU GPL, version 2.
>>>
>>> Was it an intentional decision to assign this under the version 2 *only* ?
>>>
>>> QEMU's LICENSE file states
>>>
>>> [quote]
>>> As of July 2013, contributions under version 2 of the GNU General Public
>>> License (and no later version) are only accepted for the following files
>>> or directories: bsd-user/, linux-user/, hw/vfio/, hw/xen/xen_pt*.
>>> [/quote]
>>>
>>> Thus we'd expect this new file to be version 2, or later.
>>
>> My mistake, sorry.  It should say "GNU GPL, version 2 or later"
> 
> Could you re-post, as aside from that, this series looks
> ready for merge.

Done, thanks, see V5.

- Steve
diff mbox series

Patch

diff --git a/migration/file.c b/migration/file.c
new file mode 100644
index 0000000..8e35827
--- /dev/null
+++ b/migration/file.c
@@ -0,0 +1,62 @@ 
+/*
+ * Copyright (c) 2021-2023 Oracle and/or its affiliates.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "channel.h"
+#include "file.h"
+#include "migration.h"
+#include "io/channel-file.h"
+#include "io/channel-util.h"
+#include "trace.h"
+
+void file_start_outgoing_migration(MigrationState *s, const char *filename,
+                                   Error **errp)
+{
+    g_autoptr(QIOChannelFile) fioc = NULL;
+    QIOChannel *ioc;
+
+    trace_migration_file_outgoing(filename);
+
+    fioc = qio_channel_file_new_path(filename, O_CREAT | O_WRONLY | O_TRUNC,
+                                     0600, errp);
+    if (!fioc) {
+        return;
+    }
+
+    ioc = QIO_CHANNEL(fioc);
+    qio_channel_set_name(ioc, "migration-file-outgoing");
+    migration_channel_connect(s, ioc, NULL, NULL);
+}
+
+static gboolean file_accept_incoming_migration(QIOChannel *ioc,
+                                               GIOCondition condition,
+                                               gpointer opaque)
+{
+    migration_channel_process_incoming(ioc);
+    object_unref(OBJECT(ioc));
+    return G_SOURCE_REMOVE;
+}
+
+void file_start_incoming_migration(const char *filename, Error **errp)
+{
+    QIOChannelFile *fioc = NULL;
+    QIOChannel *ioc;
+
+    trace_migration_file_incoming(filename);
+
+    fioc = qio_channel_file_new_path(filename, O_RDONLY, 0, errp);
+    if (!fioc) {
+        return;
+    }
+
+    ioc = QIO_CHANNEL(fioc);
+    qio_channel_set_name(QIO_CHANNEL(ioc), "migration-file-incoming");
+    qio_channel_add_watch_full(ioc, G_IO_IN,
+                               file_accept_incoming_migration,
+                               NULL, NULL,
+                               g_main_context_get_thread_default());
+}
diff --git a/migration/file.h b/migration/file.h
new file mode 100644
index 0000000..841b94a
--- /dev/null
+++ b/migration/file.h
@@ -0,0 +1,14 @@ 
+/*
+ * Copyright (c) 2021-2023 Oracle and/or its affiliates.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef QEMU_MIGRATION_FILE_H
+#define QEMU_MIGRATION_FILE_H
+void file_start_incoming_migration(const char *filename, Error **errp);
+
+void file_start_outgoing_migration(MigrationState *s, const char *filename,
+                                   Error **errp);
+#endif
diff --git a/migration/meson.build b/migration/meson.build
index 1ae2852..92b1cc4 100644
--- a/migration/meson.build
+++ b/migration/meson.build
@@ -16,6 +16,7 @@  system_ss.add(files(
   'dirtyrate.c',
   'exec.c',
   'fd.c',
+  'file.c',
   'global_state.c',
   'migration-hmp-cmds.c',
   'migration.c',
diff --git a/migration/migration.c b/migration/migration.c
index dc05c6f..cfbde86 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -20,6 +20,7 @@ 
 #include "migration/blocker.h"
 #include "exec.h"
 #include "fd.h"
+#include "file.h"
 #include "socket.h"
 #include "sysemu/runstate.h"
 #include "sysemu/sysemu.h"
@@ -442,6 +443,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);
     }
@@ -1662,6 +1665,8 @@  void qmp_migrate(const char *uri, bool has_blk, bool blk,
         exec_start_outgoing_migration(s, p, &local_err);
     } else if (strstart(uri, "fd:", &p)) {
         fd_start_outgoing_migration(s, p, &local_err);
+    } else if (strstart(uri, "file:", &p)) {
+        file_start_outgoing_migration(s, p, &local_err);
     } else {
         if (!(has_resume && resume)) {
             yank_unregister_instance(MIGRATION_YANK_INSTANCE);
diff --git a/migration/trace-events b/migration/trace-events
index cdaef7a..c8c1771 100644
--- a/migration/trace-events
+++ b/migration/trace-events
@@ -307,6 +307,10 @@  migration_exec_incoming(const char *cmd) "cmd=%s"
 migration_fd_outgoing(int fd) "fd=%d"
 migration_fd_incoming(int fd) "fd=%d"
 
+# file.c
+migration_file_outgoing(const char *filename) "filename=%s"
+migration_file_incoming(const char *filename) "filename=%s"
+
 # socket.c
 migration_socket_incoming_accepted(void) ""
 migration_socket_outgoing_connected(const char *hostname) "hostname=%s"
diff --git a/qemu-options.hx b/qemu-options.hx
index b57489d..5aab8fb 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4622,6 +4622,7 @@  DEF("incoming", HAS_ARG, QEMU_OPTION_incoming, \
     "                prepare for incoming migration, listen on\n" \
     "                specified protocol and socket address\n" \
     "-incoming fd:fd\n" \
+    "-incoming file:filename\n" \
     "-incoming exec:cmdline\n" \
     "                accept incoming migration on given file descriptor\n" \
     "                or from given external command\n" \
@@ -4638,7 +4639,10 @@  SRST
     Prepare for incoming migration, listen on a given unix socket.
 
 ``-incoming fd:fd``
-    Accept incoming migration from a given filedescriptor.
+    Accept incoming migration from a given file descriptor.
+
+``-incoming file:filename``
+    Accept incoming migration from a given file.
 
 ``-incoming exec:cmdline``
     Accept incoming migration as an output from specified external