import os
import popen2
import merge_hw_tables
+import re
+import errno
hwdatapath = "usr/share/hwdata"
class systeminfo:
if not os.access(self.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
# only do this once every system boot
if not os.access(self.DEVICES_SCANNED_FLAG, os.R_OK):
# 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.
- for dev_prefix in ('sd','hd'):
- block_dev_num= 0
- while block_dev_num < 10:
- if block_dev_num < 26:
- devicename= "/dev/%s%c" % \
- (dev_prefix, chr(ord('a')+block_dev_num))
- else:
- devicename= "/dev/%s%c%c" % \
- ( dev_prefix,
- chr(ord('a')+((block_dev_num/26)-1)),
- chr(ord('a')+(block_dev_num%26)) )
-
- os.system( "sfdisk -l %s > /dev/null 2>&1" % devicename )
- block_dev_num = block_dev_num + 1
-
- additional_scan_devices= ("/dev/cciss/c0d0p", "/dev/cciss/c0d1p",
- "/dev/cciss/c0d2p", "/dev/cciss/c0d3p",
- "/dev/cciss/c0d4p", "/dev/cciss/c0d5p",
- "/dev/cciss/c0d6p", "/dev/cciss/c0d7p",
- "/dev/cciss/c1d0p", "/dev/cciss/c1d1p",
- "/dev/cciss/c1d2p", "/dev/cciss/c1d3p",
- "/dev/cciss/c1d4p", "/dev/cciss/c1d5p",
- "/dev/cciss/c1d6p", "/dev/cciss/c1d7p",)
-
- for devicename in additional_scan_devices:
- os.system( "sfdisk -l %s > /dev/null 2>&1" % devicename )
+ devicenames = valid_blk_names.keys()
+ devicenames.sort()
+ for devicename in devicenames:
+ os.system( "sfdisk -l /dev/%s > /dev/null 2>&1" % devicename )
- os.system( "touch %s" % self.DEVICES_SCANNED_FLAG )
-
+ # touch file
+ fb = open(self.DEVICES_SCANNED_FLAG,"w")
+ fb.close()
devicelist= {}
partitions_file= file(self.PROC_PARTITIONS_PATH,"r")
line_count= 0
-
for line in partitions_file:
line_count= line_count + 1
continue
device= parts[3]
-
- dev_name= "/dev/%s" % device
+ # skip and ignore any partitions
+ if not valid_blk_names.has_key(device):
+ continue
+
try:
major= int(parts[0])
minor= int(parts[1])
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 <disk> to get the readonly flag;
- # if this fails, assume it isn't read only
- readonly= 0
-
- hdparm_cmd = popen2.Popen3("hdparm %s 2> /dev/null" % dev_name)
- status= hdparm_cmd.wait()
-
- if os.WIFEXITED(status) and os.WEXITSTATUS(status) == 0:
- try:
- hdparm_output= hdparm_cmd.fromchild.read()
- hdparm_cmd= None
-
- # parse the output of hdparm, the lines we are interested
- # in look
- # like:
- #
- # readonly = 0 (off)
- #
-
- for line in string.split(hdparm_output,"\n"):
-
- line= string.strip(line)
- if line == "":
- continue
-
- line_parts= string.split(line,"=")
- if len(line_parts) < 2:
- continue
-
- name= string.strip(line_parts[0])
-
- if name == "readonly":
- value= string.strip(line_parts[1])
- if len(value) == 0:
- break
-
- if value[0] == "1":
- readonly= 1
- break
-
- except IOError:
- pass
+ # 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
# search for the corresponding driver from the dictionary
# generated by merge_hw_tables
for line in lspci_prog.fromchild:
- if string.strip(line) == "":
- continue
-
- parts= string.split(line)
-
+ # 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:
- classid= self.remove_quotes(parts[2])
- classid= long(classid,16)
- except IndexError:
- print( "Skipping invalid classid:", string.strip(line) )
+ 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
- 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_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])
- vendorid= long(vendorid,16)
- except IndexError:
- print( "Skipping invalid vendorid:", string.strip(line) )
- continue
- except ValueError, e:
- print( "Skipping invalid vendorid:", string.strip(line) )
- continue
-
- # parse in deviceid
+ # Device may have a subvendorid and subdeviceid
try:
- deviceid= self.remove_quotes(parts[4])
- deviceid= long(deviceid,16)
- except IndexError:
- print( "Skipping invalid deviceid:", string.strip(line) )
- continue
- 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
+ subvendorid = long(parts[4], 16)
+ subdeviceid = long(parts[5], 16)
+ except:
+ subvendorid = self.PCI_ANY
+ subdeviceid = self.PCI_ANY
# search for driver that most closely matches the full_id
# to drivers that can handle any subvendor/subdevice
self.PCI_CLASS_STORAGE_OTHER,
self.PCI_CLASS_STORAGE_IDE):
scsi_mods.append(module[0])
+ else:
+ print "not network or scsi: 0x%x" % classid
break
system_mods[self.MODULE_CLASS_SCSI]= scsi_mods