From 3b8446d6a787e414506e79e9f3d9a3322d931144 Mon Sep 17 00:00:00 2001 From: Juan Quintela <quintela@redhat.com> Date: Fri, 10 Apr 2009 13:25:38 +0200 Subject: [PATCH 06/11] Reopen block drivers after migration This patch reopens the block drivers just before the migration ends. This is needed because there are formats like qcow2, where you need to re-read the metadata if the file has changed. Signed-off-by: Juan Quintela <quintela@redhat.com> Message-Id: <5890417e75fd94bd57738290e319c75e5371812a.1239359004.git.quintela@redhat.com> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com RH-Upstream-status: pending Acked-by: john cooper <john.cooper@redhat.com> Acked-by: Zachary Amsden <zamsden@redhat.com> Acked-by: Eduardo Habkost <ehabkost@redhat.com> Bugzilla: 497886 --- qemu/migration-tcp.c | 4 ++++ qemu/sysemu.h | 6 ++++++ qemu/vl.c | 40 ++++++++++++++++++++++++++++++++++++---- 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/qemu/migration-tcp.c b/qemu/migration-tcp.c index d4214b5..b1d4656 100644 --- a/qemu/migration-tcp.c +++ b/qemu/migration-tcp.c @@ -482,6 +482,10 @@ static void tcp_incoming_load_vm(void) close(in_state.listener); in_state.listener = -1; term_printf_async(MIGRATION_ASYNC_EVENT, "migration: migration process finished\n"); + if (drives_reopen() != 0) { + fprintf(stderr, "reopening of drives failed\n"); + goto error; + } vm_start(); error: diff --git a/qemu/sysemu.h b/qemu/sysemu.h index 5d510f8..f920346 100644 --- a/qemu/sysemu.h +++ b/qemu/sysemu.h @@ -146,6 +146,10 @@ typedef struct DriveInfo { char serial[21]; int used; int drive_opt_idx; + int opened; + int bdrv_flags; + char *file; + BlockDriver *drv; } DriveInfo; #define MAX_IDE_DEVS 2 @@ -177,6 +181,8 @@ struct QEMUMachine; extern int drive_add(const char *file, const char *fmt, ...); extern int drive_init(struct drive_opt *arg, int snapshot, struct QEMUMachine *machine); +extern int drive_open(DriveInfo drive); +extern int drives_reopen(void); /* acpi */ void qemu_system_cpu_hot_add(int cpu, int state); diff --git a/qemu/vl.c b/qemu/vl.c index ca8e68e..030de15 100644 --- a/qemu/vl.c +++ b/qemu/vl.c @@ -2699,14 +2699,46 @@ int drive_init(struct drive_opt *arg, int snapshot, bdrv_flags |= BDRV_O_CACHE_WB; else if (cache == 3) /* not specified */ bdrv_flags |= BDRV_O_CACHE_DEF; - if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0) { + + drives_table[drives_table_idx].drv = drv; + drives_table[drives_table_idx].bdrv_flags = bdrv_flags; + drives_table[drives_table_idx].file = strdup(file); + drives_table[drives_table_idx].opened = 1; + if (drive_open(drives_table[drives_table_idx]) != 0) + return -1; + return drives_table_idx; +} + +int drive_open(DriveInfo drive) +{ + if (bdrv_open2(drive.bdrv, drive.file, drive.bdrv_flags, drive.drv) < 0) { fprintf(stderr, "qemu: could not open disk image %s\n", - file); + drive.file); return -1; } - return drives_table_idx; + return 0; } +int drives_reopen(void) +{ + int i; + + for (i=0; i < nb_drives; i++) + if (drives_table[i].used && drives_table[i].opened) { + int res; + + bdrv_close(drives_table[i].bdrv); + res = drive_open(drives_table[i]); + if (res) { + fprintf(stderr, "qemu: re-open of %s failed wth error %d\n", + drives_table[i].file, res); + return res; + } + } + return 0; + } + + /***********************************************************/ /* USB devices */ @@ -6033,7 +6065,7 @@ int main(int argc, char **argv, char **envp) */ for(i = 0; i < nb_drives_opt; i++) if (drive_init(&drives_opt[i], snapshot, machine) == -1) - exit(1); + exit(1); register_savevm("timer", 0, 2, timer_save, timer_load, NULL); register_savevm_live("ram", 0, 3, ram_save_live, NULL, ram_load, NULL); -- 1.6.1