Message ID | 1687466251-310524-2-git-send-email-steven.sistare@oracle.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | migration file URI | expand |
On Thu, Jun 22, 2023 at 01:37:30PM -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> > --- > 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. > + * 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); Miss one object_unref(ioc)? > +} > + > +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 8ba6e42..3af817e 100644 > --- a/migration/meson.build > +++ b/migration/meson.build > @@ -16,6 +16,7 @@ softmmu_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 > -- > 1.8.3.1 >
On Wed, Jun 28, 2023 at 01:07:24PM -0400, Peter Xu wrote: > On Thu, Jun 22, 2023 at 01:37:30PM -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> > > --- > > 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. > > + * 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); > > Miss one object_unref(ioc)? Never mind, I overlooked the g_autoptr.. all fine: Reviewed-by: Peter Xu <peterx@redhat.com>
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 8ba6e42..3af817e 100644 --- a/migration/meson.build +++ b/migration/meson.build @@ -16,6 +16,7 @@ softmmu_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