diff --git a/lib/backend.py b/lib/backend.py index 5e50f2f373b3f821ad6ad557505130892af77370..bfe6669d0ccb85f5962f378b2c59088fab012e36 100644 --- a/lib/backend.py +++ b/lib/backend.py @@ -443,6 +443,7 @@ def GetNodeInfo(vgname, hypervisor_type): - memory_dom0 is the memory allocated for domain0 in MiB - memory_free is the currently available (free) ram in MiB - memory_total is the total number of ram in MiB + - hv_version: the hypervisor version, if available """ outputarray = {} diff --git a/lib/cmdlib.py b/lib/cmdlib.py index 4f33e5f1873e89a368826b45d4117da1fddc8c40..87ef9f1517348b0ef8ca6e8493a13cfb7bc430fd 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -7343,6 +7343,21 @@ class TLMigrateInstance(Tasklet): target_node = self.target_node source_node = self.source_node + # Check for hypervisor version mismatch and warn the user. + nodeinfo = self.rpc.call_node_info([source_node, target_node], + None, self.instance.hypervisor) + src_info = nodeinfo[source_node] + dst_info = nodeinfo[target_node] + + if ((constants.HV_NODEINFO_KEY_VERSION in src_info.payload) and + (constants.HV_NODEINFO_KEY_VERSION in dst_info.payload)): + src_version = src_info.payload[constants.HV_NODEINFO_KEY_VERSION] + dst_version = dst_info.payload[constants.HV_NODEINFO_KEY_VERSION] + if src_version != dst_version: + self.feedback_fn("* warning: hypervisor version mismatch between" + " source (%s) and target (%s) node" % + (src_version, dst_version)) + self.feedback_fn("* checking disk consistency between source and target") for dev in instance.disks: if not _CheckDiskConsistency(self.lu, dev, target_node, False): diff --git a/lib/constants.py b/lib/constants.py index dfb541a75b3563c64a93531d75963d45d0648f04..fd9cc7c0ba3ec2b6c663a3ceb57ac55efaaf98ee 100644 --- a/lib/constants.py +++ b/lib/constants.py @@ -776,6 +776,9 @@ HVS_PARAMETER_TYPES = { HVS_PARAMETERS = frozenset(HVS_PARAMETER_TYPES.keys()) +# Node info keys +HV_NODEINFO_KEY_VERSION = "hv_version" + # Backend parameter names BE_MEMORY = "memory" BE_VCPUS = "vcpus" diff --git a/lib/hypervisor/hv_kvm.py b/lib/hypervisor/hv_kvm.py index 2f1b67dbffa06745ae34fcf62725a2e6d9946b9f..176e448450378fa34d2dd747d7642ce7f1c85584 100644 --- a/lib/hypervisor/hv_kvm.py +++ b/lib/hypervisor/hv_kvm.py @@ -1541,15 +1541,18 @@ class KVMHypervisor(hv_base.BaseHypervisor): def GetNodeInfo(self): """Return information about the node. - This is just a wrapper over the base GetLinuxNodeInfo method. - @return: a dict with the following keys (values in MiB): - memory_total: the total memory size on the node - memory_free: the available memory on the node for instances - memory_dom0: the memory used by the node itself, if available + - hv_version: the hypervisor version in the form (major, minor, + revision) """ - return self.GetLinuxNodeInfo() + result = self.GetLinuxNodeInfo() + _, v_major, v_min, v_rev = self._GetKVMVersion() + result[constants.HV_NODEINFO_KEY_VERSION] = (v_major, v_min, v_rev) + return result @classmethod def GetInstanceConsole(cls, instance, hvparams, beparams): diff --git a/lib/hypervisor/hv_xen.py b/lib/hypervisor/hv_xen.py index 5a772d0b58aa87a474ec8a161d33e51c45f47fbe..5a4bdb9381e492f43b2f94b9ad4b248353893ea8 100644 --- a/lib/hypervisor/hv_xen.py +++ b/lib/hypervisor/hv_xen.py @@ -257,6 +257,7 @@ class XenHypervisor(hv_base.BaseHypervisor): - nr_cpus: total number of CPUs - nr_nodes: in a NUMA system, the number of domains - nr_sockets: the number of physical CPU sockets in the node + - hv_version: the hypervisor version in the form (major, minor) """ # note: in xen 3, memory has changed to total_memory @@ -269,6 +270,7 @@ class XenHypervisor(hv_base.BaseHypervisor): xmoutput = result.stdout.splitlines() result = {} cores_per_socket = threads_per_core = nr_cpus = None + xen_major, xen_minor = None, None for line in xmoutput: splitfields = line.split(":", 1) @@ -287,6 +289,10 @@ class XenHypervisor(hv_base.BaseHypervisor): cores_per_socket = int(val) elif key == "threads_per_core": threads_per_core = int(val) + elif key == "xen_major": + xen_major = int(val) + elif key == "xen_minor": + xen_minor = int(val) if (cores_per_socket is not None and threads_per_core is not None and nr_cpus is not None): @@ -296,6 +302,9 @@ class XenHypervisor(hv_base.BaseHypervisor): if dom0_info is not None: result["memory_dom0"] = dom0_info[2] + if not (xen_major is None or xen_minor is None): + result[constants.HV_NODEINFO_KEY_VERSION] = (xen_major, xen_minor) + return result @classmethod