From 70619d45cc540ae4f46927fc22972060fba43750 Mon Sep 17 00:00:00 2001 From: Luis Fernandez Alvarez Date: Fri, 23 Nov 2012 09:46:52 +0100 Subject: Added cpu_info report to HyperV Compute driver It fixes bug 1082275 The current version of the HyperV Compute driver wasn't returning CPU information when it reported its resources. In order to solve it, this patch extracts the cpu properties from WMI and Win32 calls. Change-Id: I5c2a89b5e432f4e958354a15582258d4cff83658 --- ...estCase.test_get_available_resource_ctypes.p.gz | Bin 0 -> 926 bytes ...est_get_available_resource_multiprocessing.p.gz | Bin 270 -> 270 bytes ...APITestCase.test_get_available_resource_os.p.gz | Bin 423 -> 423 bytes ...estCase.test_get_available_resource_shutil.p.gz | Bin 309 -> 309 bytes ...PITestCase.test_get_available_resource_wmi.p.gz | Bin 980 -> 1276 bytes nova/tests/test_hypervapi.py | 5 +-- nova/virt/hyperv/constants.py | 24 ++++++++++++++ nova/virt/hyperv/hostops.py | 35 +++++++++++++++++++-- 8 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_ctypes.p.gz diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_ctypes.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_ctypes.p.gz new file mode 100644 index 000000000..b363af55a Binary files /dev/null and b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_ctypes.p.gz differ diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_multiprocessing.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_multiprocessing.p.gz index dd8eb1248..92dfc0823 100644 Binary files a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_multiprocessing.p.gz and b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_multiprocessing.p.gz differ diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_os.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_os.p.gz index 27611287c..e2ccdc024 100644 Binary files a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_os.p.gz and b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_os.p.gz differ diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_shutil.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_shutil.p.gz index 47e882ab0..8a4186b2f 100644 Binary files a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_shutil.p.gz and b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_shutil.p.gz differ diff --git a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_wmi.p.gz b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_wmi.p.gz index 3b91f7e0a..3747f8f03 100644 Binary files a/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_wmi.p.gz and b/nova/tests/hyperv/stubs/test_hypervapi.HyperVAPITestCase.test_get_available_resource_wmi.p.gz differ diff --git a/nova/tests/test_hypervapi.py b/nova/tests/test_hypervapi.py index 36f153531..c3091e1b7 100644 --- a/nova/tests/test_hypervapi.py +++ b/nova/tests/test_hypervapi.py @@ -76,7 +76,7 @@ class HyperVAPITestCase(basetestcase.BaseTestCase): fake_image.stub_out_image_service(self.stubs) fake_network.stub_out_nw_api_get_instance_nw_info(self.stubs) - def fake_dumps(msg): + def fake_dumps(msg, default=None, **kwargs): return '""' self.stubs.Set(json, 'dumps', fake_dumps) @@ -108,7 +108,8 @@ class HyperVAPITestCase(basetestcase.BaseTestCase): 'multiprocessing', '_winreg', 'nova.virt.configdrive', - 'nova.utils' + 'nova.utils', + 'ctypes' ] # Modules in which the mocks are going to be injected diff --git a/nova/virt/hyperv/constants.py b/nova/virt/hyperv/constants.py index 29a98d345..4be569e88 100644 --- a/nova/virt/hyperv/constants.py +++ b/nova/virt/hyperv/constants.py @@ -44,6 +44,30 @@ REQ_POWER_STATE = { 'Suspended': HYPERV_VM_STATE_SUSPENDED, } +WMI_WIN32_PROCESSOR_ARCHITECTURE = { + 0: 'x86', + 1: 'MIPS', + 2: 'Alpha', + 3: 'PowerPC', + 5: 'ARM', + 6: 'Itanium-based systems', + 9: 'x64', +} + +PROCESSOR_FEATURE = { + 7: '3dnow', + 3: 'mmx', + 12: 'nx', + 9: 'pae', + 8: 'rdtsc', + 20: 'slat', + 13: 'sse3', + 21: 'vmx', + 6: 'sse', + 10: 'sse2', + 17: 'xsave', +} + WMI_JOB_STATUS_STARTED = 4096 WMI_JOB_STATE_RUNNING = 4 WMI_JOB_STATE_COMPLETED = 7 diff --git a/nova/virt/hyperv/hostops.py b/nova/virt/hyperv/hostops.py index c07388c35..8c501ab30 100644 --- a/nova/virt/hyperv/hostops.py +++ b/nova/virt/hyperv/hostops.py @@ -18,13 +18,16 @@ """ Management class for host operations. """ +import ctypes import multiprocessing import os import platform from nova.openstack.common import cfg +from nova.openstack.common import jsonutils from nova.openstack.common import log as logging from nova.virt.hyperv import baseops +from nova.virt.hyperv import constants CONF = cfg.CONF LOG = logging.getLogger(__name__) @@ -35,6 +38,35 @@ class HostOps(baseops.BaseOps): super(HostOps, self).__init__() self._stats = None + def _get_cpu_info(self): + """ Get the CPU information. + :returns: A dictionary containing the main properties + of the central processor in the hypervisor. + """ + cpu_info = dict() + processor = self._conn_cimv2.query( + "SELECT * FROM Win32_Processor WHERE ProcessorType = 3") + + cpu_info['arch'] = constants.WMI_WIN32_PROCESSOR_ARCHITECTURE\ + .get(processor[0].Architecture, 'Unknown') + cpu_info['model'] = processor[0].Name + cpu_info['vendor'] = processor[0].Manufacturer + + topology = dict() + topology['sockets'] = len(processor) + topology['cores'] = processor[0].NumberOfCores + topology['threads'] = processor[0].NumberOfLogicalProcessors\ + / processor[0].NumberOfCores + cpu_info['topology'] = topology + + features = list() + for fkey, fname in constants.PROCESSOR_FEATURE.items(): + if ctypes.windll.kernel32.IsProcessorFeaturePresent(fkey): + features.append(fname) + cpu_info['features'] = features + + return jsonutils.dumps(cpu_info) + def _get_vcpu_total(self): """Get vcpu number of physical computer. :returns: the number of cpu core. @@ -114,7 +146,6 @@ class HostOps(baseops.BaseOps): LOG.info(_('get_available_resource called')) local_gb, used_gb = self._get_local_hdd_info_gb() - # TODO(alexpilotti) implemented cpu_info dic = {'vcpus': self._get_vcpu_total(), 'memory_mb': self._get_memory_mb_total(), 'local_gb': local_gb, @@ -124,7 +155,7 @@ class HostOps(baseops.BaseOps): 'hypervisor_type': "hyperv", 'hypervisor_version': self._get_hypervisor_version(), 'hypervisor_hostname': platform.node(), - 'cpu_info': 'unknown'} + 'cpu_info': self._get_cpu_info()} return dic -- cgit