mirror of https://github.com/xemu-project/xemu.git
migration/multifd: Add mapped-ram support to fd: URI
If we receive a file descriptor that points to a regular file, there's nothing stopping us from doing multifd migration with mapped-ram to that file. Enable the fd: URI to work with multifd + mapped-ram. Note that the fds passed into multifd are duplicated because we want to avoid cross-thread effects when doing cleanup (i.e. close(fd)). The original fd doesn't need to be duplicated because monitor_get_fd() transfers ownership to the caller. Signed-off-by: Fabiano Rosas <farosas@suse.de> Reviewed-by: Peter Xu <peterx@redhat.com> Link: https://lore.kernel.org/r/20240229153017.2221-23-farosas@suse.de Signed-off-by: Peter Xu <peterx@redhat.com>
This commit is contained in:
parent
a49d15a38d
commit
decdc76772
|
@ -15,18 +15,41 @@
|
|||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include "channel.h"
|
||||
#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_cleanup_outgoing_migration(void)
|
||||
{
|
||||
if (outgoing_args.fd > 0) {
|
||||
close(outgoing_args.fd);
|
||||
outgoing_args.fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
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 +61,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 +98,23 @@ 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(dup(fd)));
|
||||
|
||||
if (QIO_CHANNEL_FILE(ioc)->fd == -1) {
|
||||
error_setg(errp, "Failed to duplicate fd %d", fd);
|
||||
return;
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,4 +20,6 @@ void fd_start_incoming_migration(const char *fdname, Error **errp);
|
|||
|
||||
void fd_start_outgoing_migration(MigrationState *s, const char *fdname,
|
||||
Error **errp);
|
||||
void fd_cleanup_outgoing_migration(void);
|
||||
int fd_args_get_fd(void);
|
||||
#endif
|
||||
|
|
|
@ -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"
|
||||
|
@ -53,15 +54,20 @@ bool file_send_channel_create(gpointer opaque, Error **errp)
|
|||
{
|
||||
QIOChannelFile *ioc;
|
||||
int flags = O_WRONLY;
|
||||
bool ret = true;
|
||||
bool ret = false;
|
||||
int fd = fd_args_get_fd();
|
||||
|
||||
ioc = qio_channel_file_new_path(outgoing_args.fname, flags, 0, errp);
|
||||
if (!ioc) {
|
||||
ret = false;
|
||||
goto out;
|
||||
if (fd && fd != -1) {
|
||||
ioc = qio_channel_file_new_fd(dup(fd));
|
||||
} else {
|
||||
ioc = qio_channel_file_new_path(outgoing_args.fname, flags, 0, errp);
|
||||
if (!ioc) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
multifd_channel_connect(opaque, QIO_CHANNEL(ioc));
|
||||
ret = true;
|
||||
|
||||
out:
|
||||
/*
|
||||
|
|
|
@ -140,6 +140,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_mapped_ram();
|
||||
}
|
||||
|
||||
return (saddr->type == SOCKET_ADDRESS_TYPE_INET ||
|
||||
saddr->type == SOCKET_ADDRESS_TYPE_UNIX ||
|
||||
saddr->type == SOCKET_ADDRESS_TYPE_VSOCK);
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "exec/ramblock.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qapi/error.h"
|
||||
#include "fd.h"
|
||||
#include "file.h"
|
||||
#include "migration.h"
|
||||
#include "migration-stats.h"
|
||||
|
@ -731,6 +732,7 @@ static bool multifd_send_cleanup_channel(MultiFDSendParams *p, Error **errp)
|
|||
static void multifd_send_cleanup_state(void)
|
||||
{
|
||||
file_cleanup_outgoing_migration();
|
||||
fd_cleanup_outgoing_migration();
|
||||
socket_cleanup_outgoing_migration();
|
||||
qemu_sem_destroy(&multifd_send_state->channels_created);
|
||||
qemu_sem_destroy(&multifd_send_state->channels_ready);
|
||||
|
|
Loading…
Reference in New Issue