Vitor de Lima has uploaded a new change for review. Change subject: Capabilities: List capabilities of the IBM POWER familiy ......................................................................
Capabilities: List capabilities of the IBM POWER familiy This introduces a parser capable of interpreting the /proc/cpuinfo present in IBM POWER hosts. It also retrieves the possible emulated machines for QEMU guests. The POWER 7 processors are not compatible between themselves so only the host CPU is reported as compatible in the _getCompatibleCpuModels() function. There is also a bug on libvirt that prevents the host CPU from being properly detected. This code has a workaround for this. A upcoming 'fake KVM on POWER' mode is partially included, adding a configuration parameter indicating to VDSM if it must report fake capabilities, so a x86_64 host could be used to validate POWER specific code. Change-Id: I42c4d00ace06805edbe765d975b40c9311a1fa9b Signed-off-by: Vitor de Lima <[email protected]> --- M lib/vdsm/config.py.in M tests/capsTests.py M vdsm/caps.py 3 files changed, 93 insertions(+), 36 deletions(-) git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/37/17437/1 diff --git a/lib/vdsm/config.py.in b/lib/vdsm/config.py.in index bdbd91a..d9b0db4 100644 --- a/lib/vdsm/config.py.in +++ b/lib/vdsm/config.py.in @@ -135,6 +135,8 @@ ('fake_kvm_support', 'false', None), + ('fake_kvm_architecture', 'x86_64', None), + ('xmlrpc_enable', 'true', 'Enable the xmlrpc server'), ('jsonrpc_enable', 'true', 'Enable the JSON RPC server'), diff --git a/tests/capsTests.py b/tests/capsTests.py index 9c7ea12..5c7c16c 100644 --- a/tests/capsTests.py +++ b/tests/capsTests.py @@ -31,7 +31,7 @@ testPath = os.path.realpath(__file__) dirName = os.path.split(testPath)[0] path = os.path.join(dirName, "cpu_info.out") - c = caps.CpuInfo(path) + c = caps.CpuInfo(path, 'x86_64') self.assertEqual(set(c.flags()), set("""fpu vme de pse tsc msr pae mce cx8 apic mtrr pge mca cmov pat pse36 clflush dts @@ -79,7 +79,7 @@ testPath = os.path.realpath(__file__) dirName = os.path.split(testPath)[0] path = os.path.join(dirName, "caps_libvirt_amd_6274.out") - machines = caps._getEmulatedMachines(file(path).read()) + machines = caps._getEmulatedMachines('x86_64', file(path).read()) expectedMachines = ['pc-0.15', 'pc', 'pc-1.0', 'pc-0.14', 'pc-0.13', 'pc-0.12', 'pc-0.11', 'pc-0.10', 'isapc'] diff --git a/vdsm/caps.py b/vdsm/caps.py index 3a7a6a2..e19ffcb 100644 --- a/vdsm/caps.py +++ b/vdsm/caps.py @@ -38,6 +38,8 @@ from vdsm import utils import storage.hba +import platform + # For debian systems we can use python-apt if available try: import apt @@ -64,10 +66,12 @@ class CpuInfo(object): - def __init__(self, cpuinfo='/proc/cpuinfo'): + def __init__(self, cpuinfo='/proc/cpuinfo', hostArch='x86_64'): """Parse /proc/cpuinfo""" self._info = {} p = {} + self.arch = hostArch + for line in file(cpuinfo): if line.strip() == '': p = {} @@ -79,13 +83,23 @@ p[key] = value def flags(self): - return self._info.itervalues().next()['flags'].split() + if self.arch == 'x86_64': + return self._info.itervalues().next()['flags'].split() + elif self.arch == 'ppc64': + return ['powernv'] def mhz(self): - return self._info.itervalues().next()['cpu MHz'] + if self.arch == 'x86_64': + return self._info.itervalues().next()['cpu MHz'] + elif self.arch == 'ppc64': + clock = self._info.itervalues().next()['clock'] + return clock[:-3] def model(self): - return self._info.itervalues().next()['model name'] + if self.arch == 'x86_64': + return self._info.itervalues().next()['model name'] + elif self.arch == 'ppc64': + return self._info.itervalues().next()['cpu'] class CpuTopology(object): @@ -131,46 +145,76 @@ @utils.memoized -def _getEmulatedMachines(capabilities=None): +def _getEmulatedMachines(arch='x86_64', capabilities=None): if capabilities is None: capabilities = _getCapsXMLStr() caps = minidom.parseString(capabilities) + for archTag in caps.getElementsByTagName('arch'): - if archTag.getAttribute('name') == 'x86_64': + if archTag.getAttribute('name') == arch: return [m.firstChild.data for m in archTag.childNodes if m.nodeName == 'machine'] return [] -def _getAllCpuModels(): +def _getAllCpuModels(arch): cpu_map = minidom.parseString( file('/usr/share/libvirt/cpu_map.xml').read()) + if arch == 'x86_64': + arch = 'x86' + + architectureElements = cpu_map.getElementsByTagName('arch') + allModels = dict() - for m in cpu_map.getElementsByTagName('arch')[0].childNodes: - if m.nodeName != 'model': - continue - element = m.getElementsByTagName('vendor') - if element: - vendor = element[0].getAttribute('name') - else: - # If current model doesn't have a vendor, check if it has a model - # that it is based on. The models in the cpu_map.xml file are - # sorted in a way that the base model is always defined before. - element = m.getElementsByTagName('model') - if element: - vendor = allModels.get(element[0].getAttribute('name'), None) - else: - vendor = None - allModels[m.getAttribute('name')] = vendor + + for a in architectureElements: + if a.getAttribute('name') == arch: + for m in a.childNodes: + if m.nodeName != 'model': + continue + element = m.getElementsByTagName('vendor') + if element: + vendor = element[0].getAttribute('name') + else: + # If current model doesn't have a vendor, check if it has + # a model that it is based on. The models in the + # cpu_map.xml file are sorted in a way that the base model + # is always defined before. + element = m.getElementsByTagName('model') + if element: + baseModel = element[0].getAttribute('name') + vendor = allModels.get(baseModel, None) + else: + vendor = None + allModels[m.getAttribute('name')] = vendor return allModels @utils.memoized -def _getCompatibleCpuModels(): +def _getCompatibleCpuModels(arch): + + if arch == 'ppc64': + # The entire POWER7 family is incompatible with each other, so + # it is enough to list only the host processor and its version + # This is also a hack around libvirt BZ#988077 + + for line in file('/proc/cpuinfo'): + if line.strip() == '': + continue + key, value = map(str.strip, line.split(':', 1)) + + if key == 'revision': + revision = value.split()[0] + + if revision == '2.0': + return ['model_POWER7'] + else: + return ['model_POWER7_v' + revision] + c = libvirtconnection.get() - allModels = _getAllCpuModels() + allModels = _getAllCpuModels(arch) def compatible(model, vendor): if not vendor: @@ -251,13 +295,20 @@ def get(): + hostArch = platform.machine() + + if config.getboolean('vars', 'fake_kvm_support'): + targetArch = config.get('vars', 'fake_kvm_architecture') + else: + targetArch = hostArch + caps = {} caps['kvmEnabled'] = \ str(config.getboolean('vars', 'fake_kvm_support') or os.path.exists('/dev/kvm')).lower() - cpuInfo = CpuInfo() + cpuInfo = CpuInfo(hostArch=hostArch) cpuTopology = CpuTopology() if config.getboolean('vars', 'report_host_threads_as_cores'): caps['cpuCores'] = str(cpuTopology.threads()) @@ -268,16 +319,20 @@ caps['cpuSockets'] = str(cpuTopology.sockets()) caps['cpuSpeed'] = cpuInfo.mhz() if config.getboolean('vars', 'fake_kvm_support'): - caps['cpuModel'] = 'Intel(Fake) CPU' - flags = set(cpuInfo.flags() + ['vmx', 'sse2', 'nx']) - caps['cpuFlags'] = ','.join(flags) + 'model_486,model_pentium,' \ - 'model_pentium2,model_pentium3,model_pentiumpro,model_qemu32,' \ - 'model_coreduo,model_core2duo,model_n270,model_Conroe,' \ - 'model_Penryn,model_Nehalem,model_Opteron_G1' + if config.get('vars', 'fake_kvm_architecture') == 'x86_64': + caps['cpuModel'] = 'Intel(Fake) CPU' + flags = set(cpuInfo.flags() + ['vmx', 'sse2', 'nx']) + caps['cpuFlags'] = ','.join(flags) + 'model_486,model_pentium,' \ + 'model_pentium2,model_pentium3,model_pentiumpro,' \ + 'model_qemu32,model_coreduo,model_core2duo,model_n270,' \ + 'model_Conroe,model_Penryn,model_Nehalem,model_Opteron_G1' + elif config.get('vars', 'fake_kvm_architecture') == 'ppc64': + caps['cpuModel'] = 'POWER 7 (fake)' + caps['cpuFlags'] = 'powernv,model_POWER7' else: caps['cpuModel'] = cpuInfo.model() caps['cpuFlags'] = ','.join(cpuInfo.flags() + - _getCompatibleCpuModels()) + _getCompatibleCpuModels(hostArch)) caps.update(dsaversion.version_info) caps.update(netinfo.get()) @@ -290,7 +345,7 @@ caps['operatingSystem'] = osversion() caps['uuid'] = utils.getHostUUID() caps['packages2'] = _getKeyPackages() - caps['emulatedMachines'] = _getEmulatedMachines() + caps['emulatedMachines'] = _getEmulatedMachines(targetArch) caps['ISCSIInitiatorName'] = _getIscsiIniName() caps['HBAInventory'] = storage.hba.HBAInventory() caps['vmTypes'] = ['kvm'] -- To view, visit http://gerrit.ovirt.org/17437 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I42c4d00ace06805edbe765d975b40c9311a1fa9b Gerrit-PatchSet: 1 Gerrit-Project: vdsm Gerrit-Branch: master Gerrit-Owner: Vitor de Lima <[email protected]> _______________________________________________ vdsm-patches mailing list [email protected] https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches
