migration: file URI
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> Tested-by: Michael Galaxy <mgalaxy@akamai.com> Reviewed-by: Michael Galaxy <mgalaxy@akamai.com> Reviewed-by: Fabiano Rosas <farosas@suse.de> Reviewed-by: Peter Xu <peterx@redhat.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Reviewed-by: Juan Quintela <quintela@redhat.com> Signed-off-by: Juan Quintela <quintela@redhat.com> Message-ID: <1694182931-61390-2-git-send-email-steven.sistare@oracle.com>
This commit is contained in:
parent
b28e3ecf0d
commit
2a9e2e595f
62
migration/file.c
Normal file
62
migration/file.c
Normal file
@ -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 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());
|
||||||
|
}
|
14
migration/file.h
Normal file
14
migration/file.h
Normal file
@ -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 or later.
|
||||||
|
* 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
|
@ -16,6 +16,7 @@ system_ss.add(files(
|
|||||||
'dirtyrate.c',
|
'dirtyrate.c',
|
||||||
'exec.c',
|
'exec.c',
|
||||||
'fd.c',
|
'fd.c',
|
||||||
|
'file.c',
|
||||||
'global_state.c',
|
'global_state.c',
|
||||||
'migration-hmp-cmds.c',
|
'migration-hmp-cmds.c',
|
||||||
'migration.c',
|
'migration.c',
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "migration/blocker.h"
|
#include "migration/blocker.h"
|
||||||
#include "exec.h"
|
#include "exec.h"
|
||||||
#include "fd.h"
|
#include "fd.h"
|
||||||
|
#include "file.h"
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
#include "sysemu/runstate.h"
|
#include "sysemu/runstate.h"
|
||||||
#include "sysemu/sysemu.h"
|
#include "sysemu/sysemu.h"
|
||||||
@ -449,6 +450,8 @@ static void qemu_start_incoming_migration(const char *uri, Error **errp)
|
|||||||
exec_start_incoming_migration(p, errp);
|
exec_start_incoming_migration(p, errp);
|
||||||
} else if (strstart(uri, "fd:", &p)) {
|
} else if (strstart(uri, "fd:", &p)) {
|
||||||
fd_start_incoming_migration(p, errp);
|
fd_start_incoming_migration(p, errp);
|
||||||
|
} else if (strstart(uri, "file:", &p)) {
|
||||||
|
file_start_incoming_migration(p, errp);
|
||||||
} else {
|
} else {
|
||||||
error_setg(errp, "unknown migration protocol: %s", uri);
|
error_setg(errp, "unknown migration protocol: %s", uri);
|
||||||
}
|
}
|
||||||
@ -1702,6 +1705,8 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk,
|
|||||||
exec_start_outgoing_migration(s, p, &local_err);
|
exec_start_outgoing_migration(s, p, &local_err);
|
||||||
} else if (strstart(uri, "fd:", &p)) {
|
} else if (strstart(uri, "fd:", &p)) {
|
||||||
fd_start_outgoing_migration(s, p, &local_err);
|
fd_start_outgoing_migration(s, p, &local_err);
|
||||||
|
} else if (strstart(uri, "file:", &p)) {
|
||||||
|
file_start_outgoing_migration(s, p, &local_err);
|
||||||
} else {
|
} else {
|
||||||
error_setg(&local_err, QERR_INVALID_PARAMETER_VALUE, "uri",
|
error_setg(&local_err, QERR_INVALID_PARAMETER_VALUE, "uri",
|
||||||
"a valid migration protocol");
|
"a valid migration protocol");
|
||||||
|
@ -311,6 +311,10 @@ migration_exec_incoming(const char *cmd) "cmd=%s"
|
|||||||
migration_fd_outgoing(int fd) "fd=%d"
|
migration_fd_outgoing(int fd) "fd=%d"
|
||||||
migration_fd_incoming(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
|
# socket.c
|
||||||
migration_socket_incoming_accepted(void) ""
|
migration_socket_incoming_accepted(void) ""
|
||||||
migration_socket_outgoing_connected(const char *hostname) "hostname=%s"
|
migration_socket_outgoing_connected(const char *hostname) "hostname=%s"
|
||||||
|
@ -4706,6 +4706,7 @@ DEF("incoming", HAS_ARG, QEMU_OPTION_incoming, \
|
|||||||
" prepare for incoming migration, listen on\n" \
|
" prepare for incoming migration, listen on\n" \
|
||||||
" specified protocol and socket address\n" \
|
" specified protocol and socket address\n" \
|
||||||
"-incoming fd:fd\n" \
|
"-incoming fd:fd\n" \
|
||||||
|
"-incoming file:filename\n" \
|
||||||
"-incoming exec:cmdline\n" \
|
"-incoming exec:cmdline\n" \
|
||||||
" accept incoming migration on given file descriptor\n" \
|
" accept incoming migration on given file descriptor\n" \
|
||||||
" or from given external command\n" \
|
" or from given external command\n" \
|
||||||
@ -4722,7 +4723,10 @@ SRST
|
|||||||
Prepare for incoming migration, listen on a given unix socket.
|
Prepare for incoming migration, listen on a given unix socket.
|
||||||
|
|
||||||
``-incoming fd:fd``
|
``-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``
|
``-incoming exec:cmdline``
|
||||||
Accept incoming migration as an output from specified external
|
Accept incoming migration as an output from specified external
|
||||||
|
Loading…
Reference in New Issue
Block a user