"""
LsPci - Commands ``lspci``
==========================
This combiner combines the following Parsers to a list.
- LsPci - the output of command ``lspci -k``
- LsPciVmmkn - the output of command ``lspci -vmmkn``
"""
from insights import combiner
from insights.parsers import keyword_search
from insights.parsers.lspci import LsPci, LsPciVmmkn
[docs]
@combiner([LsPci, LsPciVmmkn])
class LsPci(list):
"""
Combines the Parser LsPci of ``/sbin/lspci -k`` command and Parser
LsPciVmmkn of ``/sbin/lspci -vmmkn`` command.
.. note::
In case the ``lspci -k`` sometimes outputs the `Slot` in the full
format of ``domain:bus:device.function``, and the ``lspci -k`` is more
common than ``lspci -vmmkn``, so this combiner will take the `Slot` of
the `lspci -k` as the key.
Typical output of the ``lspci -k`` command is::
00:00.0 Host bridge: Intel Corporation Haswell-ULT DRAM Controller (rev 09)
Subsystem: Lenovo ThinkPad X240
Kernel driver in use: hsw_uncore
00:02.0 VGA compatible controller: Intel Corporation Haswell-ULT Integrated Graphics Controller (rev 09)
Subsystem: Lenovo ThinkPad X240
Kernel driver in use: i915
Kernel modules: i915
00:03.0 Audio device: Intel Corporation Haswell-ULT HD Audio Controller (rev 09)
Subsystem: Lenovo ThinkPad X240
Kernel driver in use: snd_hda_intel
Kernel modules: snd_hda_intel
00:16.0 Communication controller: Intel Corporation 8 Series HECI #0 (rev 04)
Subsystem: Lenovo ThinkPad X240
Kernel driver in use: mei_me
Kernel modules: mei_me
00:19.0 Ethernet controller: Intel Corporation Ethernet Connection I218-LM (rev 04)
Subsystem: Lenovo ThinkPad X240
Kernel driver in use: e1000e
Kernel modules: e1000e
00:1b.0 Audio device: Intel Corporation 8 Series HD Audio Controller (rev 04)
Subsystem: Lenovo ThinkPad X240
Kernel driver in use: snd_hda_intel
Kernel modules: snd_hda_intel
Typical output of the ``lspci -vmmkn`` command is::
Slot: 00:00.0
Class: 0600
Vendor: 8086
Device: 0a04
SVendor: 17aa
SDevice: 2214
Rev: 09
Driver: hsw_uncore
Slot: 00:02.0
Class: 0300
Vendor: 8086
Device: 0a16
SVendor: 17aa
SDevice: 2214
Rev: 09
Driver: i915
Module: i915
Slot: 00:03.0
Class: 0403
Vendor: 8086
Device: 0a0c
SVendor: 17aa
SDevice: 2214
Rev: 09
Driver: snd_hda_intel
Module: snd_hda_intel
Slot: 00:16.0
Class: 0780
Vendor: 8086
Device: 9c3a
SVendor: 17aa
SDevice: 2214
Rev: 04
Driver: mei_me
Module: mei_me
Slot: 00:19.0
Class: 0200
Vendor: 8086
Device: 155a
SVendor: 17aa
SDevice: 2214
Rev: 04
Driver: e1000e
Module: e1000e
Slot: 00:1b.0
Class: 0403
Vendor: 8086
Device: 9c20
SVendor: 17aa
SDevice: 2214
Rev: 04
Driver: snd_hda_intel
Module: snd_hda_intel
Examples:
>>> type(lspci)
<class 'insights.combiners.lspci.LsPci'>
>>> sorted(lspci.pci_dev_list)
['00:00.0', '00:02.0', '00:03.0', '00:16.0', '00:19.0', '00:1b.0']
>>> lspci.search(Dev_Details__contains='I218')[0]['Slot']
'00:19.0'
"""
def __init__(self, lspci_k, lspci_vmmkn):
if lspci_vmmkn:
for dev in lspci_vmmkn:
# use the local copy to prevent from writing back to the parser
dev_t = dev.copy()
if lspci_k and (dev['Slot'] in lspci_k.data or '0000:' + dev['Slot'] in lspci_k.data):
# use the local copy to prevent from writing back to the parser
dev_k = [v for v in lspci_k.data.values() if v['Slot'].endswith(dev['Slot'])][0].copy()
# Since the 'lspci -k' is a more common command than the
# 'lspci -vmmkn', the following line should be commented
# out to use the 'Slot' in 'lspci -k' as the 'Slot' in
# this combiner:
# dev_k.pop('Slot') if 'Slot' in dev_k else None
dev_k.pop('Kernel driver in use') if 'Kernel driver in use' in dev_k else None
dev_k.pop('Kernel modules') if 'Kernel modules' in dev_k else None
dev_t.update(dev_k)
self.append(dev_t)
self._pci_dev_list = (lspci_k if lspci_k else lspci_vmmkn).pci_dev_list
else:
for dev in lspci_k.data.values():
# use the local copy to prevent from writing back to the parser
dev = dev.copy()
dev.update(Driver=dev.pop('Kernel driver in use')) if 'Kernel driver in use' in dev else None
dev.update(Module=[i.strip() for i in dev.pop('Kernel modules').split(',')]) if 'Kernel modules' in dev else None
self.append(dev)
self._pci_dev_list = lspci_k.pci_dev_list
@property
def pci_dev_list(self):
"""
The list of PCI devices.
"""
return self._pci_dev_list
[docs]
def search(self, **kwargs):
"""
Get the details of PCI devices by searching the table with kwargs.
This uses the :py:func:`insights.parsers.keyword_search` function for
searching; see its documentation for usage details. If no search
parameters are given, no rows are returned.
It simplify the value of the column according to actual usage.
Returns:
list: A list of dictionaries of PCI devices that match the given
search criteria.
Examples:
>>> len(lspci.search(Subsystem__startswith='Lenovo'))
6
>>> len(lspci.search(Subsystem__startswith='Lenovo', Dev_Details__startswith='Audio device'))
2
>>> lspci.search(Driver='snd_hda_intel', Dev_Details__contains='8') == [
... {'Slot': '00:1b.0', 'Class': '0403', 'Vendor': '8086',
... 'Device': '9c20', 'SVendor': '17aa', 'SDevice': '2214',
... 'Rev': '04', 'Driver': 'snd_hda_intel',
... 'Module': ['snd_hda_intel'], 'Subsystem': 'Lenovo ThinkPad X240',
... 'Dev_Details': 'Audio device: Intel Corporation 8 Series HD Audio Controller (rev 04)'}]
True
"""
return keyword_search(self, row_keys_change=True, **kwargs)