xemu/migration/fd.c

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

113 lines
2.6 KiB
C
Raw Normal View History

/*
* 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"
migration: Allow pipes to keep working for fd migrations Libvirt may still use pipes for old file migrations in fd: URI form, especially when loading old images dumped from Libvirt's compression algorithms. In that case, Libvirt needs to compress / uncompress the images on its own over the migration binary stream, and pipes are passed over to QEMU for outgoing / incoming migrations in "fd:" URIs. For future such use case, it should be suggested to use mapped-ram when saving such VM image. However there can still be old images that was compressed in such way, so libvirt needs to be able to load those images, uncompress them and use the same pipe mechanism to pass that over to QEMU. It means, even if new file migrations can be gradually moved over to mapped-ram (after Libvirt start supporting it), Libvirt still needs the uncompressor for the old images to be able to load like before. Meanwhile since Libvirt currently exposes the compression capability to guest images, it may needs its own lifecycle management to move that over to mapped-ram, maybe can be done after mapped-ram saved the image, however Dan and PeterK raised concern on temporary double disk space consumption. I suppose for now the easiest is to enable pipes for both sides of "fd:" migrations, until all things figured out from Libvirt side on how to move on. And for "channels" QMP interface support on "migrate" / "migrate-incoming" commands, we'll also need to move away from pipe. But let's leave that for later too. So far, still allow pipes to happen like before on both save/load sides, just like we would allow sockets to pass. Cc: qemu-stable <qemu-stable@nongnu.org> Cc: Fabiano Rosas <farosas@suse.de> Cc: Peter Krempa <pkrempa@redhat.com> Cc: Daniel P. Berrangé <berrange@redhat.com> Fixes: c55deb860c ("migration: Deprecate fd: for file migration") Reviewed-by: Fabiano Rosas <farosas@suse.de> Link: https://lore.kernel.org/r/20241120160132.3659735-1-peterx@redhat.com Signed-off-by: Peter Xu <peterx@redhat.com>
2024-11-20 16:01:32 +00:00
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;
}
void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **errp)
{
QIOChannel *ioc;
int fd = monitor_get_fd(monitor_cur(), fdname, errp);
if (fd == -1) {
return;
}
migration: Allow pipes to keep working for fd migrations Libvirt may still use pipes for old file migrations in fd: URI form, especially when loading old images dumped from Libvirt's compression algorithms. In that case, Libvirt needs to compress / uncompress the images on its own over the migration binary stream, and pipes are passed over to QEMU for outgoing / incoming migrations in "fd:" URIs. For future such use case, it should be suggested to use mapped-ram when saving such VM image. However there can still be old images that was compressed in such way, so libvirt needs to be able to load those images, uncompress them and use the same pipe mechanism to pass that over to QEMU. It means, even if new file migrations can be gradually moved over to mapped-ram (after Libvirt start supporting it), Libvirt still needs the uncompressor for the old images to be able to load like before. Meanwhile since Libvirt currently exposes the compression capability to guest images, it may needs its own lifecycle management to move that over to mapped-ram, maybe can be done after mapped-ram saved the image, however Dan and PeterK raised concern on temporary double disk space consumption. I suppose for now the easiest is to enable pipes for both sides of "fd:" migrations, until all things figured out from Libvirt side on how to move on. And for "channels" QMP interface support on "migrate" / "migrate-incoming" commands, we'll also need to move away from pipe. But let's leave that for later too. So far, still allow pipes to happen like before on both save/load sides, just like we would allow sockets to pass. Cc: qemu-stable <qemu-stable@nongnu.org> Cc: Fabiano Rosas <farosas@suse.de> Cc: Peter Krempa <pkrempa@redhat.com> Cc: Daniel P. Berrangé <berrange@redhat.com> Fixes: c55deb860c ("migration: Deprecate fd: for file migration") Reviewed-by: Fabiano Rosas <farosas@suse.de> Link: https://lore.kernel.org/r/20241120160132.3659735-1-peterx@redhat.com Signed-off-by: Peter Xu <peterx@redhat.com>
2024-11-20 16:01:32 +00:00
if (!migration_fd_valid(fd)) {
warn_report("fd: migration to a file is deprecated."
" Use file: instead.");
}
trace_migration_fd_outgoing(fd);
ioc = qio_channel_new_fd(fd, errp);
if (!ioc) {
close(fd);
return;
}
qio_channel_set_name(ioc, "migration-fd-outgoing");
migration_channel_connect(s, ioc, NULL, NULL);
object_unref(OBJECT(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_start_incoming_migration(const char *fdname, Error **errp)
{
QIOChannel *ioc;
int fd = monitor_fd_param(monitor_cur(), fdname, errp);
if (fd == -1) {
return;
}
migration: Allow pipes to keep working for fd migrations Libvirt may still use pipes for old file migrations in fd: URI form, especially when loading old images dumped from Libvirt's compression algorithms. In that case, Libvirt needs to compress / uncompress the images on its own over the migration binary stream, and pipes are passed over to QEMU for outgoing / incoming migrations in "fd:" URIs. For future such use case, it should be suggested to use mapped-ram when saving such VM image. However there can still be old images that was compressed in such way, so libvirt needs to be able to load those images, uncompress them and use the same pipe mechanism to pass that over to QEMU. It means, even if new file migrations can be gradually moved over to mapped-ram (after Libvirt start supporting it), Libvirt still needs the uncompressor for the old images to be able to load like before. Meanwhile since Libvirt currently exposes the compression capability to guest images, it may needs its own lifecycle management to move that over to mapped-ram, maybe can be done after mapped-ram saved the image, however Dan and PeterK raised concern on temporary double disk space consumption. I suppose for now the easiest is to enable pipes for both sides of "fd:" migrations, until all things figured out from Libvirt side on how to move on. And for "channels" QMP interface support on "migrate" / "migrate-incoming" commands, we'll also need to move away from pipe. But let's leave that for later too. So far, still allow pipes to happen like before on both save/load sides, just like we would allow sockets to pass. Cc: qemu-stable <qemu-stable@nongnu.org> Cc: Fabiano Rosas <farosas@suse.de> Cc: Peter Krempa <pkrempa@redhat.com> Cc: Daniel P. Berrangé <berrange@redhat.com> Fixes: c55deb860c ("migration: Deprecate fd: for file migration") Reviewed-by: Fabiano Rosas <farosas@suse.de> Link: https://lore.kernel.org/r/20241120160132.3659735-1-peterx@redhat.com Signed-off-by: Peter Xu <peterx@redhat.com>
2024-11-20 16:01:32 +00:00
if (!migration_fd_valid(fd)) {
warn_report("fd: migration to a file is deprecated."
" Use file: instead.");
}
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());
}