From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LOhqy-000814-2b for qemu-devel@nongnu.org; Sun, 18 Jan 2009 19:18:56 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LOhqu-00080d-3K for qemu-devel@nongnu.org; Sun, 18 Jan 2009 19:18:54 -0500 Received: from [199.232.76.173] (port=32965 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LOhqu-00080a-0S for qemu-devel@nongnu.org; Sun, 18 Jan 2009 19:18:52 -0500 Received: from mx2.redhat.com ([66.187.237.31]:45412) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1LOhqt-0000AC-HV for qemu-devel@nongnu.org; Sun, 18 Jan 2009 19:18:51 -0500 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id n0J0Im8N001437 for ; Sun, 18 Jan 2009 19:18:50 -0500 From: Uri Lublin Date: Mon, 19 Jan 2009 02:18:45 +0200 Message-Id: <1232324325-25060-1-git-send-email-uril@redhat.com> Subject: [Qemu-devel] [PATCH] migration: adding migration to/from a file Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Uri Lublin Migration to file, reuses migration-to-fd. Migration from file, uses qemu-fopen directly. The saved state-file should be used only once and removed (or used with -snapshot, or a the disk-image should be copied), as the disk image is not saved, only the VM state. Also there is not point of doing a _live_ migration to file (except for debugging migration code), so I recommend to stop the VM before migrating its state to a file. An advantage migration-to-file over savevm/loadvm is that for the latter a qcow2 is a requirement, while the former works for any image-format. Signed-off-by: Uri Lublin --- Makefile | 2 +- migration-file.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ migration.c | 4 ++ migration.h | 5 ++ 4 files changed, 137 insertions(+), 1 deletions(-) create mode 100644 migration-file.c diff --git a/Makefile b/Makefile index 8cbdcda..7e0e6f2 100644 --- a/Makefile +++ b/Makefile @@ -81,7 +81,7 @@ OBJS+=usb.o usb-hub.o usb-$(HOST_USB).o usb-hid.o usb-msd.o usb-wacom.o OBJS+=usb-serial.o usb-net.o OBJS+=sd.o ssi-sd.o OBJS+=bt.o bt-host.o bt-vhci.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o usb-bt.o -OBJS+=buffered_file.o migration.o migration-tcp.o net.o qemu-sockets.o +OBJS+=buffered_file.o migration.o migration-tcp.o migration-file.o net.o qemu-sockets.o OBJS+=qemu-char.o aio.o net-checksum.o savevm.o cache-utils.o ifdef CONFIG_BRLAPI diff --git a/migration-file.c b/migration-file.c new file mode 100644 index 0000000..5cde3e2 --- /dev/null +++ b/migration-file.c @@ -0,0 +1,127 @@ +/* + * QEMU live migration + * + * Copyright IBM, Corp. 2008 + * Red Hat, Inc. 2008 + * + * Authors: + * Anthony Liguori + * Uri Lublin + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ + +#include +#include "qemu-common.h" +#include "migration.h" +#include "sysemu.h" +#include "console.h" +#include "block.h" + +//#define DEBUG_MIGRATION_FILE + +#ifdef DEBUG_MIGRATION_FILE +#define dprintf(fmt, ...) \ + do { printf("migration-file: " fmt, ## __VA_ARGS__); } while (0) +#else +#define dprintf(fmt, ...) \ + do { } while (0) +#endif + +static int file_close(FdMigrationState *s) +{ + close(s->fd); +} + +static int file_errno(FdMigrationState *s) +{ + return errno; +} + +static int file_write(FdMigrationState *s, const void * buf, size_t size) +{ + return write(s->fd, buf, size); +} + +MigrationState *file_start_outgoing_migration(const char *filename, + int64_t bandwidth_limit, + int async) +{ + FdMigrationState *s; + int fd; + + s = qemu_mallocz(sizeof(*s)); + if (s == NULL) { + perror("file_migration: qemu_mallocz failed"); + term_printf("file_migration: qemu_mallocz failed"); + goto err1; + } + + fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); + if (fd < 0) { + perror("file_migration: failed to open filename"); + term_printf("file_migration: failed to open filename %s\n", filename); + goto err2; + } + + s->fd = fd; + s->close = file_close; + s->get_error = file_errno; + s->write = file_write; + s->mig_state.cancel = migrate_fd_cancel; + s->mig_state.get_status = migrate_fd_get_status; + s->mig_state.release = migrate_fd_release; + + s->state = MIG_STATE_ACTIVE; + s->detach = !async; + s->bandwidth_limit = bandwidth_limit; + + if (s->detach == 1) { + dprintf("detaching from monitor\n"); + monitor_suspend(); + s->detach = 2; + } + + migrate_fd_connect(s); + return &s->mig_state; + +err1: + close(fd); + unlink(filename); +err2: + qemu_free(s); + + return NULL; +} + +int file_start_incoming_migration(const char *filename) +{ + int ret; + QEMUFile *f; + + dprintf("Starting incoming file migration from '%s'\n", filename); + f = qemu_fopen(filename, "rb"); + if(f == NULL) { + perror("failed to open file"); + term_printf("failed to open file %s\n", filename); + return -errno; + } + + vm_stop(0); /* just in case */ + ret = qemu_loadvm_state(f); + if (ret < 0) { + fprintf(stderr, "in_file_mig: load of migration failed\n"); + goto err; + } + qemu_announce_self(); + dprintf("successfully loaded vm state\n"); + vm_start(); + qemu_fclose(f); + return 0; + +err: + qemu_fclose(f); + return -errno; +} diff --git a/migration.c b/migration.c index 0ef777a..0dde557 100644 --- a/migration.c +++ b/migration.c @@ -44,6 +44,8 @@ void qemu_start_incoming_migration(const char *uri) else if (strstart(uri, "exec:", &p)) exec_start_incoming_migration(p); #endif + else if (strstart(uri, "file:", &p)) + file_start_incoming_migration(p); else fprintf(stderr, "unknown migration protocol: %s\n", uri); } @@ -59,6 +61,8 @@ void do_migrate(int detach, const char *uri) else if (strstart(uri, "exec:", &p)) s = exec_start_outgoing_migration(p, max_throttle, detach); #endif + else if (strstart(uri, "file:", &p)) + s = file_start_outgoing_migration(p, (1<<31), detach); else term_printf("unknown migration protocol: %s\n", uri); diff --git a/migration.h b/migration.h index d9771ad..30d4ab4 100644 --- a/migration.h +++ b/migration.h @@ -67,6 +67,11 @@ MigrationState *tcp_start_outgoing_migration(const char *host_port, int64_t bandwidth_limit, int detach); +MigrationState *file_start_outgoing_migration(const char *filename, + int64_t bandwidth_limit, + int detach); +int file_start_incoming_migration(const char *filename); + void migrate_fd_error(FdMigrationState *s); void migrate_fd_cleanup(FdMigrationState *s); -- 1.6.0.6