From e6ba3320822fdf774cf3a76716f00960fb6f7fd7 Mon Sep 17 00:00:00 2001
From: Dimitris Aragiorgis <dimara@grnet.gr>
Date: Tue, 8 Jan 2013 19:38:16 +0200
Subject: [PATCH] Add machine version in kvm runtime file

kvm -M ? returns the supported machines (e.g. pc-1.1).
Add _GetDefaultMachineVersion() function to get the default value.

Upon kvm runtime file creation (this is in _GenerateKVMRuntime() invoked
only in StartInstance()) append this info in kvm_cmd. During
live migration the -incoming kvm process is started based on this file.

In case of different KVM versions between source and target nodes
there is a possibility (e.g. due to a kvm bug) for migration to fail silently.

This patch forces the target node to emulate the same machine version
used by running process. If KVM on target node does not support it
the -incoming kvm process will crash and migration will be aborted.

Signed-off-by: Dimitris Aragiorgis <dimara@grnet.gr>
Reviewed-by: Guido Trotter <ultrotter@google.com>
---
 lib/hypervisor/hv_kvm.py | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/lib/hypervisor/hv_kvm.py b/lib/hypervisor/hv_kvm.py
index a388ec254..2fd3684e5 100644
--- a/lib/hypervisor/hv_kvm.py
+++ b/lib/hypervisor/hv_kvm.py
@@ -549,6 +549,8 @@ class KVMHypervisor(hv_base.BaseHypervisor):
   _CPU_INFO_CMD = "info cpus"
   _CONT_CMD = "cont"
 
+  _DEFAULT_MACHINE_VERSION_RE = re.compile(r"(\S+).*\(default\)")
+
   ANCILLARY_FILES = [
     _KVM_NETWORK_SCRIPT,
     ]
@@ -1003,6 +1005,7 @@ class KVMHypervisor(hv_base.BaseHypervisor):
     pidfile = self._InstancePidFile(instance.name)
     kvm = constants.KVM_PATH
     kvm_cmd = [kvm]
+    kvm_cmd.extend(["-M", self._GetDefaultMachineVersion()])
     # used just by the vnc server, if enabled
     kvm_cmd.extend(["-name", instance.name])
     kvm_cmd.extend(["-m", instance.beparams[constants.BE_MAXMEM]])
@@ -1654,6 +1657,21 @@ class KVMHypervisor(hv_base.BaseHypervisor):
       else:
         self._CallMonitorCommand(name, "system_powerdown")
 
+  @classmethod
+  def _GetDefaultMachineVersion(cls):
+    """Return the default hardware revision (e.g. pc-1.1)
+
+    """
+    result = utils.RunCmd([constants.KVM_PATH, "-M", "?"])
+    if result.failed:
+      raise errors.HypervisorError("Unable to get default hardware revision")
+    for line in result.output.splitlines():
+      match = cls._DEFAULT_MACHINE_VERSION_RE.match(line)
+      if match:
+        return match.group(1)
+
+    return "pc"
+
   def CleanupInstance(self, instance_name):
     """Cleanup after a stopped instance
 
-- 
GitLab