X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=source%2Fsysteminfo.py;h=921ede6dd9d55ede051c0ad867540bb20a7ca5a2;hb=b55940dc66e561b2f186fba8202098d809070a1c;hp=966c149456ebec2273b0b43a84f8e3526ebb233e;hpb=4a1eab94eaaf3d9774b7fb89c3a233ca62388d2f;p=bootmanager.git diff --git a/source/systeminfo.py b/source/systeminfo.py index 966c149..921ede6 100755 --- a/source/systeminfo.py +++ b/source/systeminfo.py @@ -1,5 +1,5 @@ -#!/usr/bin/python2 - +#!/usr/bin/python +# # Copyright (c) 2003 Intel Corporation # All rights reserved. # @@ -23,13 +23,12 @@ import string import sys import os import popen2 -import merge_hw_tables import re import errno import ModelOptions +from pypci import * from Exceptions import * -hwdatapath = "usr/share/hwdata" """ a utility class for finding and returning information about block devices, memory, and other hardware on the system @@ -47,21 +46,12 @@ DEVICES_SCANNED_FLAG= "/tmp/devices_scanned" BLOCKS_PER_GB = pow(10, 9) / 1024.0; -# -n is numeric ids (no lookup), -m is machine readable -LSPCI_CMD= "/sbin/lspci -nm" - MODULE_CLASS_NETWORK= "network" MODULE_CLASS_SCSI= "scsi" -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 +#PCI_* is now defined in the pypci modules +#PCI_BASE_CLASS_NETWORK=0x02L +#PCI_BASE_CLASS_STORAGE=0x01L def get_total_phsyical_mem(vars = {}, log = sys.stderr): """ @@ -127,7 +117,8 @@ def get_block_device_list(vars = {}, log = sys.stderr): # table with valid scsi/sata/ide/raid block device names valid_blk_names = {} # add in valid sd and hd block device names - for blk_prefix in ('sd','hd'): + # also check for vd (virtio devices used with kvm) + for blk_prefix in ('sd','hd','vd'): for blk_num in map ( \ lambda x: chr(x), range(ord('a'),ord('z')+1)): devicename="%s%c" % (blk_prefix, blk_num) @@ -139,6 +130,16 @@ def get_block_device_list(vars = {}, log = sys.stderr): devicename = "cciss/c%dd%d" % (M,N) valid_blk_names[devicename]=None + for devicename in valid_blk_names.keys(): + # devfs under 2.4 (old boot cds) used to list partitions + # in a format such as scsi/host0/bus0/target0/lun0/disc + # and /dev/sda, etc. were just symlinks + try: + devfsname= os.readlink( "/dev/%s" % devicename ) + valid_blk_names[devfsname]=None + except OSError: + pass + # only do this once every system boot if not os.access(DEVICES_SCANNED_FLAG, os.R_OK): @@ -149,10 +150,14 @@ def get_block_device_list(vars = {}, log = sys.stderr): # so, lets run sfdisk -l (list partitions) against # most possible block devices, that way they show # up when it comes time to do the install. + + # 27.6.2012 - Using parted instead of sfdisk, assuming + # that doing so respects the behavior mentioned above. + devicenames = valid_blk_names.keys() devicenames.sort() for devicename in devicenames: - os.system( "sfdisk -l /dev/%s > /dev/null 2>&1" % devicename ) + os.system( "parted --script --list /dev/%s > /dev/null 2>&1" % devicename ) # touch file fb = open(DEVICES_SCANNED_FLAG,"w") @@ -213,10 +218,8 @@ def get_system_modules( vars = {}, log = sys.stderr): """ 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 + directory, as the following file must exist and is used: /lib/modules/(first entry if kernel_version unspecified)/modules.pcimap - /lib/modules/(first entry if kernel version unspecified)/modules.dep If there are more than one kernels installed, and the kernel version is not specified, then only the first one in @@ -260,27 +263,15 @@ def get_system_modules( vars = {}, log = sys.stderr): print( "Using kernel version %s" % kernel_version ) - # test to make sure the three files we need are present - pcitable_path = "%s/%s/pcitable" % (SYSIMG_PATH,hwdatapath) + # test to make sure the file we need is present modules_pcimap_path = "%s/lib/modules/%s/modules.pcimap" % \ (SYSIMG_PATH,kernel_version) - modules_dep_path = "%s/lib/modules/%s/modules.dep" % \ - (SYSIMG_PATH,kernel_version) - - for path in (pcitable_path,modules_pcimap_path,modules_dep_path): - if not os.access(path,os.R_OK): - print( "Unable to read %s" % path ) - return - - # now, with those three files, merge them all into one easy to - # use lookup table - (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." ) + if not os.access(modules_pcimap_path,os.R_OK): + print( "WARNING: Unable to read %s" % modules_pcimap_path ) return + pcimap = pypcimap.PCIMap(modules_pcimap_path) + # this is the actual data structure we return system_mods= {} @@ -288,85 +279,30 @@ def get_system_modules( vars = {}, log = sys.stderr): network_mods= [] scsi_mods= [] + # XXX: this is really similar to what BootCD/conf_files/pl_hwinit does. merge? + pcidevs = get_devices() + + devlist=pcidevs.keys() + devlist.sort() + for slot in devlist: + dev = pcidevs[slot] + base = (dev[4] & 0xff0000) >> 16 + modules = pcimap.get(dev) + if base not in (PCI_BASE_CLASS_STORAGE, + PCI_BASE_CLASS_NETWORK): + # special exception for forcedeth NICs whose base id + # claims to be a Bridge, even though it is clearly a + # network device + if "forcedeth" in modules: + base=PCI_BASE_CLASS_NETWORK + else: + continue - # get all the system devices from lspci - lspci_prog= popen2.Popen3( LSPCI_CMD, 1 ) - if lspci_prog is None: - print( "Unable to run %s with popen2.Popen3" % LSPCI_CMD ) - return - - returncode= lspci_prog.wait() - if returncode != 0: - print( "Running %s failed" % LSPCI_CMD ) - return - else: - print( "Successfully ran %s" % 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: - # A sample line: - # - # 00:1f.1 "Class 0101" "8086" "2411" -r02 -p80 "8086" "2411" - # - # Remove '"', 'Class ', and anything beginning with '-' - # (usually revisions and prog-if flags) so that we can - # split on whitespace: - # - # 00:1f.1 0101 8086 2411 8086 2411 - # - line = line.strip() - line = line.replace('"', '') - line = line.replace('Class ', '') - line = re.sub('-[^ ]*', '', line) - - parts = line.split() - try: - if len(parts) < 4: - raise - classid = long(parts[1], 16) - vendorid = long(parts[2], 16) - deviceid = long(parts[3], 16) - except: - print "Invalid line:", line - continue - - if classid not in (PCI_CLASS_NETWORK_ETHERNET, - PCI_CLASS_STORAGE_SCSI, - PCI_CLASS_STORAGE_RAID, - PCI_CLASS_STORAGE_OTHER, - PCI_CLASS_STORAGE_IDE): - continue - - # Device may have a subvendorid and subdeviceid - try: - subvendorid = long(parts[4], 16) - subdeviceid = long(parts[5], 16) - except: - subvendorid = PCI_ANY - subdeviceid = PCI_ANY - - # 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,PCI_ANY), - (vendorid,deviceid,PCI_ANY,PCI_ANY)) - - for full_id in full_ids: - module = all_pci_ids.get(full_id, None) - if module is not None: - if classid == PCI_CLASS_NETWORK_ETHERNET: - network_mods.append(module[0]) - elif classid in (PCI_CLASS_STORAGE_SCSI, - PCI_CLASS_STORAGE_RAID, - PCI_CLASS_STORAGE_OTHER, - PCI_CLASS_STORAGE_IDE): - scsi_mods.append(module[0]) - else: - print "not network or scsi: 0x%x" % classid - break + if len(modules) > 0: + if base == PCI_BASE_CLASS_NETWORK: + network_mods += modules + elif base == PCI_BASE_CLASS_STORAGE: + scsi_mods += modules system_mods[MODULE_CLASS_SCSI]= scsi_mods system_mods[MODULE_CLASS_NETWORK]= network_mods @@ -439,13 +375,10 @@ if __name__ == "__main__": if not modules: print "unable to list system modules" else: - for type in modules: - if type == MODULE_CLASS_SCSI: - print( "all scsi modules:" ) - for a_mod in modules[type]: - print a_mod - elif type == MODULE_CLASS_NETWORK: - print( "all network modules:" ) - for a_mod in modules[type]: - print a_mod + for module_class in (MODULE_CLASS_SCSI,MODULE_CLASS_NETWORK): + if len(modules[module_class]) > 0: + module_list = "" + for a_mod in modules[module_class]: + module_list = module_list + "%s " % a_mod + print "all %s modules: %s" % (module_class, module_list)