Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > media > main-src > by-pkgid > aadbe78a25743146bb784eee19f007c5 > files > 173

kvm-83-164.el5_5.9.src.rpm

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