mirror of
https://github.com/qemu/qemu.git
synced 2026-02-04 05:35:39 +00:00
Make the synchronous calls evident by not hiding the call to migration_channel_connect_outgoing() in the transport code. Have those functions return and call the function at the upper level. This helps with navigation: the transport code returns the ioc, there's no need to look into them when browsing the code. It also allows RDMA in the source side to use the same path as the rest of the transports. While here, document the async calls which are the exception. Reviewed-by: Peter Xu <peterx@redhat.com> Reviewed-by: Prasad Pandit <pjp@fedoraproject.org> Link: https://lore.kernel.org/qemu-devel/20260123141656.6765-26-farosas@suse.de Signed-off-by: Fabiano Rosas <farosas@suse.de>
117 lines
2.7 KiB
C
117 lines
2.7 KiB
C
/*
|
|
* QEMU live migration via generic fd
|
|
*
|
|
* Copyright Red Hat, Inc. 2009-2016
|
|
*
|
|
* Authors:
|
|
* Chris Lalancette <clalance@redhat.com>
|
|
* Daniel P. Berrange <berrange@redhat.com>
|
|
*
|
|
* This work is licensed under the terms of the GNU GPL, version 2. See
|
|
* the COPYING file in the top-level directory.
|
|
*
|
|
* Contributions after 2012-01-13 are licensed under the terms of the
|
|
* GNU GPL, version 2 or (at your option) any later version.
|
|
*/
|
|
|
|
#include "qemu/osdep.h"
|
|
#include "channel.h"
|
|
#include "fd.h"
|
|
#include "file.h"
|
|
#include "migration.h"
|
|
#include "monitor/monitor.h"
|
|
#include "qemu/error-report.h"
|
|
#include "qemu/sockets.h"
|
|
#include "io/channel-util.h"
|
|
#include "trace.h"
|
|
#include "qapi/error.h"
|
|
|
|
static bool fd_is_pipe(int fd)
|
|
{
|
|
struct stat statbuf;
|
|
|
|
if (fstat(fd, &statbuf) == -1) {
|
|
return false;
|
|
}
|
|
|
|
return S_ISFIFO(statbuf.st_mode);
|
|
}
|
|
|
|
static bool migration_fd_valid(int fd)
|
|
{
|
|
if (fd_is_socket(fd)) {
|
|
return true;
|
|
}
|
|
|
|
if (fd_is_pipe(fd)) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
QIOChannel *fd_connect_outgoing(MigrationState *s, const char *fdname,
|
|
Error **errp)
|
|
{
|
|
QIOChannel *ioc = NULL;
|
|
int fd = monitor_get_fd(monitor_cur(), fdname, errp);
|
|
if (fd == -1) {
|
|
goto out;
|
|
}
|
|
|
|
if (!migration_fd_valid(fd)) {
|
|
error_setg(errp, "fd: migration to a file is not supported."
|
|
" Use file: instead.");
|
|
goto out;
|
|
}
|
|
|
|
trace_migration_fd_outgoing(fd);
|
|
ioc = qio_channel_new_fd(fd, errp);
|
|
if (!ioc) {
|
|
close(fd);
|
|
goto out;
|
|
}
|
|
|
|
qio_channel_set_name(ioc, "migration-fd-outgoing");
|
|
out:
|
|
return ioc;
|
|
}
|
|
|
|
static gboolean fd_accept_incoming_migration(QIOChannel *ioc,
|
|
GIOCondition condition,
|
|
gpointer opaque)
|
|
{
|
|
migration_channel_process_incoming(ioc);
|
|
object_unref(OBJECT(ioc));
|
|
return G_SOURCE_REMOVE;
|
|
}
|
|
|
|
void fd_connect_incoming(const char *fdname, Error **errp)
|
|
{
|
|
QIOChannel *ioc;
|
|
int fd = monitor_fd_param(monitor_cur(), fdname, errp);
|
|
if (fd == -1) {
|
|
return;
|
|
}
|
|
|
|
if (!migration_fd_valid(fd)) {
|
|
error_setg(errp, "fd: migration to a file is not supported."
|
|
" Use file: instead.");
|
|
return;
|
|
}
|
|
|
|
trace_migration_fd_incoming(fd);
|
|
|
|
ioc = qio_channel_new_fd(fd, errp);
|
|
if (!ioc) {
|
|
close(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());
|
|
}
|