Skip to content

Commit

Permalink
More robust CPU selection
Browse files Browse the repository at this point in the history
CPU model for Lago VMs is passed through from the host and the cluster CPU
family is set based on that CPU model.  With this approach, the environment
deployment may fail due to invalid CPU family of the cluster.  Although the
family corresponds to the host CPU, kernel may remove some CPU flags in nested
virtual machines (when the Lago host is actually a VM).  Then some CPU flags
required for the given CPU family (such as Haswell-NoTSX) may be missing in the
Lago virtual machines.  This is a real problem observed on Lenovo W541.

This patch fixes the problem by selecting the minimum reasonable CPU model.
Westmere is selected unless older or non-Intel hardware is used.  Additionally,
virtualization flags may still be missing with some CPU models (real problem
observed on Lenovo W541 with Westmere).  So let's them to the CPU features,
simply for both Intel and AMD families as optional features, libvirt will do
the right thing with this setting.

A future patch could make the CPU family configurable, when one wants to run
the tests on a different CPU model.
  • Loading branch information
mz-pdm committed Jan 4, 2017
1 parent bfd635d commit 05ccf72
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 24 deletions.
5 changes: 4 additions & 1 deletion lago/dom_template.xml
Expand Up @@ -3,7 +3,10 @@
<memory unit='MiB'>@MEM_SIZE@</memory>
<vcpu>@VCPU@</vcpu>
<iothreads>1</iothreads>
<cpu mode='host-passthrough'>
<cpu match="exact">
<model>@CPUMODEL@</model>
<feature policy='optional' name='vmx'/>
<feature policy='optional' name='svm'/>
<topology sockets='@CPU@' cores='1' threads='1'/>
</cpu>
<os>
Expand Down
25 changes: 25 additions & 0 deletions lago/virt.py
Expand Up @@ -76,6 +76,19 @@ class VirtEnv(object):
* libvirt_con
'''

_CPU_FAMILIES = {
'Westmere': 'Intel Westmere Family',
'Nehalem': 'Intel Nehalem Family',
'Penryn': 'Intel Penryn Family',
'Conroe': 'Intel Conroe Family',
'Opteron_G5': 'AMD Opteron G5',
'Opteron_G4': 'AMD Opteron G4',
'Opteron_G3': 'AMD Opteron G3',
'Opteron_G2': 'AMD Opteron G2',
'Opteron_G1': 'AMD Opteron G1',
}
_compatible_cpu_and_family = None

def __init__(self, prefix, vm_specs, net_specs):
self.vm_types = plugins.load_plugins(
plugins.PLUGIN_ENTRY_POINTS['vm'],
Expand Down Expand Up @@ -105,6 +118,18 @@ def get_cpu_model(self):
cpu_model = cap_tree.xpath('/capabilities/host/cpu/model')[0].text
return cpu_model

def get_compatible_cpu_and_family(self):
if self._compatible_cpu_and_family is None:
for cpu in (
self.get_cpu_model(),
'Westmere',
):
family = self._CPU_FAMILIES.get(cpu)
if family is not None:
break
self._compatible_cpu_and_family = cpu, family
return self._compatible_cpu_and_family

def _create_net(self, net_spec):
if net_spec['type'] == 'nat':
cls = NATNetwork
Expand Down
1 change: 1 addition & 0 deletions lago/vm.py
Expand Up @@ -286,6 +286,7 @@ def _libvirt_xml(self):
'@NAME@': self._libvirt_name(),
'@VCPU@': self.vm._spec.get('vcpu', 2),
'@CPU@': self.vm._spec.get('cpu', 2),
'@CPUMODEL@': self.vm.virt_env.get_compatible_cpu_and_family()[0],
'@MEM_SIZE@': self.vm._spec.get('memory', 16 * 1024),
'@QEMU_KVM@': qemu_kvm_path,
}
Expand Down
24 changes: 1 addition & 23 deletions ovirtlago/virt.py
Expand Up @@ -88,29 +88,7 @@ def host_vms(self):
return self._host_vms[:]

def get_ovirt_cpu_family(self):
ovirt_cpu_families = {
'Broadwell': 'Intel Broadwell Family',
'Broadwell-noTSX': 'Intel Broadwell-noTSX Family',
'Haswell': 'Intel Haswell Family',
'Haswell-noTSX': 'Intel Haswell-noTSX Family',
'SandyBridge': 'Intel SandyBridge Family',
'Westmere': 'Intel Westmere Family',
'Nehalem': 'Intel Nehalem Family',
'Penryn': 'Intel Penryn Family',
'Conroe': 'Intel Conroe Family',
'Opteron_G5': 'AMD Opteron G5',
'Opteron_G4': 'AMD Opteron G4',
'Opteron_G3': 'AMD Opteron G3',
'Opteron_G2': 'AMD Opteron G2',
'Opteron_G1': 'AMD Opteron G1',
}

if self._ovirt_cpu_family is None:
cpu_model = super(OvirtVirtEnv, self).get_cpu_model()
self._ovirt_cpu_family = ovirt_cpu_families.get(
cpu_model, ovirt_cpu_families['Conroe']
)
return self._ovirt_cpu_family
return super(OvirtVirtEnv, self).get_compatible_cpu_and_family()[1]


# TODO : solve the problem of ssh to the Node
Expand Down

0 comments on commit 05ccf72

Please sign in to comment.