Package up2date_client :: Module hardware_gudev
[hide private]
[frames] | no frames]

Source Code for Module up2date_client.hardware_gudev

  1  # Copyright (c) 2010--2016 Red Hat, Inc. 
  2  # 
  3  # This software is licensed to you under the GNU General Public License, 
  4  # version 2 (GPLv2). There is NO WARRANTY for this software, express or 
  5  # implied, including the implied warranties of MERCHANTABILITY or FITNESS 
  6  # FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 
  7  # along with this software; if not, see 
  8  # http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. 
  9  # 
 10  # Red Hat trademarks are not licensed under GPLv2. No permission is 
 11  # granted to use or replicate Red Hat trademarks that are incorporated 
 12  # in this software or its documentation. 
 13  # 
 14   
 15  try: 
 16      import gi 
 17      gi.require_version('GUdev', '1.0') 
 18      from gi.repository import GUdev 
 19      gi_gudev = True 
 20  except ImportError: 
 21      import gudev 
 22      import glib 
 23      gi_gudev = False 
 24   
 25  import os 
 26  import re 
 27   
 28  from hwdata import PCI, USB 
 29   
30 -def get_devices():
31 """ Returns list of dictionaries with keys for every device in system 32 (values are provide as example): 33 'bus' : 'pci' 34 'driver' : 'pcieport-driver' 35 'pciType' : '1' 36 'detached' : '0' 37 'class' : 'OTHER' 38 'desc' : 'Intel Corporation|5000 Series Chipset PCI Express x4 Port 2' 39 """ 40 # listen to uevents on all subsystems 41 if gi_gudev: 42 client = GUdev.Client() 43 else: 44 client = gudev.Client([""]) 45 # FIX ME - change to None to list all devices once it is fixed in gudev 46 devices = client.query_by_subsystem("pci") + client.query_by_subsystem("usb") + client.query_by_subsystem("block") + client.query_by_subsystem("ccw") + client.query_by_subsystem("scsi") 47 result = [] 48 for device in devices: 49 subsystem = device.get_subsystem() 50 result_item = { 51 'bus': subsystem, 52 'driver': device.get_driver(), 53 'pciType': _clasify_pci_type(subsystem), 54 'detached': '0', # always zero? 55 'class': _clasify_class(device), 56 'desc': _get_device_desc(device), 57 } 58 if result_item['class'] is None: 59 result_item['class'] = 'OTHER' 60 if result_item['driver'] is None: 61 result_item['driver'] = 'unknown' 62 if subsystem == 'block': 63 if device.has_property('ID_BUS'): 64 result_item['bus'] = device.get_property('ID_BUS') 65 result_item['device'] = device.get_name() 66 if device.get_devtype() == 'partition': 67 # do not report partitions, just whole disks 68 continue 69 if device.get_property('DM_NAME'): 70 # LVM device 71 continue 72 if device.get_property('MAJOR') == '1': 73 # ram device 74 continue 75 if device.get_property('MAJOR') == '7': 76 # character devices for virtual console terminals 77 continue 78 # This is interpreted as Physical. But what to do with it? 79 # result_item['prop1'] = '' 80 # This is interpreted as Logical. But what to do with it? 81 # result_item['prop2'] = '' 82 elif subsystem == 'pci': 83 pci_class = device.get_property('PCI_ID') 84 if pci_class: 85 (result_item['prop1'], result_item['prop2']) = pci_class.split(':') 86 pci_subsys = device.get_property('PCI_SUBSYS_ID') 87 if pci_subsys: 88 (result_item['prop3'], result_item['prop4']) = pci_subsys.split(':') 89 elif subsystem == 'usb': 90 if device.has_property('ID_VENDOR_ID'): 91 result_item['prop1'] = device.get_property('ID_VENDOR_ID') 92 if device.has_property('ID_MODEL_ID'): 93 result_item['prop2'] = device.get_property('ID_MODEL_ID') 94 if device.has_property('ID_BUS') and device.get_property('ID_BUS') == 'scsi': 95 if device.has_property('ID_PATH') or device.has_property('DEVPATH'): 96 if device.has_property('ID_PATH'): 97 path = device.get_property('ID_PATH') 98 m = re.search('.*scsi-(\d+):(\d+):(\d+):(\d+)', path) 99 else: # device.has_property('DEVPATH') 100 path = device.get_property('DEVPATH') 101 m = re.search('.*/(\d+):(\d+):(\d+):(\d+)/block/', path) 102 if m: # do not fail, if regexp did not match 103 result_item['prop1'] = m.group(1) # DEV_HOST 104 result_item['prop2'] = m.group(2) # DEV_ID 105 result_item['prop3'] = m.group(3) # DEV_CHANNEL 106 result_item['prop4'] = m.group(4) # DEV_LUN 107 result.append(result_item) 108 return result
109
110 -def get_computer_info():
111 """ Return dictionaries with keys (values are provided as example): 112 'system.formfactor': 'unknown' 113 'system.kernel.version': '2.6.18-128.1.6.el5xen' 114 'system.kernel.machine': 'i686' 115 'system.kernel.name': 'Linux' 116 """ 117 uname = os.uname() 118 result = { 119 'system.kernel.name': uname[0], 120 'system.kernel.version': uname[2], 121 'system.kernel.machine': uname[4], 122 } 123 return result
124 125 #PCI DEVICE DEFINES 126 # These are taken from pci_ids.h in the linux kernel source and used to 127 # properly identify the hardware 128 PCI_BASE_CLASS_STORAGE = '1' 129 PCI_CLASS_STORAGE_SCSI = '00' 130 PCI_CLASS_STORAGE_IDE = '01' 131 PCI_CLASS_STORAGE_FLOPPY = '02' 132 PCI_CLASS_STORAGE_IPI = '03' 133 PCI_CLASS_STORAGE_RAID = '04' 134 PCI_CLASS_STORAGE_OTHER = '80' 135 136 PCI_BASE_CLASS_NETWORK = '2' 137 PCI_CLASS_NETWORK_ETHERNET = '00' 138 PCI_CLASS_NETWORK_TOKEN_RING = '01' 139 PCI_CLASS_NETWORK_FDDI = '02' 140 PCI_CLASS_NETWORK_ATM = '03' 141 PCI_CLASS_NETWORK_OTHER = '80' 142 143 PCI_BASE_CLASS_DISPLAY = '3' 144 PCI_CLASS_DISPLAY_VGA = '00' 145 PCI_CLASS_DISPLAY_XGA = '01' 146 PCI_CLASS_DISPLAY_3D = '02' 147 PCI_CLASS_DISPLAY_OTHER = '80' 148 149 PCI_BASE_CLASS_MULTIMEDIA = '4' 150 PCI_CLASS_MULTIMEDIA_VIDEO = '00' 151 PCI_CLASS_MULTIMEDIA_AUDIO = '01' 152 PCI_CLASS_MULTIMEDIA_PHONE = '02' 153 PCI_CLASS_MULTIMEDIA_OTHER = '80' 154 155 PCI_BASE_CLASS_BRIDGE = '6' 156 PCI_CLASS_BRIDGE_HOST = '00' 157 PCI_CLASS_BRIDGE_ISA = '01' 158 PCI_CLASS_BRIDGE_EISA = '02' 159 PCI_CLASS_BRIDGE_MC = '03' 160 PCI_CLASS_BRIDGE_PCI = '04' 161 PCI_CLASS_BRIDGE_PCMCIA = '05' 162 PCI_CLASS_BRIDGE_NUBUS = '06' 163 PCI_CLASS_BRIDGE_CARDBUS = '07' 164 PCI_CLASS_BRIDGE_RACEWAY = '08' 165 PCI_CLASS_BRIDGE_OTHER = '80' 166 167 PCI_BASE_CLASS_COMMUNICATION = '7' 168 PCI_CLASS_COMMUNICATION_SERIAL = '00' 169 PCI_CLASS_COMMUNICATION_PARALLEL = '01' 170 PCI_CLASS_COMMUNICATION_MULTISERIAL = '02' 171 PCI_CLASS_COMMUNICATION_MODEM = '03' 172 PCI_CLASS_COMMUNICATION_OTHER = '80' 173 174 PCI_BASE_CLASS_INPUT = '9' 175 PCI_CLASS_INPUT_KEYBOARD = '00' 176 PCI_CLASS_INPUT_PEN = '01' 177 PCI_CLASS_INPUT_MOUSE = '02' 178 PCI_CLASS_INPUT_SCANNER = '03' 179 PCI_CLASS_INPUT_GAMEPORT = '04' 180 PCI_CLASS_INPUT_OTHER = '80' 181 182 PCI_BASE_CLASS_SERIAL = 'C' 183 PCI_CLASS_SERIAL_FIREWIRE = '00' 184 PCI_CLASS_SERIAL_ACCESS = '01' 185 PCI_CLASS_SERIAL_SSA = '02' 186 PCI_CLASS_SERIAL_USB = '03' 187 PCI_CLASS_SERIAL_FIBER = '04' 188 PCI_CLASS_SERIAL_SMBUS = '05' 189
190 -def _clasify_pci_type(subsystem):
191 """ return 1 if device is PCI, otherwise -1 """ 192 if subsystem == 'pci': 193 return '1' 194 else: 195 return '-1'
196
197 -def _clasify_class(device):
198 """ Clasify type of device. Returned value is one of following string: 199 NETWORK, KEYBOARD, MOUSE, VIDEO, USB, IDE, SCSI, RAID, MODEM, SCANNER 200 CAPTURE, AUDIO, FIREWIRE, SOCKET, CDROM, HD, FLOPPY, TAPE, PRINTER, OTHER 201 or None if it is neither PCI nor USB device. 202 """ 203 (base_class, sub_class) = _parse_pci_class(device.get_property('PCI_CLASS')) 204 subsystem = device.get_subsystem() 205 206 # network devices 207 if base_class == PCI_BASE_CLASS_NETWORK: 208 return 'OTHER' # if set as 'NETWORK' it will not display in HW tab 209 210 # input devices 211 # pci 212 if base_class == PCI_BASE_CLASS_INPUT: 213 if sub_class == PCI_CLASS_INPUT_KEYBOARD: 214 return 'KEYBOARD' 215 elif sub_class == PCI_CLASS_INPUT_MOUSE: 216 return 'MOUSE' 217 # usb 218 id_serial = device.get_property('ID_SERIAL') 219 if id_serial: 220 id_serial = id_serial.lower() 221 # KEYBOARD <-- do this before mouse, some keyboards have built-in mice 222 if 'keyboard' in id_serial: 223 return 'KEYBOARD' 224 # MOUSE 225 if 'mouse' in id_serial: 226 return 'MOUSE' 227 228 if base_class: # PCI Devices 229 if base_class == PCI_BASE_CLASS_DISPLAY: 230 return 'VIDEO' 231 elif base_class == PCI_BASE_CLASS_SERIAL: 232 if sub_class == PCI_CLASS_SERIAL_USB: 233 return 'USB' 234 elif sub_class == PCI_CLASS_SERIAL_FIREWIRE: 235 return 'FIREWIRE' 236 elif base_class == PCI_BASE_CLASS_STORAGE: 237 if sub_class == PCI_CLASS_STORAGE_IDE: 238 return 'IDE' 239 elif sub_class == PCI_CLASS_STORAGE_SCSI: 240 return 'SCSI' 241 elif sub_class == PCI_CLASS_STORAGE_RAID: 242 return 'RAID' 243 elif sub_class == PCI_CLASS_STORAGE_FLOPPY: 244 return 'FLOPPY' 245 elif base_class == PCI_BASE_CLASS_COMMUNICATION and sub_class == PCI_CLASS_COMMUNICATION_MODEM: 246 return 'MODEM' 247 elif base_class == PCI_BASE_CLASS_INPUT and sub_class == PCI_CLASS_INPUT_SCANNER: 248 return 'SCANNER' 249 elif base_class == PCI_BASE_CLASS_MULTIMEDIA: 250 if sub_class == PCI_CLASS_MULTIMEDIA_VIDEO: 251 return 'CAPTURE' 252 elif sub_class == PCI_CLASS_MULTIMEDIA_AUDIO: 253 return 'AUDIO' 254 elif base_class == PCI_BASE_CLASS_BRIDGE and ( 255 sub_class == PCI_CLASS_BRIDGE_PCMCIA or sub_class == PCI_CLASS_BRIDGE_CARDBUS ): 256 return 'SOCKET' 257 258 if subsystem == 'block': 259 if device.has_property('ID_CDROM') or ( 260 device.has_property('ID_TYPE') and device.get_property('ID_TYPE') == 'cd'): 261 return 'CDROM' 262 else: 263 return 'HD' 264 elif subsystem == 'sound': 265 return 'AUDIO' 266 267 if subsystem =='scsi': 268 if device.get_devtype =='scsi_device': 269 dev_type = _get_scsi_dev_type(device) 270 if dev_type == 0 or dev_type == 14: 271 return 'HD' 272 elif dev_type == 1: 273 return 'TAPE' 274 elif dev_type == 5: 275 return 'CDROM' 276 else: 277 return 'OTHER' 278 # PRINTER 279 m = re.search('.*/lp\d+$', device.get_sysfs_path()) 280 if m: 281 return 'PRINTER' 282 283 if subsystem == 'scsi': 284 return 'SCSI' 285 286 # Catchall for specific devices, only do this after all the others 287 if subsystem == 'pci' or subsystem == 'usb': 288 return 'OTHER' 289 290 # No class found 291 return None
292
293 -def _get_device_desc(device):
294 """ Return human readable description of device. """ 295 subsystem = device.get_subsystem() 296 command = None 297 result = None 298 if subsystem == 'pci': 299 (vendor_id, device_id) = device.get_property('PCI_ID').split(':') 300 pci = PCI() 301 result = "%s|%s" % (pci.get_vendor(vendor_id), pci.get_device(vendor_id, device_id)) 302 elif subsystem == 'usb': 303 vendor_id = device.get_property('ID_VENDOR_ID') 304 usb = USB() 305 if vendor_id: 306 result = "%s|%s" % (usb.get_vendor(vendor_id), usb.get_device(vendor_id, device.get_property('ID_MODEL_ID'))) 307 elif device.get_devtype() == 'usb_interface': 308 if device.get_driver() == 'usbhid': 309 result = 'USB HID Interface' 310 elif device.get_driver() == 'hub': 311 result = 'USB Hub Interface' 312 else: 313 result = 'USB Interface' 314 elif device.get_devtype() == 'usb_device' and device.get_property('PRODUCT'): 315 (vendor_id, model_id) = device.get_property('PRODUCT').split('/')[:2] 316 # left pad it with 0 to 4 digits 317 vendor_id = '%.4x' % int(vendor_id, 16) 318 model_id = '%.4x' % int(model_id, 16) 319 result = "%s|%s" % (usb.get_vendor(vendor_id), usb.get_device(vendor_id, model_id)) 320 elif subsystem == 'block': 321 result = device.get_property('ID_MODEL') 322 if result: 323 return result 324 else: 325 return ''
326
327 -def _parse_pci_class(pci_class):
328 """ Parse Class Code. Return touple of 329 [base class code, sub-class code] 330 You are usually interested to only first two. 331 The third - "specific register-level programming interface" is ignored. 332 For details, see the PCI Local Bus Specification 2.1/2.2 Section 6.2.1 Device Identification 333 """ 334 if pci_class is None: 335 return (None, None) 336 else: 337 return (pci_class[-6:-4], pci_class[-4:-2])
338
339 -def _get_scsi_dev_type(device):
340 """ Return SCSI type of device in raw format as presented in /sys/...devpath../type """ 341 try: 342 f = open("%s/type" % device.get_sysfs_path(), 'r') 343 except IOError: 344 return -1 345 result = f.readline() 346 f.close() 347 return result
348