diff --git a/lib/ansible/module_utils/facts.py b/lib/ansible/module_utils/facts.py index 7a73a32ffbe..a3442d20bb1 100644 --- a/lib/ansible/module_utils/facts.py +++ b/lib/ansible/module_utils/facts.py @@ -46,7 +46,7 @@ except ImportError: import simplejson as json # -------------------------------------------------------------- -# timeout function to make sure some fact gathering +# timeout function to make sure some fact gathering # steps do not exceed a time limit class TimeoutError(Exception): @@ -603,23 +603,38 @@ class LinuxHardware(Hardware): def get_cpu_facts(self): i = 0 + vendor_id_occurrence = 0 + model_name_occurrence = 0 physid = 0 coreid = 0 sockets = {} cores = {} + xen_paravirt = False if not os.access("/proc/cpuinfo", os.R_OK): return self.facts['processor'] = [] for line in open("/proc/cpuinfo").readlines(): data = line.split(":", 1) key = data[0].strip() + # model name is for Intel arch, Processor (mind the uppercase P) # works for some ARM devices, like the Sheevaplug. if key == 'model name' or key == 'Processor' or key == 'vendor_id': if 'processor' not in self.facts: self.facts['processor'] = [] self.facts['processor'].append(data[1].strip()) + if key == 'vendor_id': + vendor_id_occurrence += 1 + if key == 'model name': + model_name_occurrence += 1 i += 1 + elif key == 'flags': + # Check for vme cpu flag, Xen paravirt does not expose this. + # Need to detect Xen paravirt because it exposes cpuinfo + # differently than Xen HVM or KVM and causes reporting of + # only a single cpu core. + if 'vme' not in data: + xen_paravirt = True elif key == 'physical id': physid = data[1].strip() if physid not in sockets: @@ -634,13 +649,23 @@ class LinuxHardware(Hardware): cores[coreid] = int(data[1].strip()) elif key == '# processors': self.facts['processor_cores'] = int(data[1].strip()) + + if vendor_id_occurrence == model_name_occurrence: + i = vendor_id_occurrence + if self.facts['architecture'] != 's390x': - self.facts['processor_count'] = sockets and len(sockets) or i - self.facts['processor_cores'] = sockets.values() and sockets.values()[0] or 1 - self.facts['processor_threads_per_core'] = ((cores.values() and - cores.values()[0] or 1) / self.facts['processor_cores']) - self.facts['processor_vcpus'] = (self.facts['processor_threads_per_core'] * - self.facts['processor_count'] * self.facts['processor_cores']) + if xen_paravirt: + self.facts['processor_count'] = i + self.facts['processor_cores'] = i + self.facts['processor_threads_per_core'] = 1 + self.facts['processor_vcpus'] = i + else: + self.facts['processor_count'] = sockets and len(sockets) or i + self.facts['processor_cores'] = sockets.values() and sockets.values()[0] or 1 + self.facts['processor_threads_per_core'] = ((cores.values() and + cores.values()[0] or 1) / self.facts['processor_cores']) + self.facts['processor_vcpus'] = (self.facts['processor_threads_per_core'] * + self.facts['processor_count'] * self.facts['processor_cores']) def get_dmi_facts(self): ''' learn dmi facts from system