[Kimchi-devel] [PATCH 3/4] host pci pass through: list all host devices in a tree

Zhou Zheng Sheng zhshzhou at linux.vnet.ibm.com
Wed Apr 23 09:48:11 UTC 2014


The host devices form a tree. If the user decides to pass through an HBA
card to guest, all the related SCSI disks under the HBA card will be
managed by the guest as well. If we can present all host devices in a
tree, the user can conveniently infer the affected sub-devices of a
passed through PCI device.

To get all devices in a tree, GET the following URL:

curl -u root -H "Content-Type: application/json" \
  -H  "Accept: application/json" \
  http://127.0.0.1:8000/host/devices?_tree=1

It would print information like follow.
[
  {
    "hardware":{...},
    "product":"...",
    "name":"computer",
    "parent":null,
    "path":null,
    "firmware":{...},
    "type":"system",
    "children":[
      {
        "slot":"0",
        "function":"0",
        "domain":"0",
        "vendor":{...},
        "name":"pci_0000_00_00_0",
        "parent":"computer",
        "bus":"0",
        "product":{...},
        "path":"/sys/devices/pci0000:00/0000:00:00.0",
        "type":"pci",
        "iommuGroup":"0"
      },
      {
        # Another child device info ...,
        "children":[
          {
            # A grand child device info ...,
          }, ... # Other grand children devices info
        ]
      }, ...
    ]
  }
]

The above tree is not very human friendly. In future we should parse
this tree in front-end and show a nice graphical tree to the user.
For now, you can get a human readable device tree using the following
command (but it's just for debugging purpose).
  PYTHONPATH=src python -m kimchi.hostdev | less

It would print the following.
-----------------
 ~{'firmware': {...},
 ~ 'hardware': {...},
 ~ 'name': 'computer',
 ~ 'parent': None,
 ~ 'path': None,
 ~ 'product': '...',
 ~ 'type': 'system'}
   +-----------------
   | ~{'bus': '0',
   | ~ 'domain': '0',
   | ~ 'function': '0',
   | ~ 'iommuGroup': '0',
   | ~ 'name': 'pci_0000_00_00_0',
   | ~ 'parent': 'computer',
   | ~ 'path': '/sys/devices/pci0000:00/0000:00:00.0',
   | ~ 'product': {'description': '... DRAM Controller',
   | ~             'id': '0x0104'},
   | ~ 'slot': '0',
   | ~ 'type': 'pci',
   | ~ 'vendor': {'id': '0x8086', 'name': 'Intel Corporation'}}
   |
   +-----------------
   | ~{'bus': '0',
   | ~ 'domain': '0',
   | ~ 'function': '0',
   | ~ 'iommuGroup': '1',
   | ~ 'name': 'pci_0000_00_01_0',
   | ~ 'parent': 'computer',
   | ~ 'path': '/sys/devices/pci0000:00/0000:00:01.0',
   | ~ 'product': {...},
   | ~ 'slot': '1',
   | ~ 'type': 'pci',
   | ~ 'vendor': {'id': '0x8086', 'name': 'Intel Corporation'}}
   |   \-----------------
   |     ~{'bus': '1',
   |     ~ 'domain': '0',
   |     ~ 'function': '0',
   |     ~ 'iommuGroup': '1',
   |     ~ 'name': 'pci_0000_01_00_0',
   |     ~ 'parent': 'pci_0000_00_01_0',
   |     ~ 'path': '/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0',
   |     ~ 'product': {'description': 'GF119M ...', 'id': '0x1057'},
   |     ~ 'slot': '0',
   |     ~ 'type': 'pci',
   |     ~ 'vendor': {'id': '0x10de', 'name': 'NVIDIA Corporation'}}
   |
   |
   +-----------------
   | ~{'bus': '0',
   | ~ 'domain': '0',
   ...

Signed-off-by: Zhou Zheng Sheng <zhshzhou at linux.vnet.ibm.com>
---
 docs/API.md                |  7 +++++++
 src/kimchi/control/host.py | 21 +++++++++++++++++++++
 src/kimchi/i18n.py         |  2 ++
 3 files changed, 30 insertions(+)

diff --git a/docs/API.md b/docs/API.md
index 009c58d..d89ca8c 100644
--- a/docs/API.md
+++ b/docs/API.md
@@ -812,6 +812,13 @@ Contains the host sample data.
     * Parameters:
         * _cap: Filter node device list with given node device capability.
                 To list Fibre Channel SCSI Host devices, use "_cap=fc_host".
+        * _tree: To list the devices in a tree, use "_tree=1". The result is
+                 like [root_device], where root_device dictionary contains all
+                 information of the root divice, and a root_device["children"]
+                 item. The root_device["children"] is a list, and the elements
+                 in the list are device dicts containing device information and
+                 "children" lists. If a device is a leaf one, it does not
+                 contain device["children"] item.
 
 ### Resource: Device
 
diff --git a/src/kimchi/control/host.py b/src/kimchi/control/host.py
index 003c4b9..9347932 100644
--- a/src/kimchi/control/host.py
+++ b/src/kimchi/control/host.py
@@ -22,6 +22,7 @@ import cherrypy
 from kimchi.control.base import Collection, Resource, SimpleCollection
 from kimchi.control.utils import UrlSubNode, validate_method
 from kimchi.exception import OperationFailed
+from kimchi import hostdev
 from kimchi.template import render
 
 
@@ -88,6 +89,26 @@ class Devices(Collection):
         super(Devices, self).__init__(model)
         self.resource = Device
 
+    def _get_resources(self, flag_filter):
+        try:
+            _tree = bool(int(flag_filter['_tree']))
+            del flag_filter['_tree']
+        except KeyError:
+            _tree = False
+
+        devices = super(Devices, self)._get_resources(flag_filter)
+
+        if devices and _tree:
+            dev_infos = [device.data for device in devices]
+            root = hostdev.get_devices_tree(dev_infos)
+            if root is None:
+                raise InvalidParameter('KCHTMPL0023E')
+            root_device = Device(self.model, root['name'])
+            root_device.info = root
+            devices = [root_device]
+
+        return devices
+
 
 class Device(Resource):
     def __init__(self, model, id):
diff --git a/src/kimchi/i18n.py b/src/kimchi/i18n.py
index 3d3abb4..955aff2 100644
--- a/src/kimchi/i18n.py
+++ b/src/kimchi/i18n.py
@@ -117,6 +117,8 @@ messages = {
     "KCHTMPL0020E": _("Unable to create template due error: %(err)s"),
     "KCHTMPL0021E": _("Unable to delete template due error: %(err)s"),
     "KCHTMPL0022E": _("Disk size must be greater than 1GB."),
+    "KCHTMPL0023E": _("No root device found. Maybe you should stop filtering "
+                      "devices to avoid filtering out the root device of the device tree."),
 
     "KCHPOOL0001E": _("Storage pool %(name)s already exists"),
     "KCHPOOL0002E": _("Storage pool %(name)s does not exist"),
-- 
1.9.0




More information about the Kimchi-devel mailing list