Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 340e01248478ba8b78a6d4d1809b1eff > files > 735

kvm-83-270.el5_11.src.rpm

From fd5247b1cd3f9a84a20987000e31277873803cb4 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Fri, 8 Apr 2011 16:06:48 -0300
Subject: [PATCH 2/2] race between qemu monitor "cont" and incoming migration can cause failed restore/migration

RH-Author: Paolo Bonzini <pbonzini@redhat.com>
Message-id: <1302278808-29135-1-git-send-email-pbonzini@redhat.com>
Patchwork-id: 21689
O-Subject: [RHEL5.7 kvm PATCH] race between qemu monitor "cont" and incoming migration can cause failed restore/migration
Bugzilla: 647368
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
RH-Acked-by: Juan Quintela <quintela@redhat.com>
RH-Acked-by: Don Dutile <ddutile@redhat.com>

Bugzilla: 647368

Upstream: a different patch was committed upstream and in RHEL6 which
    depends on QMP.  I backported this one from v1; discussion upstream at
    http://lists.gnu.org/archive/html/qemu-devel/2010-07/msg01385.html

Brew build: http://brewweb.devel.redhat.com/brew/taskinfo?taskID=3244318

When a 'cont' is issued on a VM that's just waiting for an incoming
migration, the VM reboots and boots into the guest, crashing it or
possibly corrupting its storage since it could be shared with another
VM running elsewhere.

Ensure that a VM started with '-incoming' is only run when an incoming
migration successfully completes.  However, we still need to ask for
passwords (unlike RHEL6+upstream) because libvirt will only attempt
to execute "cont" once with the text-based monitor.

Signed-off-by: Amit Shah <amit.shah@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 qemu/migration-exec.c |    2 ++
 qemu/migration-tcp.c  |    2 ++
 qemu/monitor.c        |    4 ++++
 qemu/sysemu.h         |    1 +
 qemu/vl.c             |    3 +++
 5 files changed, 12 insertions(+), 0 deletions(-)

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 qemu/migration-exec.c |    2 ++
 qemu/migration-tcp.c  |    2 ++
 qemu/monitor.c        |    4 ++++
 qemu/sysemu.h         |    1 +
 qemu/vl.c             |    3 +++
 5 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/qemu/migration-exec.c b/qemu/migration-exec.c
index 6f8470b..45ea8b5 100644
--- a/qemu/migration-exec.c
+++ b/qemu/migration-exec.c
@@ -141,6 +141,8 @@ int exec_start_incoming_migration(const char *command)
     qemu_announce_self();
     dprintf("successfully loaded vm state\n");
     term_printf_async(MIGRATION_ASYNC_EVENT, "migration: migration process finished\n");
+    incoming_expected = 0;
+    incoming_done = 1;
     if (autostart)
         vm_start();
     qemu_fclose(f);
diff --git a/qemu/migration-tcp.c b/qemu/migration-tcp.c
index e81393c..dc0e385 100644
--- a/qemu/migration-tcp.c
+++ b/qemu/migration-tcp.c
@@ -486,6 +486,8 @@ static void tcp_incoming_load_vm(void)
 	    fprintf(stderr, "reopening of drives failed\n");
 	    goto error;
     }
+    incoming_expected = 0;
+    incoming_done = 1;
     if (autostart)
         vm_start();
 
diff --git a/qemu/monitor.c b/qemu/monitor.c
index 5b5ffb6..42a1172 100644
--- a/qemu/monitor.c
+++ b/qemu/monitor.c
@@ -640,6 +640,10 @@ static void do_cont(void)
     int err = 0;
 
     bdrv_iterate(encrypted_bdrv_it, &err);
+    if (!err && incoming_expected && !incoming_done) {
+        autostart = 1;
+        return; /* Waiting for incoming migration */
+    }
     /* only resume the vm if all keys are set and valid */
     if (!err)
         vm_start();
diff --git a/qemu/sysemu.h b/qemu/sysemu.h
index 3484651..cda1e92 100644
--- a/qemu/sysemu.h
+++ b/qemu/sysemu.h
@@ -94,6 +94,7 @@ int tap_win32_init(VLANState *vlan, const char *model,
 void do_info_slirp(void);
 
 extern int autostart;
+extern int incoming_expected, incoming_done;
 extern int bios_size;
 extern int cirrus_vga_enabled;
 extern int vmsvga_enabled;
diff --git a/qemu/vl.c b/qemu/vl.c
index a6bfbf8..781f11c 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -245,6 +245,8 @@ int cursor_hide = 1;
 int graphic_rotate = 0;
 int daemonize = 0;
 int autostart = 0;
+int incoming_expected = 0;
+int incoming_done = 0;
 const char *incoming;
 const char *option_rom[MAX_OPTION_ROMS];
 int nb_option_roms;
@@ -6046,6 +6048,7 @@ int main(int argc, char **argv, char **envp)
                 break;
             case QEMU_OPTION_incoming:
                 incoming = optarg;
+                incoming_expected = 1;
                 break;
             case QEMU_OPTION_notify: {
                 if (enable_async_notification(optarg)) {
-- 
1.7.3.2