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

Source Code for Module up2date_client.hardware_udev

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