--- /dev/null
+#!/usr/bin/python2
+
+# Copyright (c) 2003 Intel Corporation
+# All rights reserved.
+#
+# Copyright (c) 2004-2006 The Trustees of Princeton University
+# All rights reserved.
+
+
+"""
+The point of this small utility is to take a file in the format
+of /lib/modules/`uname -r`/modules.pcimap and /usr/share/hwdata/pcitable
+and output a condensed, more easily used format for module detection. This is
+done by first getting a list of all the built modules, then loading the
+pci ids for each of those modules from modules.pcimap, then finally merging
+in the contents of pcitable (for built modules only). The result should be
+a file with a pretty comprehensive mapping of pci ids to module names.
+
+The output is used by the PlanetLab boot cd (3.0+) and the pl_hwinit script
+to load all the applicable modules by scanning lspci output.
+
+
+
+Expected format of file modules.dep includes lines of:
+
+/full/module/path/mod.ko: <dependencies>
+
+Expected format of file modules.pcimap includes lines of:
+
+# pci_module vendor device subvendor subdevice class class_mask driver_data
+cciss 0x00000e11 0x0000b060 0x00000e11 0x00004070 0x00000000 0x00000000 0x0
+cciss 0x00000e11 0x0000b178 0x00000e11 0x00004070 0x00000000 0x00000000 0x0
+
+Expected format of file pcitable includes lines of:
+
+# ("%d\t%d\t%s\t"%s"\n", vendid, devid, moduleName, cardDescription)
+# or ("%d\t%d\t%d\t%d\t%s\t"%s"\n", vendid, devid, subvendid, subdevid, moduleNa
+# me, cardDescription)
+0x0e11 0x0508 "tmspci" "Compaq|Netelligent 4/16 Token Ring"
+0x1000 0x0407 0x8086 0x0532 "megaraid" "Storage RAID Controller SRCU42X"
+
+Lines listing a module name of ignore or unknown from pcitable are skipped
+
+
+
+Output format, for each line that matches the above lines:
+cciss 0e11:b060 0e11:b178
+
+"""
+
+import os, sys
+import string
+import StringIO
+
+PCI_ANY = 0xffffffffL
+
+def merge_files(modules_dep_path, modules_pcimap_path, pcitable_path):
+ """
+ merge the three files as described above, and return a dictionary.
+ keys are module names, value is a list of pci ids for that module,
+ in the form "0e11:b178"
+ """
+
+ try:
+ modulesdep_file= file(modules_dep_path,"r")
+ except IOError:
+ sys.stderr.write( "Unable to open modules.dep: %s\n" %
+ modules_dep_path )
+ return
+
+ try:
+ pcimap_file= file(modules_pcimap_path,"r")
+ except IOError:
+ sys.stderr.write( "Unable to open modules.pcimap: %s\n" %
+ modules_pcimap_path )
+ return
+
+ try:
+ pcitable_file= file(pcitable_path,"r")
+ except IOError:
+ sys.stderr.write( "Unable to open pcitable: %s\n" %
+ pcitable_path )
+ pcitable_file=StringIO.StringIO()
+
+ # associative array to store all matches of module -> ['vendor:device',..]
+ # entries
+ all_modules= {}
+ all_pci_ids= {}
+
+ # first step, create an associative array of all the built modules
+ for line in modulesdep_file:
+ parts= string.split(line,":")
+ if len(parts) < 2:
+ continue
+
+ full_mod_path= parts[0]
+ parts= string.split(full_mod_path,"/")
+ module= parts[len(parts)-1]
+ module_len= len(module)
+ if module[module_len-3:] == ".ko":
+ module= module[:-3]
+ all_modules[module]= []
+
+ modulesdep_file.close()
+
+ # now, parse the pcimap and add devices
+ line_num= 0
+ for line in pcimap_file:
+ line_num= line_num+1
+
+ # skip blank lines, or lines that begin with # (comments)
+ line= string.strip(line)
+ if len(line) == 0:
+ continue
+
+ if line[0] == "#":
+ continue
+
+ line_parts= string.split(line)
+ if line_parts is None or len(line_parts) != 8:
+ sys.stderr.write( "Skipping line %d in pcimap " \
+ "(incorrect format %s)\n" % (line_num,line) )
+ continue
+
+ # first two parts are always vendor / device id
+ module= line_parts[0]
+
+ # XXX In kernel versions <2.6.14, mptscsih is the actual
+ # module that should be loaded instead of mptbase.
+ if module == "mptbase":
+ module= "mptscsih"
+
+ try:
+ vendor_id= long(line_parts[1],16)
+ except ValueError, e:
+ sys.stderr.write( "Skipping line %d in %s " \
+ "(incorrect vendor id format %s)\n" % (line_num,modules_pcimap_path,line_parts[1]))
+ continue
+
+ try:
+ device_id= long(line_parts[2],16)
+ except ValueError, e:
+ sys.stderr.write( "Skipping line %d in %s " \
+ "(incorrect device id format %s)\n" % (line_num,modules_pcimap_path,line_parts[2]))
+ continue
+
+ try:
+ subvendor_id= long(line_parts[3],16)
+ except ValueError, e:
+ sys.stderr.write( "Skipping line %d in %s " \
+ "(incorrect subvendor id format %s)\n" % (line_num,modules_pcimap_path,line_parts[3]))
+ continue
+
+ try:
+ subdevice_id= long(line_parts[4],16)
+ except ValueError, e:
+ sys.stderr.write( "Skipping line %d in %s " \
+ "(incorrect subdevice id format %s)\n" % (line_num,modules_pcimap_path,line_parts[4]))
+ continue
+
+ full_id= (vendor_id, device_id, subvendor_id, subdevice_id)
+ if not all_modules.has_key(module):
+ # normally shouldn't get here, as the list is
+ # prepopulated with all the built modules
+
+ # XXX we probably shouldn't be doing this at all
+ all_modules[module] = [full_id]
+ else:
+ all_modules[module].append(full_id)
+
+ if all_pci_ids.has_key(full_id):
+ # conflict as there are multiple modules that support
+ # particular pci device
+ all_pci_ids[full_id].append(module)
+ else:
+ all_pci_ids[full_id]= [module]
+
+ pcimap_file.close()
+
+ # parse pcitable, add any more ids for the devices
+ # We make the (potentially risky) assumption that pcitable contains
+ # only unique (vendor,device,subvendor,subdevice) entries.
+ line_num= 0
+ for line in pcitable_file:
+ line_num= line_num+1
+
+ # skip blank lines, or lines that begin with # (comments)
+ line= string.strip(line)
+ if len(line) == 0:
+ continue
+
+ if line[0] == "#":
+ continue
+
+ line_parts= string.split(line)
+ if line_parts is None or len(line_parts) <= 2:
+ sys.stderr.write( "Skipping line %d in pcitable " \
+ "(incorrect format 1)\n" % line_num )
+ continue
+
+ # vendor id is always the first field, device the second. also,
+ # strip off first two chars (the 0x)
+ try:
+ vendor_id= long(line_parts[0],16)
+ except ValueError, e:
+ sys.stderr.write( "Skipping vendor_id %s in %s on line %d\n" \
+ % (line_parts[0],pcitable_path,line_num))
+ continue
+
+ try:
+ device_id= long(line_parts[1],16)
+ except ValueError, e:
+ sys.stderr.write( "Skipping device %s in %s on line %d\n" \
+ % (line_parts[1],pcitable_path,line_num))
+ continue
+
+ # if the first char of the third field is a double
+ # quote, the third field is a module, else if the first
+ # char of the third field is a 0 (zero), the fifth field is
+ # the module name. it would nice if there was any easy way
+ # to split a string on spaces, but recognize quoted strings,
+ # so they wouldn't be split up. that is the reason for this wierd check
+ if line_parts[2][0] == '"':
+ module= line_parts[2]
+
+ subvendor_id=PCI_ANY
+ subdevice_id=PCI_ANY
+ elif line_parts[2][0] == '0':
+ try:
+ module= line_parts[4]
+ except ValueError, e:
+ sys.stderr.write( "Skipping line %d in pcitable " \
+ "(incorrect format 2)\n" % line_num )
+ continue
+ try:
+ subvendor_id= long(line_parts[2],16)
+ except ValueError, e:
+ sys.stderr.write( "Skipping line %d in pcitable " \
+ "(incorrect format 2a)\n" % line_num )
+ continue
+
+ try:
+ subdevice_id= long(line_parts[3],16)
+ except ValueError, e:
+ sys.stderr.write( "Skipping line %d in pcitable " \
+ "(incorrect format 2b)\n" % line_num )
+
+ else:
+ sys.stderr.write( "Skipping line %d in pcitable " \
+ "(incorrect format 3)\n" % line_num )
+ continue
+
+ # remove the first and last char of module (quote marks)
+ module= module[1:]
+ module= module[:len(module)-1]
+
+ full_id= (vendor_id, device_id, subvendor_id, subdevice_id)
+
+ if not all_modules.has_key(module):
+ # Do not process any modules listed in pcitable for which
+ # we do not have a prebuilt module.
+ continue
+
+ if not full_id in all_modules[module]:
+ all_modules[module].append(full_id)
+
+ if all_pci_ids.has_key(full_id):
+ if not module in all_pci_ids[full_id]:
+ all_pci_ids[full_id].append(module)
+
+ # check if there are duplicate mappings between modules
+ # and full_ids
+ if len(all_pci_ids[full_id])>1:
+ # collect the set of modules that are different than what
+ # is listed in the pcitables file
+ other_modules = []
+ for other_module in all_pci_ids[full_id]:
+ if other_module != module:
+ other_modules.append(other_module)
+
+ # remove full_id from the set of other modules in all_modules {}
+ for other_module in other_modules:
+ all_modules[other_module].remove(full_id)
+
+ # ensure that there is only one full_id -> module
+ all_pci_ids[full_id] = [module]
+
+ else:
+ all_pci_ids[full_id] = [module]
+
+ pcitable_file.close()
+
+ return (all_pci_ids,all_modules)
+
+if __name__ == "__main__":
+ def usage():
+ print( "\nUsage:" )
+ print( "%s <modules.dep> <modules.pcimap> " \
+ "<pcitable> [<output>]" % sys.argv[0] )
+ print( "" )
+
+ if len(sys.argv) < 4:
+ usage()
+ sys.exit(1)
+
+
+ if len(sys.argv) > 4:
+ output_file_name= sys.argv[4]
+ try:
+ output_file= file(output_file_name,"w")
+ except IOError:
+ sys.stderr.write( "Unable to open %s for writing.\n" % output_file )
+ sys.exit(1)
+ else:
+ output_file= sys.stdout
+
+
+ (all_pci_ids,all_modules)=merge_files( sys.argv[1],
+ sys.argv[2],
+ sys.argv[3] )
+ if all_modules is not None:
+ for module in all_modules.keys():
+ pci_ids = all_modules[module]
+ if len(pci_ids)>0:
+ output_file.write("%s" % module)
+ for pci_id in pci_ids:
+ output_file.write(" %x:%x:%x:%x" % pci_id)
+ output_file.write(" \n")
+ else:
+ sys.stderr.write( "Unable to list modules.\n" )
+
+ output_file.close()
pass
if not sshd_started:
+ # NOTE: these commands hang if ssh_host_*_key files exist, b/c
+ # ssh-keygen asks for user input to confirm the overwrite.
+ # could fix this with "echo 'y' | "
log.write( "Creating ssh host keys\n" )
utils.makedirs( ssh_dir )
# Copyright (c) 2003 Intel Corporation
# All rights reserved.
#
-# Copyright (c) 2004-2006 The Trustees of Princeton University
+# Copyright (c) 2004-2008 The Trustees of Princeton University
# All rights reserved.
-# expected /proc/partitions format
-
-#----------------------------------------------------
-#major minor #blocks name
-#
-#3 0 40017915 hda
-#3 1 208813 hda1
-#3 2 20482875 hda2
-#3 3 522112 hda3
-#3 4 18804082 hda4
-#----------------------------------------------------
-
-
-import string
-import sys
-import os
-import popen2
-import re
-import errno
-import ModelOptions
-import pypciscan
-import pypcimap
-from Exceptions import *
-
-"""
-a utility class for finding and returning information about
-block devices, memory, and other hardware on the system
-"""
-
-PROC_MEMINFO_PATH= "/proc/meminfo"
-PROC_PARTITIONS_PATH= "/proc/partitions"
-
-# set when the sfdisk -l <dev> trick has been done to make
-# all devices show up
-DEVICES_SCANNED_FLAG= "/tmp/devices_scanned"
-
-# a /proc/partitions block is 1024 bytes
-# a GB to a HDD manufacturer is 10^9 bytes
-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_BASE_CLASS_NETWORK=0x02L
-PCI_BASE_CLASS_STORAGE=0x01L
-
-PCI_ANY=0xffffffffL
-
-def get_total_phsyical_mem(vars = {}, log = sys.stderr):
- """
- return the total physical memory of the machine, in kilobytes.
-
- Return None if /proc/meminfo not readable.
- """
-
- try:
- meminfo_file= file(PROC_MEMINFO_PATH,"r")
- except IOError, e:
- return
-
- total_memory= None
-
- for line in meminfo_file:
-
- try:
- (fieldname,value)= string.split(line,":")
- except ValueError, e:
- # this will happen for lines that don't have two values
- # (like the first line on 2.4 kernels)
- continue
-
- fieldname= string.strip(fieldname)
- value= string.strip(value)
-
- if fieldname == "MemTotal":
- try:
- (total_memory,units)= string.split(value)
- except ValueError, e:
- return
-
- if total_memory == "" or total_memory == None or \
- units == "" or units == None:
- return
-
- if string.lower(units) != "kb":
- return
-
- try:
- total_memory= int(total_memory)
- except ValueError, e:
- return
-
- break
-
- meminfo_file.close()
- return total_memory
-
-def get_block_device_list(vars = {}, log = sys.stderr):
- """
- get a list of block devices from this system.
- return an associative array, where the device name
- (full /dev/device path) is the key, and the value
- is a tuple of (major,minor,numblocks,gb_size,readonly)
- """
-
- # make sure we can access to the files/directories in /proc
- if not os.access(PROC_PARTITIONS_PATH, os.F_OK):
- return None
-
- # 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'):
- for blk_num in map ( \
- lambda x: chr(x), range(ord('a'),ord('z')+1)):
- devicename="%s%c" % (blk_prefix, blk_num)
- valid_blk_names[devicename]=None
-
- # add in valid scsi raid block device names
- for M in range(0,1+1):
- for N in range(0,7+1):
- 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):
-
- # this is ugly. under devfs, device
- # entries in /dev/scsi/.. and /dev/ide/...
- # don't show up until you attempt to read
- # from the associated device at /dev (/dev/sda).
- # 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.
- devicenames = valid_blk_names.keys()
- devicenames.sort()
- for devicename in devicenames:
- os.system( "sfdisk -l /dev/%s > /dev/null 2>&1" % devicename )
-
- # touch file
- fb = open(DEVICES_SCANNED_FLAG,"w")
- fb.close()
-
- devicelist= {}
-
- partitions_file= file(PROC_PARTITIONS_PATH,"r")
- line_count= 0
- for line in partitions_file:
- line_count= line_count + 1
-
- # skip the first two lines always
- if line_count < 2:
- continue
-
- parts= string.split(line)
-
- if len(parts) < 4:
- continue
-
- device= parts[3]
-
- # skip and ignore any partitions
- if not valid_blk_names.has_key(device):
- continue
-
- try:
- major= int(parts[0])
- minor= int(parts[1])
- blocks= int(parts[2])
- except ValueError, err:
- continue
-
- gb_size= blocks/BLOCKS_PER_GB
-
- # check to see if the blk device is readonly
- try:
- # can we write to it?
- dev_name= "/dev/%s" % device
- fb = open(dev_name,"w")
- fb.close()
- readonly=False
- except IOError, e:
- # check if EROFS errno
- if errno.errorcode.get(e.errno,None) == 'EROFS':
- readonly=True
- else:
- # got some other errno, pretend device is readonly
- readonly=True
-
- devicelist[dev_name]= (major,minor,blocks,gb_size,readonly)
-
- return devicelist
-
-
-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 file must exist and is used:
- <install_root>/lib/modules/(first entry if kernel_version unspecified)/modules.pcimap
-
- 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.
- """
-
- if not vars.has_key("SYSIMG_PATH"):
- vars["SYSIMG_PATH"]="/"
- SYSIMG_PATH=vars["SYSIMG_PATH"]
-
- if not vars.has_key("NODE_MODEL_OPTIONS"):
- vars["NODE_MODEL_OPTIONS"] = 0;
-
- initrd, kernel_version = getKernelVersion(vars, log)
-
- # get the kernel version we are assuming
- if kernel_version is None:
- try:
- kernel_version= os.listdir( "%s/lib/modules/" % SYSIMG_PATH )
- except OSError, e:
- return
-
- if len(kernel_version) == 0:
- return
-
- if len(kernel_version) > 1:
- print( "WARNING: We may be returning modules for the wrong kernel." )
-
- kernel_version= kernel_version[0]
-
- print( "Using kernel version %s" % kernel_version )
-
- # test to make sure the file we need is present
- modules_pcimap_path = "%s/lib/modules/%s/modules.pcimap" % \
- (SYSIMG_PATH,kernel_version)
- if not os.access(modules_pcimap_path,os.R_OK):
- print( "Unable to read %s" % path )
- return
-
- pcimap = pypcimap.PCIMap(modules_pcimap_path)
-
- # this is the actual data structure we return
- system_mods= {}
-
- # these are the lists that will be in system_mods
- network_mods= []
- scsi_mods= []
-
- # XXX: this is really similar to what BootCD/conf_files/pl_hwinit does. merge?
- pcidevs = pypciscan.get_devices()
-
- for (slot, dev) in pcidevs.iteritems():
- base = (dev[4] & 0xff0000) >> 16
- if base not in (PCI_BASE_CLASS_STORAGE,
- PCI_BASE_CLASS_NETWORK):
- continue
-
- modules = pcimap.get(dev)
- 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
-
- return system_mods
-
-
-def getKernelVersion( vars = {} , log = sys.stderr):
- # make sure we have the variables we need
- try:
- SYSIMG_PATH= vars["SYSIMG_PATH"]
- if SYSIMG_PATH == "":
- raise ValueError, "SYSIMG_PATH"
-
- NODE_MODEL_OPTIONS=vars["NODE_MODEL_OPTIONS"]
- except KeyError, var:
- raise BootManagerException, "Missing variable in vars: %s\n" % var
- except ValueError, var:
- raise BootManagerException, "Variable in vars, shouldn't be: %s\n" % var
-
- option = ''
- if NODE_MODEL_OPTIONS & ModelOptions.SMP:
- option = 'smp'
- try:
- os.stat("%s/boot/kernel-boot%s" % (SYSIMG_PATH,option))
- os.stat("%s/boot/initrd-boot%s" % (SYSIMG_PATH,option))
- except OSError, e:
- # smp kernel is not there; remove option from modeloptions
- # such that the rest of the code base thinks we are just
- # using the base kernel.
- NODE_MODEL_OPTIONS = NODE_MODEL_OPTIONS & ~ModelOptions.SMP
- vars["NODE_MODEL_OPTIONS"] = NODE_MODEL_OPTIONS
- log.write( "WARNING: Couldn't locate smp kernel.\n")
- option = ''
- try:
- initrd= os.readlink( "%s/boot/initrd-boot%s" % (SYSIMG_PATH,option) )
- kernel_version= initrd.replace("initrd-", "").replace(".img", "")
- except OSError, e:
- initrd = None
- kernel_version = None
-
- return (initrd, kernel_version)
-
-
-if __name__ == "__main__":
- devices= get_block_device_list()
- print "block devices detected:"
- if not devices:
- print "no devices found!"
- else:
- for dev in devices.keys():
- print "%s %s" % (dev, repr(devices[dev]))
-
-
- print ""
- memory= get_total_phsyical_mem()
- if not memory:
- print "unable to read /proc/meminfo for memory"
- else:
- print "total physical memory: %d kb" % memory
-
-
- print ""
-
- kernel_version = None
- if len(sys.argv) > 2:
- kernel_version = sys.argv[1]
-
- modules= get_system_modules()
- 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
-
+try:
+ from systeminfo_34 import *
+except:
+ from systeminfo_30 import *
--- /dev/null
+#!/usr/bin/python2
+
+# Copyright (c) 2003 Intel Corporation
+# All rights reserved.
+#
+# Copyright (c) 2004-2006 The Trustees of Princeton University
+# All rights reserved.
+# expected /proc/partitions format
+
+
+#----------------------------------------------------
+#major minor #blocks name
+#
+#3 0 40017915 hda
+#3 1 208813 hda1
+#3 2 20482875 hda2
+#3 3 522112 hda3
+#3 4 18804082 hda4
+#----------------------------------------------------
+
+
+import string
+import sys
+import os
+import popen2
+import merge_hw_tables
+import re
+import errno
+import ModelOptions
+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
+"""
+
+PROC_MEMINFO_PATH= "/proc/meminfo"
+PROC_PARTITIONS_PATH= "/proc/partitions"
+
+# set when the sfdisk -l <dev> trick has been done to make
+# all devices show up
+DEVICES_SCANNED_FLAG= "/tmp/devices_scanned"
+
+# a /proc/partitions block is 1024 bytes
+# a GB to a HDD manufacturer is 10^9 bytes
+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_SATA=0x0106L
+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(vars = {}, log = sys.stderr):
+ """
+ return the total physical memory of the machine, in kilobytes.
+
+ Return None if /proc/meminfo not readable.
+ """
+
+ try:
+ meminfo_file= file(PROC_MEMINFO_PATH,"r")
+ except IOError, e:
+ return
+
+ total_memory= None
+
+ for line in meminfo_file:
+
+ try:
+ (fieldname,value)= string.split(line,":")
+ except ValueError, e:
+ # this will happen for lines that don't have two values
+ # (like the first line on 2.4 kernels)
+ continue
+
+ fieldname= string.strip(fieldname)
+ value= string.strip(value)
+
+ if fieldname == "MemTotal":
+ try:
+ (total_memory,units)= string.split(value)
+ except ValueError, e:
+ return
+
+ if total_memory == "" or total_memory == None or \
+ units == "" or units == None:
+ return
+
+ if string.lower(units) != "kb":
+ return
+
+ try:
+ total_memory= int(total_memory)
+ except ValueError, e:
+ return
+
+ break
+
+ meminfo_file.close()
+ return total_memory
+
+def get_block_device_list(vars = {}, log = sys.stderr):
+ """
+ get a list of block devices from this system.
+ return an associative array, where the device name
+ (full /dev/device path) is the key, and the value
+ is a tuple of (major,minor,numblocks,gb_size,readonly)
+ """
+
+ # make sure we can access to the files/directories in /proc
+ if not os.access(PROC_PARTITIONS_PATH, os.F_OK):
+ return None
+
+ # 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'):
+ for blk_num in map ( \
+ lambda x: chr(x), range(ord('a'),ord('z')+1)):
+ devicename="%s%c" % (blk_prefix, blk_num)
+ valid_blk_names[devicename]=None
+
+ # add in valid scsi raid block device names
+ for M in range(0,1+1):
+ for N in range(0,7+1):
+ 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):
+
+ # this is ugly. under devfs, device
+ # entries in /dev/scsi/.. and /dev/ide/...
+ # don't show up until you attempt to read
+ # from the associated device at /dev (/dev/sda).
+ # 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.
+ devicenames = valid_blk_names.keys()
+ devicenames.sort()
+ for devicename in devicenames:
+ os.system( "sfdisk -l /dev/%s > /dev/null 2>&1" % devicename )
+
+ # touch file
+ fb = open(DEVICES_SCANNED_FLAG,"w")
+ fb.close()
+
+ devicelist= {}
+
+ partitions_file= file(PROC_PARTITIONS_PATH,"r")
+ line_count= 0
+ for line in partitions_file:
+ line_count= line_count + 1
+
+ # skip the first two lines always
+ if line_count < 2:
+ continue
+
+ parts= string.split(line)
+
+ if len(parts) < 4:
+ continue
+
+ device= parts[3]
+
+ # skip and ignore any partitions
+ if not valid_blk_names.has_key(device):
+ continue
+
+ try:
+ major= int(parts[0])
+ minor= int(parts[1])
+ blocks= int(parts[2])
+ except ValueError, err:
+ continue
+
+ gb_size= blocks/BLOCKS_PER_GB
+
+ # check to see if the blk device is readonly
+ try:
+ # can we write to it?
+ dev_name= "/dev/%s" % device
+ fb = open(dev_name,"w")
+ fb.close()
+ readonly=False
+ except IOError, e:
+ # check if EROFS errno
+ if errno.errorcode.get(e.errno,None) == 'EROFS':
+ readonly=True
+ else:
+ # got some other errno, pretend device is readonly
+ readonly=True
+
+ devicelist[dev_name]= (major,minor,blocks,gb_size,readonly)
+
+ return devicelist
+
+
+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:
+ <install_root>/usr/share/hwdata/pcitable
+ <install_root>/lib/modules/(first entry if kernel_version unspecified)/modules.pcimap
+ <install_root>/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
+ /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.
+ """
+
+ if not vars.has_key("SYSIMG_PATH"):
+ vars["SYSIMG_PATH"]="/"
+ SYSIMG_PATH=vars["SYSIMG_PATH"]
+
+ if not vars.has_key("NODE_MODEL_OPTIONS"):
+ vars["NODE_MODEL_OPTIONS"] = 0;
+
+ initrd, kernel_version = getKernelVersion(vars, log)
+
+ # get the kernel version we are assuming
+ if kernel_version is None:
+ try:
+ kernel_version= os.listdir( "%s/lib/modules/" % SYSIMG_PATH )
+ except OSError, e:
+ return
+
+ if len(kernel_version) == 0:
+ return
+
+ if len(kernel_version) > 1:
+ print( "WARNING: We may be returning modules for the wrong kernel." )
+
+ 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/%s/pcitable" % (SYSIMG_PATH,hwdatapath)
+ 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." )
+ return
+
+ # this is the actual data structure we return
+ system_mods= {}
+
+ # these are the lists that will be in system_mods
+ network_mods= []
+ scsi_mods= []
+
+
+ # 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_SATA,
+ 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_SATA,
+ PCI_CLASS_STORAGE_RAID,
+ PCI_CLASS_STORAGE_OTHER,
+ PCI_CLASS_STORAGE_IDE):
+ scsi_mods.append(module[0])
+
+ # XXX ata_piix and ahci both claim 8086:2652 and 8086:2653,
+ # and it is usually a non-visible BIOS option that decides
+ # which is appropriate. Just load both.
+ if vendorid == 0x8086 and (deviceid == 0x2652 or deviceid == 0x2653):
+ if module[0] == "ahci":
+ scsi_mods.append("ata_piix")
+ elif module[0] == "ata_piix":
+ scsi_mods.append("ahci")
+ else:
+ print "not network or scsi: 0x%x" % classid
+ break
+
+ system_mods[MODULE_CLASS_SCSI]= scsi_mods
+ system_mods[MODULE_CLASS_NETWORK]= network_mods
+
+ return system_mods
+
+
+def getKernelVersion( vars = {} , log = sys.stderr):
+ # make sure we have the variables we need
+ try:
+ SYSIMG_PATH= vars["SYSIMG_PATH"]
+ if SYSIMG_PATH == "":
+ raise ValueError, "SYSIMG_PATH"
+
+ NODE_MODEL_OPTIONS=vars["NODE_MODEL_OPTIONS"]
+ except KeyError, var:
+ raise BootManagerException, "Missing variable in vars: %s\n" % var
+ except ValueError, var:
+ raise BootManagerException, "Variable in vars, shouldn't be: %s\n" % var
+
+ option = ''
+ if NODE_MODEL_OPTIONS & ModelOptions.SMP:
+ option = 'smp'
+ try:
+ os.stat("%s/boot/kernel-boot%s" % (SYSIMG_PATH,option))
+ os.stat("%s/boot/initrd-boot%s" % (SYSIMG_PATH,option))
+ except OSError, e:
+ # smp kernel is not there; remove option from modeloptions
+ # such that the rest of the code base thinks we are just
+ # using the base kernel.
+ NODE_MODEL_OPTIONS = NODE_MODEL_OPTIONS & ~ModelOptions.SMP
+ vars["NODE_MODEL_OPTIONS"] = NODE_MODEL_OPTIONS
+ log.write( "WARNING: Couldn't locate smp kernel.\n")
+ option = ''
+ try:
+ initrd= os.readlink( "%s/boot/initrd-boot%s" % (SYSIMG_PATH,option) )
+ kernel_version= initrd.replace("initrd-", "").replace(".img", "")
+ except OSError, e:
+ initrd = None
+ kernel_version = None
+
+ return (initrd, kernel_version)
+
+
+if __name__ == "__main__":
+ devices= get_block_device_list()
+ print "block devices detected:"
+ if not devices:
+ print "no devices found!"
+ else:
+ for dev in devices.keys():
+ print "%s %s" % (dev, repr(devices[dev]))
+
+
+ print ""
+ memory= get_total_phsyical_mem()
+ if not memory:
+ print "unable to read /proc/meminfo for memory"
+ else:
+ print "total physical memory: %d kb" % memory
+
+
+ print ""
+
+ kernel_version = None
+ if len(sys.argv) > 2:
+ kernel_version = sys.argv[1]
+
+ modules= get_system_modules()
+ 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
+
--- /dev/null
+#!/usr/bin/python2
+
+# Copyright (c) 2003 Intel Corporation
+# All rights reserved.
+#
+# Copyright (c) 2004-2006 The Trustees of Princeton University
+# All rights reserved.
+# expected /proc/partitions format
+
+
+#----------------------------------------------------
+#major minor #blocks name
+#
+#3 0 40017915 hda
+#3 1 208813 hda1
+#3 2 20482875 hda2
+#3 3 522112 hda3
+#3 4 18804082 hda4
+#----------------------------------------------------
+
+
+import string
+import sys
+import os
+import popen2
+import re
+import errno
+import ModelOptions
+import pypciscan
+import pypcimap
+from Exceptions import *
+
+"""
+a utility class for finding and returning information about
+block devices, memory, and other hardware on the system
+"""
+
+PROC_MEMINFO_PATH= "/proc/meminfo"
+PROC_PARTITIONS_PATH= "/proc/partitions"
+
+# set when the sfdisk -l <dev> trick has been done to make
+# all devices show up
+DEVICES_SCANNED_FLAG= "/tmp/devices_scanned"
+
+# a /proc/partitions block is 1024 bytes
+# a GB to a HDD manufacturer is 10^9 bytes
+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_BASE_CLASS_NETWORK=0x02L
+PCI_BASE_CLASS_STORAGE=0x01L
+
+PCI_ANY=0xffffffffL
+
+def get_total_phsyical_mem(vars = {}, log = sys.stderr):
+ """
+ return the total physical memory of the machine, in kilobytes.
+
+ Return None if /proc/meminfo not readable.
+ """
+
+ try:
+ meminfo_file= file(PROC_MEMINFO_PATH,"r")
+ except IOError, e:
+ return
+
+ total_memory= None
+
+ for line in meminfo_file:
+
+ try:
+ (fieldname,value)= string.split(line,":")
+ except ValueError, e:
+ # this will happen for lines that don't have two values
+ # (like the first line on 2.4 kernels)
+ continue
+
+ fieldname= string.strip(fieldname)
+ value= string.strip(value)
+
+ if fieldname == "MemTotal":
+ try:
+ (total_memory,units)= string.split(value)
+ except ValueError, e:
+ return
+
+ if total_memory == "" or total_memory == None or \
+ units == "" or units == None:
+ return
+
+ if string.lower(units) != "kb":
+ return
+
+ try:
+ total_memory= int(total_memory)
+ except ValueError, e:
+ return
+
+ break
+
+ meminfo_file.close()
+ return total_memory
+
+def get_block_device_list(vars = {}, log = sys.stderr):
+ """
+ get a list of block devices from this system.
+ return an associative array, where the device name
+ (full /dev/device path) is the key, and the value
+ is a tuple of (major,minor,numblocks,gb_size,readonly)
+ """
+
+ # make sure we can access to the files/directories in /proc
+ if not os.access(PROC_PARTITIONS_PATH, os.F_OK):
+ return None
+
+ # 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'):
+ for blk_num in map ( \
+ lambda x: chr(x), range(ord('a'),ord('z')+1)):
+ devicename="%s%c" % (blk_prefix, blk_num)
+ valid_blk_names[devicename]=None
+
+ # add in valid scsi raid block device names
+ for M in range(0,1+1):
+ for N in range(0,7+1):
+ 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):
+
+ # this is ugly. under devfs, device
+ # entries in /dev/scsi/.. and /dev/ide/...
+ # don't show up until you attempt to read
+ # from the associated device at /dev (/dev/sda).
+ # 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.
+ devicenames = valid_blk_names.keys()
+ devicenames.sort()
+ for devicename in devicenames:
+ os.system( "sfdisk -l /dev/%s > /dev/null 2>&1" % devicename )
+
+ # touch file
+ fb = open(DEVICES_SCANNED_FLAG,"w")
+ fb.close()
+
+ devicelist= {}
+
+ partitions_file= file(PROC_PARTITIONS_PATH,"r")
+ line_count= 0
+ for line in partitions_file:
+ line_count= line_count + 1
+
+ # skip the first two lines always
+ if line_count < 2:
+ continue
+
+ parts= string.split(line)
+
+ if len(parts) < 4:
+ continue
+
+ device= parts[3]
+
+ # skip and ignore any partitions
+ if not valid_blk_names.has_key(device):
+ continue
+
+ try:
+ major= int(parts[0])
+ minor= int(parts[1])
+ blocks= int(parts[2])
+ except ValueError, err:
+ continue
+
+ gb_size= blocks/BLOCKS_PER_GB
+
+ # check to see if the blk device is readonly
+ try:
+ # can we write to it?
+ dev_name= "/dev/%s" % device
+ fb = open(dev_name,"w")
+ fb.close()
+ readonly=False
+ except IOError, e:
+ # check if EROFS errno
+ if errno.errorcode.get(e.errno,None) == 'EROFS':
+ readonly=True
+ else:
+ # got some other errno, pretend device is readonly
+ readonly=True
+
+ devicelist[dev_name]= (major,minor,blocks,gb_size,readonly)
+
+ return devicelist
+
+
+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 file must exist and is used:
+ <install_root>/lib/modules/(first entry if kernel_version unspecified)/modules.pcimap
+
+ 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.
+ """
+
+ if not vars.has_key("SYSIMG_PATH"):
+ vars["SYSIMG_PATH"]="/"
+ SYSIMG_PATH=vars["SYSIMG_PATH"]
+
+ if not vars.has_key("NODE_MODEL_OPTIONS"):
+ vars["NODE_MODEL_OPTIONS"] = 0;
+
+ initrd, kernel_version = getKernelVersion(vars, log)
+
+ # get the kernel version we are assuming
+ if kernel_version is None:
+ try:
+ kernel_version= os.listdir( "%s/lib/modules/" % SYSIMG_PATH )
+ except OSError, e:
+ return
+
+ if len(kernel_version) == 0:
+ return
+
+ if len(kernel_version) > 1:
+ print( "WARNING: We may be returning modules for the wrong kernel." )
+
+ kernel_version= kernel_version[0]
+
+ print( "Using kernel version %s" % kernel_version )
+
+ # test to make sure the file we need is present
+ modules_pcimap_path = "%s/lib/modules/%s/modules.pcimap" % \
+ (SYSIMG_PATH,kernel_version)
+ if not os.access(modules_pcimap_path,os.R_OK):
+ print( "Unable to read %s" % path )
+ return
+
+ pcimap = pypcimap.PCIMap(modules_pcimap_path)
+
+ # this is the actual data structure we return
+ system_mods= {}
+
+ # these are the lists that will be in system_mods
+ network_mods= []
+ scsi_mods= []
+
+ # XXX: this is really similar to what BootCD/conf_files/pl_hwinit does. merge?
+ pcidevs = pypciscan.get_devices()
+
+ for (slot, dev) in pcidevs.iteritems():
+ base = (dev[4] & 0xff0000) >> 16
+ if base not in (PCI_BASE_CLASS_STORAGE,
+ PCI_BASE_CLASS_NETWORK):
+ continue
+
+ modules = pcimap.get(dev)
+ 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
+
+ return system_mods
+
+
+def getKernelVersion( vars = {} , log = sys.stderr):
+ # make sure we have the variables we need
+ try:
+ SYSIMG_PATH= vars["SYSIMG_PATH"]
+ if SYSIMG_PATH == "":
+ raise ValueError, "SYSIMG_PATH"
+
+ NODE_MODEL_OPTIONS=vars["NODE_MODEL_OPTIONS"]
+ except KeyError, var:
+ raise BootManagerException, "Missing variable in vars: %s\n" % var
+ except ValueError, var:
+ raise BootManagerException, "Variable in vars, shouldn't be: %s\n" % var
+
+ option = ''
+ if NODE_MODEL_OPTIONS & ModelOptions.SMP:
+ option = 'smp'
+ try:
+ os.stat("%s/boot/kernel-boot%s" % (SYSIMG_PATH,option))
+ os.stat("%s/boot/initrd-boot%s" % (SYSIMG_PATH,option))
+ except OSError, e:
+ # smp kernel is not there; remove option from modeloptions
+ # such that the rest of the code base thinks we are just
+ # using the base kernel.
+ NODE_MODEL_OPTIONS = NODE_MODEL_OPTIONS & ~ModelOptions.SMP
+ vars["NODE_MODEL_OPTIONS"] = NODE_MODEL_OPTIONS
+ log.write( "WARNING: Couldn't locate smp kernel.\n")
+ option = ''
+ try:
+ initrd= os.readlink( "%s/boot/initrd-boot%s" % (SYSIMG_PATH,option) )
+ kernel_version= initrd.replace("initrd-", "").replace(".img", "")
+ except OSError, e:
+ initrd = None
+ kernel_version = None
+
+ return (initrd, kernel_version)
+
+
+if __name__ == "__main__":
+ devices= get_block_device_list()
+ print "block devices detected:"
+ if not devices:
+ print "no devices found!"
+ else:
+ for dev in devices.keys():
+ print "%s %s" % (dev, repr(devices[dev]))
+
+
+ print ""
+ memory= get_total_phsyical_mem()
+ if not memory:
+ print "unable to read /proc/meminfo for memory"
+ else:
+ print "total physical memory: %d kb" % memory
+
+
+ print ""
+
+ kernel_version = None
+ if len(sys.argv) > 2:
+ kernel_version = sys.argv[1]
+
+ modules= get_system_modules()
+ 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
+