Vinzenz Feenstra has uploaded a new change for review.

Change subject: Implementation for CPU topology reporting
......................................................................

Implementation for CPU topology reporting

This patch implements reporting of the guests CPU topology
on Linux guests.

The following fields are reported:

 threads:  uint  number of online threads,
 cores:    uint  number of online cores,
 sockets:  uint  number of online sockets,
 online:   str   Range of online CPUs,
 offline:  str   Range of offline CPUs,
 present:  str   Range of CPUs that have been identified as
                 being present in the system,
 possible: str   Range of CPUs that have been allocated resources
                 and can be brought online if they are present

The guest agent will send the 'cpu-topology' when receiving a message
'cpu-topology' from the hypervisor and on 'refresh' when the hypervisor
reports apiVersion >= 1

Change-Id: If937fd33d2efa11425c814188df2087a85af8357
Api-Version: 1
Signed-off-by: Vinzenz Feenstra <[email protected]>
---
M ovirt-guest-agent/GuestAgentLinux2.py
M ovirt-guest-agent/OVirtAgentLogic.py
A ovirt-guest-agent/topology.py
3 files changed, 132 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-guest-agent 
refs/changes/68/23268/1

diff --git a/ovirt-guest-agent/GuestAgentLinux2.py 
b/ovirt-guest-agent/GuestAgentLinux2.py
index dec6676..5f5f7c4 100644
--- a/ovirt-guest-agent/GuestAgentLinux2.py
+++ b/ovirt-guest-agent/GuestAgentLinux2.py
@@ -22,6 +22,7 @@
 import subprocess
 import threading
 import time
+from topology import read_topology
 from OVirtAgentLogic import AgentLogicBase, DataRetriverBase
 
 CredServer = None
@@ -204,6 +205,9 @@
         self._init_vmstat()
         DataRetriverBase.__init__(self)
 
+    def getCPUTopology(self):
+        return read_topology()
+
     def getMachineName(self):
         return socket.getfqdn()
 
diff --git a/ovirt-guest-agent/OVirtAgentLogic.py 
b/ovirt-guest-agent/OVirtAgentLogic.py
index 786beb8..5c45cf1 100644
--- a/ovirt-guest-agent/OVirtAgentLogic.py
+++ b/ovirt-guest-agent/OVirtAgentLogic.py
@@ -81,6 +81,9 @@
         except Exception:
             logging.exception("onAPIVersionUpdated failed")
 
+    def getCPUTopology(self):
+        pass
+
     def getMachineName(self):
         pass
 
@@ -150,6 +153,7 @@
         self.sendUserInfo()
         self.sendAppList()
         self.sendFQDN()
+        self.sendCPUTopology()
         counter = 0
         hbsecs = self.heartBitRate
         appsecs = self.appRefreshRate
@@ -249,6 +253,14 @@
                 logging.info('API versioning not supported by VDSM. Disabling '
                              'versioning support.')
                 self.dr.setAPIVersion(0)
+            else:
+                apiVersion = 0
+                try:
+                    apiVersion = int(args['apiVersion'])
+                except ValueError:
+                    pass
+                if apiVersion >= 1:
+                    self.sendCPUTopology()
             self.sendUserInfo(True)
             self.sendAppList()
             self.sendInfo()
@@ -260,6 +272,8 @@
         elif command == 'hibernate':
             state = args.get('state', 'disk')
             self.commandHandler.hibernate(state)
+        elif command == 'cpu-topology':
+            self.sendCPUTopology()
         else:
             logging.error("Unknown external command: %s (%s)"
                           % (command, args))
@@ -267,6 +281,11 @@
     def sendFQDN(self):
         self.vio.write('fqdn', {'fqdn': self.dr.getFQDN()})
 
+    def sendCPUTopology(self):
+        topology = self.dr.getCPUTopology()
+        if topology:
+            self.vio.write('cpu-topology', topology)
+
     def sendUsedAPIVersion(self):
         logging.debug("Sending API version %d", self.dr.getAPIVersion())
         self.vio.write('api-version', {'apiVersion': self.dr.getAPIVersion()})
diff --git a/ovirt-guest-agent/topology.py b/ovirt-guest-agent/topology.py
new file mode 100644
index 0000000..23b10a3
--- /dev/null
+++ b/ovirt-guest-agent/topology.py
@@ -0,0 +1,109 @@
+#
+# Copyright (C) 2014 Vinzenz Feenstra, Red Hat Inc. and/or its affiliates.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Refer to the README and COPYING files for full details of the license.
+#
+import os.path
+
+
+def _file(*args):
+    return os.path.join('/sys/devices/system/cpu', *args)
+
+
+def _range_to_list(data):
+    result = []
+    for part in data.split(','):
+        parts = part.split('-')
+        assert(0 < len(parts) <= 2)
+        parts = [int(p) for p in parts]
+        if len(parts) == 2:
+            result.extend([i for i in range(parts[0], parts[1] + 1)])
+        else:
+            result.append(int(parts[0]))
+    return result
+
+
+def _read_file(*parts):
+    f = open(_file(*parts), 'r')
+    result = f.read().replace('\n', '')
+    f.close()
+    return result
+
+
+def _read_range_file_to_list(file):
+    return _range_to_list(_read_file(file))
+
+
+def _read_topology_file(id, file):
+    return _read_file('cpu%d' % id, 'topology', file)
+
+
+def _present_range():
+    return _read_file('present')
+
+
+def _possible_range():
+    return _read_file('possible')
+
+
+def _offline_range():
+    return _read_file('offline')
+
+
+def _online_range():
+    return _read_file('online')
+
+
+def _online_list():
+    return _read_range_file_to_list('online')
+
+
+def read_topology(detailed=False):
+    cores = set()
+    sockets = set()
+
+    details = []
+    for id in _online_list():
+        thread = _read_topology_file(id, 'thread_siblings_list')
+        socket = _read_topology_file(id, 'physical_package_id')
+        if not thread in cores:
+            cores.add(thread)
+        if not socket in sockets:
+            sockets.add(socket)
+        details.append({
+            'id': id,
+            'thread': thread,
+            'socket': socket})
+
+    result = {
+        'threads': len(details),
+        'sockets': len(sockets),
+        'cores': len(cores),
+        'online': _online_range(),
+        'offline': _offline_range(),
+        'possible': _possible_range(),
+        'present': _present_range()}
+
+    if detailed:
+        result['details'] = details
+    return result
+
+
+if __name__ == '__main__':
+    from pprint import pprint
+    print 'Topology:'
+    pprint(read_topology())
+    print 'Topology detailed:'
+    pprint(read_topology(detailed=True))


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

Gerrit-MessageType: newchange
Gerrit-Change-Id: If937fd33d2efa11425c814188df2087a85af8357
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-guest-agent
Gerrit-Branch: master
Gerrit-Owner: Vinzenz Feenstra <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to