[node-patches] Change in ovirt-node[master]: system: Make CPU feature detection independent

fabiand at redhat.com fabiand at redhat.com
Fri Jul 11 10:17:58 UTC 2014


Fabian Deutsch has uploaded a new change for review.

Change subject: system: Make CPU feature detection independent
......................................................................

system: Make CPU feature detection independent

Previously the CPU feature detection relied on libvirt. This lead to two
kind of problems:
1. libvirt is only providing names fo rthe closest known/baseline CPUs
2. the old logic failed in cases where libvirtd wasn't available

Change-Id: Ie321d633508239f70e4e59bcc94ba2e16a436449
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=1096163
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=1065831
Signed-off-by: Fabian Deutsch <fabiand at fedoraproject.org>
---
M src/ovirt/node/setup/core/status_page.py
M src/ovirt/node/utils/system.py
M src/ovirt/node/utils/virt.py
M src/ovirtnode/ovirtfunctions.py
4 files changed, 82 insertions(+), 121 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-node refs/changes/35/29935/1

diff --git a/src/ovirt/node/setup/core/status_page.py b/src/ovirt/node/setup/core/status_page.py
index 5b07dac..1627e11 100644
--- a/src/ovirt/node/setup/core/status_page.py
+++ b/src/ovirt/node/setup/core/status_page.py
@@ -263,7 +263,8 @@
     """The dialog beeing displayed when th euser clicks CPU Details
     """
     def __init__(self, path, title):
-        msg = utils.system.cpu_details()
+        msg = "\n%s\n\n%s" % (utils.system.cpu_details(),
+                              utils.virt.hardware_status())
         super(CPUFeaturesDialog, self).__init__(path, title, msg)
 
 
diff --git a/src/ovirt/node/utils/system.py b/src/ovirt/node/utils/system.py
index 5e0b388..53cbd0e 100644
--- a/src/ovirt/node/utils/system.py
+++ b/src/ovirt/node/utils/system.py
@@ -115,11 +115,64 @@
                in ["rescue", "S", "single", "1"])
 
 
-def cpu_details():
-    """Return details for the CPU of this machine, virt related
+def _parse_lscpu(data):
+    """Parse the lines of the lscpu output
+
+    >>> data = \"\"\"
+    ... Architecture:          x86_64
+    ... CPU op-mode(s):        32-bit, 64-bit
+    ... Byte Order:            Little Endian
+    ... CPU(s):                4
+    ... On-line CPU(s) list:   0-3
+    ... Thread(s) per core:    2
+    ... Core(s) per socket:    2
+    ... Socket(s):             1
+    ... NUMA node(s):          1
+    ... Vendor ID:             GenuineIntel
+    ... CPU family:            6
+    ... Model:                 42
+    ... Model name:            Intel(R) Core(TM) i7-2620M CPU @ 2.70GHz
+    ... Stepping:              7
+    ... CPU MHz:               1094.976
+    ... BogoMIPS:              5382.47
+    ... Virtualization:        VT-x
+    ... L1d cache:             32K
+    ... L1i cache:             32K
+    ... L2 cache:              256K
+    ... L3 cache:              4096K
+    ... NUMA node0 CPU(s):     0-3
+    ... \"\"\"
+    >>> _parse_lscpu(data)
+    {'CPU(s)': '4', 'L1d cache': '32K', 'CPU op-mode(s)': '32-bit, 64-bit', \
+'NUMA node0 CPU(s)': '0-3', 'L2 cache': '256K', 'L1i cache': '32K', \
+'Model name': 'Intel(R) Core(TM) i7-2620M CPU @ 2.70GHz', 'CPU MHz': \
+'1094.976', 'Core(s) per socket': '2', 'Thread(s) per core': '2', \
+'On-line CPU(s) list': '0-3', 'Socket(s)': '1', 'Architecture': 'x86_64', \
+'Model': '42', 'Vendor ID': 'GenuineIntel', 'CPU family': '6', 'L3 cache': \
+'4096K', 'BogoMIPS': '5382.47', 'Virtualization': 'VT-x', 'Stepping': '7', \
+'Byte Order': 'Little Endian', 'NUMA node(s)': '1'}
     """
-    from ovirtnode.ovirtfunctions import cpu_details
-    return cpu_details()
+    cpu = {}
+    for line in data.splitlines():
+        if not line.strip():
+            continue
+        k, v = line.split(":", 1)
+        cpu[k.strip()] = v.strip()
+    return cpu
+
+
+def cpu_details():
+    """Return details for the CPU of this machine
+    """
+    fields = ["Model name", "Architecture", "CPU MHz", "Virtualization",
+              "CPU(s)", "Socket(s)",
+              "Core(s) per socket", "Thread(s) per core"]
+
+    data = process.pipe(["lscpu"])
+    cpu = _parse_lscpu(data)
+    cpu_details = ("%s: %s" % (f, cpu.get(f, "(Unknown)")) for f in fields)
+
+    return "\n".join(cpu_details)
 
 
 def has_hostvg():
diff --git a/src/ovirt/node/utils/virt.py b/src/ovirt/node/utils/virt.py
index 5a4b951..cd40171 100644
--- a/src/ovirt/node/utils/virt.py
+++ b/src/ovirt/node/utils/virt.py
@@ -77,12 +77,24 @@
         read-able string
     """
     if hardware_is_enabled():
-        return "Virtualization hardware was detected and is enabled"
+        msg = "Virtualization hardware was detected and is enabled"
     if hardware_is_available():
-        return "Virtualization hardware was detected but is disabled"
-    return "No virtualization hardware was detected on this system"
+        msg = "Virtualization hardware was detected but is disabled"
+    msg = "No virtualization hardware was detected on this system"
+    if not is_libvirtd_reachable():
+        msg += "\n(Failed to Establish Libvirt Connection)"
+    return msg
 
 
+def is_libvirtd_reachable():
+    reachable = True
+    try:
+        with LibvirtConnection() as l:
+            l.getCapabilities()
+    except:
+        reachable = False
+    return reachable
+
 def number_of_domains():
     # FIXME solve this more general
     num_domains = None
diff --git a/src/ovirtnode/ovirtfunctions.py b/src/ovirtnode/ovirtfunctions.py
index dcc19fa..cfe78ba 100644
--- a/src/ovirtnode/ovirtfunctions.py
+++ b/src/ovirtnode/ovirtfunctions.py
@@ -1574,126 +1574,21 @@
     size = int(size) * multiplier
     return str(size)
 
-def get_cpu_flags():
-    cpuflags_cmd = "cat /proc/cpuinfo |grep ^flags|tail -n 1"
-    cpuflags_lookup = subprocess_closefds(cpuflags_cmd, shell=True, stdout=PIPE, stderr=STDOUT)
-    output, err = cpuflags_lookup.communicate()
-    return output.strip()
-
 def kvm_enabled():
-    try:
-        conn = libvirt.openReadOnly(None)
-        libvirt_capabilities = conn.getCapabilities()
-    except:
-        return 0
-    # Look for a KVM mdomain
-    if re.search("domain type=.kvm", libvirt_capabilities):
-        return 1
-    else:
-        return 2
+    import ovirt.node.utils.virt as v
+    return v.hardware_is_enabled()
 
 def virt_cpu_flags_enabled():
-    cpuflags = get_cpu_flags()
-    if "vmx" in cpuflags or "svm" in cpuflags:
-        return True
-    else:
-        return False
+    import ovirt.node.utils.virt as v
+    return v.hardware_is_available()
 
 def get_virt_hw_status():
-    hwvirt_msg = ""
-    kvm_status = kvm_enabled()
-    if kvm_status == 0:
-        return "(Failed to Establish Libvirt Connection)"
-    elif kvm_status == 1:
-        logger.info("Hardware virtualization detected")
-    elif kvm_status == 2:
-        hwvirt_msg = "Virtualization hardware is unavailable."
-        if virt_cpu_flags_enabled():
-            hwvirt_msg = "(Virtualization hardware detected but disabled)"
-        else:
-            hwvirt_msg = "(Virtualization hardware was not detected)"
-    return hwvirt_msg
-
+    import ovirt.node.utils.virt as v
+    return v.hardware_status()
 
 def cpu_details():
-    status_msg = ""
-    cpu_info_cmd = "cat /proc/cpuinfo"
-    cpu_info = subprocess.Popen(cpu_info_cmd, shell=True, stdout=PIPE, stderr=STDOUT)
-    cpu_info = cpu_info.stdout.read().strip()
-    cpu_dict = {}
-    for line in cpu_info.splitlines():
-        try:
-            key, value = line.split(":")
-            cpu_dict[key.replace("\t","")] = value
-        except:
-            pass
-    # get capabilities from libvirt
-    try:
-        conn = libvirt.openReadOnly(None)
-        libvirt_capabilities = conn.getCapabilities()
-    except:
-        return "(Failed to Establish Libvirt Connection)"
-    dom = parseString(libvirt_capabilities)
-    # get cpu section
-    cpu = parseString(dom.getElementsByTagName('cpu')[0].toxml())
-    try:
-        vendorTag = cpu.getElementsByTagName('vendor')[0].toxml()
-        cpu_vendor = vendorTag.replace('<vendor>','').replace('</vendor>','')
-    except:
-        cpu_vendor = "Unknown Vendor"
-    try:
-        modelTag = cpu.getElementsByTagName('model')[0].toxml()
-        cpu_model = modelTag.replace('<model>','').replace('</model>','')
-    except:
-        if cpu_vendor == "Unknown Vendor":
-            cpu_model = ""
-        else:
-            cpu_model = "Unknown Model"
-    try:
-        host = dom.getElementsByTagName('host')[0]
-        cells = host.getElementsByTagName('cells')[0]
-        total_cpus = cells.getElementsByTagName('cpu').length
-
-        socketIds = []
-        siblingsIds = []
-
-        socketIds = [proc.getAttribute('socket_id')
-                     for proc in cells.getElementsByTagName('cpu')
-                     if proc.getAttribute('socket_id') not in socketIds]
-
-        siblingsIds = [proc.getAttribute('siblings')
-                       for proc in cells.getElementsByTagName('cpu')
-                       if proc.getAttribute('siblings') not in siblingsIds]
-        cpu_topology = "OK"
-    except:
-        cpu_topology = "Unknown"
-    status_msg += "CPU Name: %s\n" % cpu_dict["model name"].replace("  "," ")
-    status_msg += "CPU Type: %s %s\n" % (cpu_vendor, cpu_model)
-    if kvm_enabled() == 1 and virt_cpu_flags_enabled():
-        status_msg += "Virtualization Extensions Enabled: Yes\n"
-    else:
-        status_msg += "Virtualization Extensions Enabled: \n%s\n" \
-            % get_virt_hw_status()
-    if cpu_vendor == "Intel":
-        if "nx" in cpu_dict["flags"]:
-            status_msg += "NX Flag: Yes\n"
-        else:
-            status_msg += "NX Flag: No\n"
-    elif cpu_vendor == "AMD":
-        if "evp" in cpu_dict["flags"]:
-            status_msg += "EVP Flag: Yes\n"
-        else:
-            status_msg += "EVP Flag: No\n"
-    if cpu_topology == "Unknown":
-        status_msg += "Unable to determine CPU Topology"
-    else:
-        cpu_sockets = len(set(socketIds))
-        status_msg += "CPU Sockets: %s\n" % cpu_sockets
-        cpu_cores = len(set(siblingsIds))
-        status_msg += "CPU Cores: %s\n" % cpu_cores
-        cpu_threads = total_cpus
-        status_msg += "CPU Threads: %s\n" % cpu_threads
-    return status_msg
+    import ovirt.node.utils.system as s
+    return s.cpu_details()
 
 def get_ssh_hostkey(variant="rsa"):
     fn_hostkey = "/etc/ssh/ssh_host_%s_key.pub" % variant


-- 
To view, visit http://gerrit.ovirt.org/29935
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie321d633508239f70e4e59bcc94ba2e16a436449
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-node
Gerrit-Branch: master
Gerrit-Owner: Fabian Deutsch <fabiand at redhat.com>



More information about the node-patches mailing list