X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=source%2Fsysteminfo.py;h=8de50b704120019e80c59d7726b90378564ce5aa;hb=8412dc83e50649c6b3e2f27579f5a2cd6501a5c6;hp=2faf3c2fcadf6bead1aec667e2e09eaabb61970f;hpb=7ab7e9dd797333a9fdc8604554e16e192a32144d;p=bootmanager.git diff --git a/source/systeminfo.py b/source/systeminfo.py index 2faf3c2..8de50b7 100755 --- a/source/systeminfo.py +++ b/source/systeminfo.py @@ -64,9 +64,9 @@ import string import os import popen2 -from merge_hw_tables import merge_hw_tables - +import merge_hw_tables +hwdatapath = "usr/share/hwdata" class systeminfo: """ a utility class for finding and returning information about @@ -93,10 +93,15 @@ class systeminfo: MODULE_CLASS_NETWORK= "network" MODULE_CLASS_SCSI= "scsi" - PCI_CLASS_NETWORK= "0200" - PCI_CLASS_RAID= "0104" - PCI_CLASS_RAID2= "0100" + PCI_CLASS_NETWORK_ETHERNET=0x0200L + PCI_CLASS_STORAGE_SCSI=0x0100L + PCI_CLASS_STORAGE_IDE=0x0101L + PCI_CLASS_STORAGE_FLOPPY=0x0102L + PCI_CLASS_STORAGE_IPI=0x0103L + PCI_CLASS_STORAGE_RAID=0x0104L + PCI_CLASS_STORAGE_OTHER=0x0180L + PCI_ANY=0xffffffffL def get_total_phsyical_mem(self): """ @@ -222,12 +227,6 @@ class systeminfo: device= parts[3] - # if the last char in device is a number, its - # a partition, and we ignore it - - if device[len(device)-1].isdigit(): - continue - dev_name= "/dev/%s" % device try: @@ -237,6 +236,10 @@ class systeminfo: except ValueError, err: continue + # skip and ignore any partitions + if minor != 0: + continue + gb_size= blocks/self.BLOCKS_PER_GB # parse the output of hdparm to get the readonly flag; @@ -289,42 +292,50 @@ class systeminfo: - def get_system_modules( self, install_root ): + def get_system_modules( self, install_root, kernel_version= None ): """ Return a list of kernel modules that this system requires. This requires access to the installed system's root directory, as the following files must exist and are used: /usr/share/hwdata/pcitable - /lib/modules/(first entry)/modules.pcimap - /lib/modules/(first entry)/modules.dep + /lib/modules/(first entry if kernel_version unspecified)/modules.pcimap + /lib/modules/(first entry if kernel version unspecified)/modules.dep - Note, that this assumes there is only one kernel - that is installed. If there are more than one, then - only the first one in a directory listing is used. + If there are more than one kernels installed, and the kernel + version is not specified, then only the first one in + /lib/modules is used. Returns a dictionary, keys being the type of module: - scsi MODULE_CLASS_SCSI - network MODULE_CLASS_NETWORK The value being the kernel module name to load. + + Some sata devices show up under an IDE device class, + hence the reason for checking for ide devices as well. + If there actually is a match in the pci -> module lookup + table, and its an ide device, its most likely sata, + as ide modules are built in to the kernel. """ # get the kernel version we are assuming - try: - kernel_version= os.listdir( "%s/lib/modules/" % install_root ) - except OSError, e: - return + if kernel_version is None: + try: + kernel_version= os.listdir( "%s/lib/modules/" % install_root ) + except OSError, e: + return - if len(kernel_version) == 0: - return + if len(kernel_version) == 0: + return + + if len(kernel_version) > 1: + print( "WARNING: We may be returning modules for the wrong kernel." ) - if len(kernel_version) > 1: - print( "WARNING: We may be returning modules for the wrong kernel." ) + kernel_version= kernel_version[0] - kernel_version= kernel_version[0] print( "Using kernel version %s" % kernel_version ) # test to make sure the three files we need are present - pcitable_path = "%s/usr/share/hwdata/pcitable" % install_root + pcitable_path = "%s/%s/pcitable" % (install_root,hwdatapath) modules_pcimap_path = "%s/lib/modules/%s/modules.pcimap" % \ (install_root,kernel_version) modules_dep_path = "%s/lib/modules/%s/modules.dep" % \ @@ -337,15 +348,13 @@ class systeminfo: # now, with those three files, merge them all into one easy to # use lookup table - all_modules= merge_hw_tables().merge_files( modules_dep_path, - modules_pcimap_path, - pcitable_path ) - + (all_pci_ids, all_modules) = merge_hw_tables.merge_files( modules_dep_path, + modules_pcimap_path, + pcitable_path ) if all_modules is None: print( "Unable to merge pci id tables." ) return - # this is the actual data structure we return system_mods= {} @@ -367,6 +376,9 @@ class systeminfo: else: print( "Successfully ran %s" % self.LSPCI_CMD ) + # for every lspci line, parse in the four tuple PCI id and the + # search for the corresponding driver from the dictionary + # generated by merge_hw_tables for line in lspci_prog.fromchild: if string.strip(line) == "": continue @@ -375,27 +387,111 @@ class systeminfo: try: classid= self.remove_quotes(parts[2]) + classid= long(classid,16) + except IndexError: + print( "Skipping invalid classid:", string.strip(line) ) + continue + except ValueError, e: + print( "Skipping invalid classid:", string.strip(line) ) + continue + + + if classid not in (self.PCI_CLASS_NETWORK_ETHERNET, + self.PCI_CLASS_STORAGE_SCSI, + self.PCI_CLASS_STORAGE_RAID, + self.PCI_CLASS_STORAGE_OTHER, + self.PCI_CLASS_STORAGE_IDE): + continue + + vendorid = self.PCI_ANY + deviceid = self.PCI_ANY + subvendorid = self.PCI_ANY + subdeviceid = self.PCI_ANY + + # parse in vendorid + try: vendorid= self.remove_quotes(parts[3]) - deviceid= self.remove_quotes(parts[4]) + vendorid= long(vendorid,16) except IndexError: - print( "Skipping invalid line:", string.strip(line) ) + print( "Skipping invalid vendorid:", string.strip(line) ) + continue + except ValueError, e: + print( "Skipping invalid vendorid:", string.strip(line) ) continue - if classid not in (self.PCI_CLASS_NETWORK, - self.PCI_CLASS_RAID, - self.PCI_CLASS_RAID2): + # parse in deviceid + try: + deviceid= self.remove_quotes(parts[4]) + deviceid= long(deviceid,16) + except IndexError: + print( "Skipping invalid deviceid:", string.strip(line) ) continue - - full_deviceid= "%s:%s" % (vendorid,deviceid) - - for module in all_modules.keys(): - if full_deviceid in all_modules[module]: - if classid == self.PCI_CLASS_NETWORK: - network_mods.append(module) - elif classid in (self.PCI_CLASS_RAID, - self.PCI_CLASS_RAID2): - scsi_mods.append(module) - + except ValueError, e: + print( "Skipping invalid deviceid:", string.strip(line) ) + continue + + # Now get the subvendor & subdevice portion by searching + # parts[5:] of the lspci output. Note that we have to skip + # the portions of the lspci output string that indicate + # revision info. + + # parse in subvendorid + subvendorindex = -1 + for i in range(5,len(parts)): + p = self.remove_quotes(parts[i]) + if p[0] != '-': + subvendorindex = i + break + + if subvendorindex != -1: + try: + subvendorid= self.remove_quotes(parts[subvendorindex]) + subvendorid= long(subvendorid,16) + except IndexError: + print( "Skipping invalid line:", string.strip(line) ) + continue + except ValueError, e: + print( "Skipping invalid line:", string.strip(line) ) + continue + + # parse in subdeviceid + subdeviceindex = -1 + for i in range(subvendorindex+1,len(parts)): + p = self.remove_quotes(parts[i]) + if p[0] != '-': + subdeviceindex = i + break + if subdeviceindex != -1: + error_msg = "Skipping invalid subdeviceid:" + try: + subdeviceid= self.remove_quotes(parts[subdeviceindex]) + subdeviceid= long(subdeviceid,16) + except IndexError: + print( error_msg, string.strip(line) ) + continue + except ValueError, e: + print( error_msg, string.strip(line) ) + continue + + # search for driver that most closely matches the full_id + # to drivers that can handle any subvendor/subdevice + # version of the hardware. + full_ids = ((vendorid,deviceid,subvendorid,subdeviceid), + (vendorid,deviceid,subvendorid,self.PCI_ANY), + (vendorid,deviceid,self.PCI_ANY,self.PCI_ANY)) + + for full_id in full_ids: + module = all_pci_ids.get(full_id, None) + if module is not None: + if classid == self.PCI_CLASS_NETWORK_ETHERNET: + network_mods.append(module[0]) + elif classid in (self.PCI_CLASS_STORAGE_SCSI, + self.PCI_CLASS_STORAGE_RAID, + self.PCI_CLASS_STORAGE_OTHER, + self.PCI_CLASS_STORAGE_IDE): + scsi_mods.append(module[0]) + break + system_mods[self.MODULE_CLASS_SCSI]= scsi_mods system_mods[self.MODULE_CLASS_NETWORK]= network_mods @@ -437,7 +533,13 @@ if __name__ == "__main__": print "" - modules= info.get_system_modules("/") + + import sys + kernel_version = None + if len(sys.argv) > 2: + kernel_version = sys.argv[1] + + modules= info.get_system_modules("/",kernel_version) if not modules: print "unable to list system modules" else: