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

Source Code for Module up2date_client.hardware_hal

  1  # 
  2  # Copyright (c) 1999--2016 Red Hat, Inc. 
  3  # 
  4  # This software is licensed to you under the GNU General Public License, 
  5  # version 2 (GPLv2). There is NO WARRANTY for this software, express or 
  6  # implied, including the implied warranties of MERCHANTABILITY or FITNESS 
  7  # FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 
  8  # along with this software; if not, see 
  9  # http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. 
 10  # 
 11  # Red Hat trademarks are not licensed under GPLv2. No permission is 
 12  # granted to use or replicate Red Hat trademarks that are incorporated 
 13  # in this software or its documentation. 
 14  # 
 15   
 16  """ Get hardware info using HAL """ 
 17   
 18  from haltree import HalTree, HalDevice 
 19  import dbus 
 20   
 21  #PCI DEVICE DEFINES 
 22  # These are taken from pci_ids.h in the linux kernel source and used to 
 23  # properly identify the hardware 
 24  PCI_BASE_CLASS_STORAGE =        1 
 25  PCI_CLASS_STORAGE_SCSI =        0 
 26  PCI_CLASS_STORAGE_IDE =         1 
 27  PCI_CLASS_STORAGE_FLOPPY =      2 
 28  PCI_CLASS_STORAGE_IPI =         3 
 29  PCI_CLASS_STORAGE_RAID =        4 
 30  PCI_CLASS_STORAGE_OTHER =       80 
 31   
 32  PCI_BASE_CLASS_NETWORK =        2 
 33  PCI_CLASS_NETWORK_ETHERNET =    0 
 34  PCI_CLASS_NETWORK_TOKEN_RING =  1 
 35  PCI_CLASS_NETWORK_FDDI =        2 
 36  PCI_CLASS_NETWORK_ATM =         3 
 37  PCI_CLASS_NETWORK_OTHER =       80 
 38   
 39  PCI_BASE_CLASS_DISPLAY =        3 
 40  PCI_CLASS_DISPLAY_VGA =         0 
 41  PCI_CLASS_DISPLAY_XGA =         1 
 42  PCI_CLASS_DISPLAY_3D =          2 
 43  PCI_CLASS_DISPLAY_OTHER =       80 
 44   
 45  PCI_BASE_CLASS_MULTIMEDIA =     4 
 46  PCI_CLASS_MULTIMEDIA_VIDEO =    0 
 47  PCI_CLASS_MULTIMEDIA_AUDIO =    1 
 48  PCI_CLASS_MULTIMEDIA_PHONE =    2 
 49  PCI_CLASS_MULTIMEDIA_OTHER =    80 
 50   
 51  PCI_BASE_CLASS_BRIDGE =         6 
 52  PCI_CLASS_BRIDGE_HOST =         0 
 53  PCI_CLASS_BRIDGE_ISA =          1 
 54  PCI_CLASS_BRIDGE_EISA =         2 
 55  PCI_CLASS_BRIDGE_MC =           3 
 56  PCI_CLASS_BRIDGE_PCI =          4 
 57  PCI_CLASS_BRIDGE_PCMCIA =       5 
 58  PCI_CLASS_BRIDGE_NUBUS =        6 
 59  PCI_CLASS_BRIDGE_CARDBUS =      7 
 60  PCI_CLASS_BRIDGE_RACEWAY =      8 
 61  PCI_CLASS_BRIDGE_OTHER =        80 
 62   
 63  PCI_BASE_CLASS_COMMUNICATION =  7 
 64  PCI_CLASS_COMMUNICATION_SERIAL = 0 
 65  PCI_CLASS_COMMUNICATION_PARALLEL = 1 
 66  PCI_CLASS_COMMUNICATION_MULTISERIAL = 2 
 67  PCI_CLASS_COMMUNICATION_MODEM = 3 
 68  PCI_CLASS_COMMUNICATION_OTHER = 80 
 69   
 70  PCI_BASE_CLASS_INPUT =          9 
 71  PCI_CLASS_INPUT_KEYBOARD =      0 
 72  PCI_CLASS_INPUT_PEN =           1 
 73  PCI_CLASS_INPUT_MOUSE =         2 
 74  PCI_CLASS_INPUT_SCANNER =       3 
 75  PCI_CLASS_INPUT_GAMEPORT =      4 
 76  PCI_CLASS_INPUT_OTHER =         80 
 77   
 78  PCI_BASE_CLASS_SERIAL =         12 
 79  PCI_CLASS_SERIAL_FIREWIRE =     0 
 80  PCI_CLASS_SERIAL_ACCESS =       1 
 81  PCI_CLASS_SERIAL_SSA =          2 
 82  PCI_CLASS_SERIAL_USB =          3 
 83  PCI_CLASS_SERIAL_FIBER =        4 
 84  PCI_CLASS_SERIAL_SMBUS =        5 
 85   
 86  # read_hal() 
 87  # 
 88  # This reads in all the properties for each device from HAL, storing the 
 89  # property names & values into a dict.  A list of dicts is returned. 
 90  # 
 91  # This only works on newer versions of dbus & HAL (as found in RHEL5) 
92 -def read_hal():
93 ret = [] 94 bus = dbus.SystemBus() 95 96 hal_manager_obj = bus.get_object('org.freedesktop.Hal', 97 '/org/freedesktop/Hal/Manager') 98 hal_manager = dbus.Interface(hal_manager_obj, 99 'org.freedesktop.Hal.Manager') 100 101 device_list = hal_manager.GetAllDevices() 102 hal_tree = HalTree() 103 for udi in device_list: 104 device_obj = bus.get_object ('org.freedesktop.Hal', udi) 105 device = dbus.Interface(device_obj, 'org.freedesktop.Hal.Device') 106 107 properties = device.GetAllProperties() 108 109 haldev = HalDevice(properties) 110 hal_tree.add(haldev) 111 112 kudzu_list = process_hal_nodes(hal_tree.head) 113 return kudzu_list
114 115 # Recursive function, does all the dirty work for add_hal_hardware
116 -def process_hal_nodes(node):
117 kudzu_list = [] 118 node.classification = classify_hal(node) 119 if node.classification: 120 parent = node.parent 121 dev = {} 122 dev['class'] = node.classification 123 #get bus 124 dev['bus'] = str(get_device_bus(node)) 125 126 #get scsi info 127 if dev['bus'] == 'scsi': 128 if 'scsi.host' in parent.properties: 129 dev['prop1'] = parent.properties['scsi.host'] 130 if 'scsi.target' in parent.properties: 131 dev['prop2'] = parent.properties['scsi.target'] 132 if 'scsi.bus' in parent.properties: 133 dev['prop3'] = parent.properties['scsi.bus'] 134 if 'scsi.lun' in parent.properties: 135 dev['prop4'] = parent.properties['scsi.lun'] 136 137 138 dev['driver'] = str(get_device_driver(node)) 139 140 device_path = get_device_path(node) 141 if device_path: 142 dev['device'] = str(device_path) 143 144 dev['desc'] = str(get_device_description(node)) 145 146 dev['pciType'] = str(get_device_pcitype(node)) 147 148 dev['detached'] = 0 149 kudzu_list.append(dev) 150 151 for child in node.children: 152 child_list = process_hal_nodes(child) 153 kudzu_list.extend(child_list) 154 155 return kudzu_list
156
157 -def classify_hal(node):
158 # NETWORK 159 if 'net.interface' in node.properties: 160 return 'NETWORK' 161 162 if 'info.product' in node.properties and 'info.category' in node.properties: 163 if node.properties['info.category'] == 'input': 164 # KEYBOARD <-- do this before mouse, some keyboards have built-in mice 165 if 'keyboard' in node.properties['info.product'].lower(): 166 return 'KEYBOARD' 167 # MOUSE 168 if 'mouse' in node.properties['info.product'].lower(): 169 return 'MOUSE' 170 171 if 'pci.device_class' in node.properties: 172 #VIDEO 173 if node.properties['pci.device_class'] == PCI_BASE_CLASS_DISPLAY: 174 return 'VIDEO' 175 #USB 176 if (node.properties['pci.device_class'] == PCI_BASE_CLASS_SERIAL 177 and node.properties['pci.device_subclass'] == PCI_CLASS_SERIAL_USB): 178 return 'USB' 179 180 if node.properties['pci.device_class'] == PCI_BASE_CLASS_STORAGE: 181 #IDE 182 if node.properties['pci.device_subclass'] == PCI_CLASS_STORAGE_IDE: 183 return 'IDE' 184 #SCSI 185 if node.properties['pci.device_subclass'] == PCI_CLASS_STORAGE_SCSI: 186 return 'SCSI' 187 #RAID 188 if node.properties['pci.device_subclass'] == PCI_CLASS_STORAGE_RAID: 189 return 'RAID' 190 #MODEM 191 if (node.properties['pci.device_class'] == PCI_BASE_CLASS_COMMUNICATION 192 and node.properties['pci.device_subclass'] == PCI_CLASS_COMMUNICATION_MODEM): 193 return 'MODEM' 194 #SCANNER 195 if (node.properties['pci.device_class'] == PCI_BASE_CLASS_INPUT 196 and node.properties['pci.device_subclass'] == PCI_CLASS_INPUT_SCANNER): 197 return 'SCANNER' 198 199 if node.properties['pci.device_class'] == PCI_BASE_CLASS_MULTIMEDIA: 200 #CAPTURE -- video capture card 201 if node.properties['pci.device_subclass'] == PCI_CLASS_MULTIMEDIA_VIDEO: 202 return 'CAPTURE' 203 #AUDIO 204 if node.properties['pci.device_subclass'] == PCI_CLASS_MULTIMEDIA_AUDIO: 205 return 'AUDIO' 206 207 #FIREWIRE 208 if (node.properties['pci.device_class'] == PCI_BASE_CLASS_SERIAL 209 and node.properties['pci.device_subclass'] == PCI_CLASS_SERIAL_FIREWIRE): 210 return 'FIREWIRE' 211 #SOCKET -- PCMCIA yenta socket stuff 212 if (node.properties['pci.device_class'] == PCI_BASE_CLASS_BRIDGE 213 and (node.properties['pci.device_subclass'] == PCI_CLASS_BRIDGE_PCMCIA 214 or node.properties['pci.device_subclass'] == PCI_CLASS_BRIDGE_CARDBUS)): 215 return 'SOCKET' 216 217 if 'storage.drive_type' in node.properties: 218 #CDROM 219 if node.properties['storage.drive_type'] == 'cdrom': 220 return 'CDROM' 221 #HD 222 if node.properties['storage.drive_type'] == 'disk': 223 return 'HD' 224 #FLOPPY 225 if node.properties['storage.drive_type'] == 'floppy': 226 return 'FLOPPY' 227 #TAPE 228 if node.properties['storage.drive_type'] == 'tape': 229 return 'TAPE' 230 231 if 'xen.type' in node.properties: 232 if node.properties['xen.type'] == 'vbd': 233 return 'HD' 234 235 #PRINTER 236 if 'printer.product' in node.properties: 237 return 'PRINTER' 238 239 #Catchall for specific devices, only do this after all the others 240 if ('pci.product_id' in node.properties or 241 'usb.product_id' in node.properties): 242 return 'OTHER' 243 244 # No class found 245 return None
246
247 -def get_device_bus(node):
248 if 'storage.bus' in node.properties: 249 bus = node.properties['storage.bus'] 250 elif 'info.bus' in node.properties: 251 if node.properties['info.bus'] == 'platform': 252 bus = 'MISC' 253 else: 254 bus = node.properties['info.bus'] 255 else: 256 bus = 'MISC' 257 258 return bus
259
260 -def get_device_driver(node):
261 if 'info.linux.driver' in node.properties: 262 driver = node.properties['info.linux.driver'] 263 elif 'net.linux.driver' in node.properties: 264 driver = node.properties['net.linux.driver'] 265 else: 266 driver = 'unknown' 267 268 return driver
269
270 -def get_device_path(node):
271 """ 272 Return the device file path. 273 274 As kudzu did not return a string with the /dev/ prefix, 275 this function will not, either. 276 RHN's DB has a limit of 16 characters for the device path. 277 If the path is longer than that, return None. 278 If no device path is found, return None. 279 """ 280 dev = None 281 282 if 'block.device' in node.properties: 283 dev = node.properties['block.device'] 284 elif 'linux.device_file' in node.properties: 285 dev = node.properties['linux.device_file'] 286 elif (node.classification == 'NETWORK' 287 and 'net.interface' in node.properties): 288 dev = node.properties['net.interface'] 289 290 if dev: 291 if dev.startswith('/dev/'): 292 dev = dev[5:] 293 if len(dev) > 16: 294 dev = None 295 296 return dev
297
298 -def get_device_description(node):
299 if ('info.vendor' in node.properties 300 and 'info.product' in node.properties): 301 desc = node.properties['info.vendor'] + '|' + node.properties['info.product'] 302 elif ('info.vendor' in node.properties): 303 desc = node.properties['info.vendor'] 304 elif 'info.product' in node.properties: 305 desc = node.properties['info.product'] 306 else: 307 desc = "" 308 309 return desc
310
311 -def get_device_pcitype(node):
312 PCI_TYPE_PCMCIA = 2 313 PCI_TYPE_PCI = 1 314 PCI_TYPE_NOT_PCI = -1 315 316 if 'info.bus' in (node.properties 317 and node.properties['info.bus'] == 'pci'): 318 parent = node.parent 319 if ('pci.device_class' in parent.properties 320 and (parent.properties['pci.device_class'] == 6 321 and (parent.properties['pci.device_subclass'] == 5 322 or parent.properties['pci.device_subclass'] == 7))): 323 pcitype = PCI_TYPE_PCMCIA 324 else: 325 pcitype = PCI_TYPE_PCI 326 else: 327 pcitype = PCI_TYPE_NOT_PCI 328 329 return pcitype
330
331 -def get_hal_computer():
332 bus = dbus.SystemBus() 333 computer_obj = bus.get_object("org.freedesktop.Hal", 334 "/org/freedesktop/Hal/devices/computer") 335 computer = dbus.Interface(computer_obj, "org.freedesktop.Hal.Device") 336 337 return computer
338
339 -def check_hal_dbus_status():
340 # check if hal and messagebus are running, if not warn the user 341 import commands 342 hal_status, msg = commands.getstatusoutput('/etc/init.d/haldaemon status') 343 dbus_status, msg = commands.getstatusoutput('/etc/init.d/messagebus status') 344 return hal_status, dbus_status
345