diff options
Diffstat (limited to 'mountconfig/MicroHAL.py')
-rwxr-xr-x | mountconfig/MicroHAL.py | 884 |
1 files changed, 884 insertions, 0 deletions
diff --git a/mountconfig/MicroHAL.py b/mountconfig/MicroHAL.py new file mode 100755 index 0000000..9ce8b83 --- /dev/null +++ b/mountconfig/MicroHAL.py @@ -0,0 +1,884 @@ +#!/usr/bin/python +########################################################################### +# MicroHAL.py - # +# ------------------------------ # +# begin : Tue Oct 30 2004 # +# copyright : (C) 2004 by Simon Edwards # +# email : [email protected] # +# # +########################################################################### +# # +# This program is free software; you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation; either version 2 of the License, or # +# (at your option) any later version. # +# # +########################################################################### + +import os +import os.path +from SimpleCommandRunner import * + +############################################################################ +class MicroHAL__(object): + + # Major device numbers for Linux block devices that support partitions. + partitionblockdevs = [ + 3, # IDE harddisks + 8, # SCSI disks + 13, # 8-bit MFM/RLL/IDE controller + 14, # BIOS harddrive callback support {2.6} + 21, # Acorn MFM hard drive interface + 22, # Second IDE hard disk/CD-ROM interface + 28, # ACSI disk (68k/Atari) + 33, # Third IDE hard disk/CD-ROM interface + 34, # Fourth IDE hard disk/CD-ROM interface + 36, # MCA ESDI hard disk + 44, # Flash Translation Layer (FTL) filesystems + 45, # Parallel port IDE disk devices + 48, # Mylex DAC960 PCI RAID controller; first controller + 49, # Mylex DAC960 PCI RAID controller; second controller + 50, # Mylex DAC960 PCI RAID controller; third controller + 51, # Mylex DAC960 PCI RAID controller; fourth controller + 52, # Mylex DAC960 PCI RAID controller; fifth controller + 53, # Mylex DAC960 PCI RAID controller; sixth controller + 54, # Mylex DAC960 PCI RAID controller; seventh controller + 55, # Mylex DAC960 PCI RAID controller; eigth controller + 56, # Fifth IDE hard disk/CD-ROM interface + 57, # Sixth IDE hard disk/CD-ROM interface + 65, # SCSI disk devices (16-31) + 66, # SCSI disk devices (32-47) + 67, # SCSI disk devices (48-63) + 68, # SCSI disk devices (64-79) + 69, # SCSI disk devices (80-95) + 70, # SCSI disk devices (96-111) + 71, # SCSI disk devices (112-127) + 72, # Compaq Intelligent Drive Array, first controller + 73, # Compaq Intelligent Drive Array, second controller + 74, # Compaq Intelligent Drive Array, third controller + 75, # Compaq Intelligent Drive Array, fourth controller + 76, # Compaq Intelligent Drive Array, fifth controller + 77, # Compaq Intelligent Drive Array, sixth controller + 78, # Compaq Intelligent Drive Array, seventh controller + 79, # Compaq Intelligent Drive Array, eigth controller + 80, # I2O hard disk + 81, # I2O hard disk + 82, # I2O hard disk + 83, # I2O hard disk + 84, # I2O hard disk + 85, # I2O hard disk + 86, # I2O hard disk + 87, # I2O hard disk + 88, # Seventh IDE hard disk/CD-ROM interface + 89, # Eighth IDE hard disk/CD-ROM interface + 90, # Ninth IDE hard disk/CD-ROM interface + 91, # Tenth IDE hard disk/CD-ROM interface + 92, # PPDD encrypted disk driver + 95, # IBM S/390 DASD block storage + 101, # AMI HyperDisk RAID controller + 102, # Compressed block device + 104, # Compaq Next Generation Drive Array, first controller + 105, # Compaq Next Generation Drive Array, second controller + 106, # Compaq Next Generation Drive Array, third controller + 107, # Compaq Next Generation Drive Array, fourth controller + 108, # Compaq Next Generation Drive Array, fifth controller + 109, # Compaq Next Generation Drive Array, sixth controller + 110, # Compaq Next Generation Drive Array, seventh controller + 111, # Compaq Next Generation Drive Array, eigth controller + 112, # IBM iSeries virtual disk + 114, # IDE BIOS powered software RAID interfaces such as the Promise Fastrak + 128, # SCSI disk devices (128-143) + 129, # SCSI disk devices (144-159) + 130, # SCSI disk devices (160-175) + 131, # SCSI disk devices (176-191) + 132, # SCSI disk devices (192-207) + 133, # SCSI disk devices (208-223) + 134, # SCSI disk devices (224-239) + 135, # SCSI disk devices (240-255) + 136, # Mylex DAC960 PCI RAID controller; ninth controller + 137, # Mylex DAC960 PCI RAID controller; tenth controller + 138, # Mylex DAC960 PCI RAID controller; eleventh controller + 139, # Mylex DAC960 PCI RAID controller; twelfth controller + 140, # Mylex DAC960 PCI RAID controller; thirteenth controller + 141, # Mylex DAC960 PCI RAID controller; fourteenth controller + 142, # Mylex DAC960 PCI RAID controller; fifteenth controller + 143, # Mylex DAC960 PCI RAID controller; sixteenth controller + 160, # Promise SX8 8-port SATA Disks on First Controller + 161 # Promise SX8 8-port SATA Disks on Second Controller + ] + + floppydevs = [ + 2, # Floppy disks + 40 # Syquest EZ135 parallel port removable drive + ] + + cdromsdevs = [ + 11, # SCSI CD-ROM devices + 12, # MSCDEX CD-ROM callback support {2.6} + 15, # Sony CDU-31A/CDU-33A CD-ROM + 16, # GoldStar CD-ROM + 17, # Optics Storage CD-ROM + 18, # Sanyo CD-ROM + 20, # Hitachi CD-ROM (under development) + 23, # Mitsumi proprietary CD-ROM + 24, # Sony CDU-535 CD-ROM + 25, # First Matsushita (Panasonic/SoundBlaster) CD-ROM + 26, # Second Matsushita (Panasonic/SoundBlaster) CD-ROM + 27, # Third Matsushita (Panasonic/SoundBlaster) CD-ROM + 28, # Fourth Matsushita (Panasonic/SoundBlaster) CD-ROM + 29, # Aztech/Orchid/Okano/Wearnes CD-ROM + 30, # Philips LMS CM-205 CD-ROM + 32, # Philips LMS CM-206 CD-ROM + 41, # MicroSolutions BackPack parallel port CD-ROM + 46, # Parallel port ATAPI CD-ROM devices + 47, # Parallel port ATAPI disk devices + 48, # Mylex DAC960 PCI RAID controller; first controller + 113 # IBM iSeries virtual CD-ROM + ] + + burnerpacketdevs = [ + 97 # Packet writing for CD/DVD devices + ] + + # We provide a mapping between filesystems and kernelmodules, so filesystems + # that are built as modules can be loaded on demand. (In fact, mountconfig will + # load all filesystem modules needed to be able to mount all fstab entries.) + FilesystemProcDriver = [ + # fstab name, /proc name, kernel module name + ('auto','autofs','autofs4'), + ('iso9660','iso9660','isofs'), + ('nfs','nfsd','nfs') + ] + + ############################################################################ + def __init__(self): + self.devices = None + self.supportedfs = None + self.partitionsizelines = None + + ############################################################################ + def getDevices(self): + if self.devices is None: + self.devices = [] + # Scan through /sys/block for devices. Find out which disks are + # installed and should be shown in the listview. For real + # disks we put a 'group' in the listview and under the group + # we list the partitions, whether they are mounted or not. + # FIXME: Check if sysfs is mounted. + blockdevices = os.listdir("/sys/block") + blockdevices.sort() + + for blockdevice in blockdevices: + # We are looking for block devices that represent hard disks or + # things that have partitions. + # Grab the major device number + fhandle = open(os.path.join("/sys/block",blockdevice,"dev")) + devnumbers = fhandle.read() + fhandle.close() + devnum = int(devnumbers.split(":")[0]) + # Is it on our list of partition devices? + if devnum in MicroHAL.partitionblockdevs: + fulldevice = os.path.join("/dev",blockdevice) + + # Check for removable devices. + fhandle = open(os.path.join("/sys/block",blockdevice,"removable")) + removable = fhandle.read().strip()=="1" + fhandle.close() + + if not removable: + newdisk = Disk() + else: + if os.readlink(os.path.join("/sys/block",blockdevice,"device")).split(os.path.sep)[5].startswith("usb"): + newdisk = USBDisk() + else: + newdisk = RemovableDisk() + newdisk.dev = fulldevice + newdisk.major = devnum + newdisk.removable = removable + newdisk.modelname = self.getModelName(fulldevice) + + if not removable or isinstance(newdisk, USBDisk): + # We have a not removable block device or a USB Disk here. + partitions = os.listdir(os.path.join("/sys/block",blockdevice)) + partitions.sort() + i = 1 + for partition in partitions: + # Look for a partitions device names and not the other + # stuff that lives in the directory. + if partition.startswith(blockdevice): + fullpartition = os.path.join("/dev",partition) + newpartition = Partition() + newpartition.dev = fullpartition + newpartition.size = self.getPartitionSize(fullpartition) + newpartition.num = i + newdisk.partitions.append(newpartition) + i += 1 + self.devices.append(newdisk) + + elif devnum in MicroHAL.cdromsdevs: + fulldevice = os.path.join("/dev",blockdevice) + newdisk = RemovableDisk() + newdisk.dev = fulldevice + newdisk.major = devnum + newdisk.modelname = self.getModelName(fulldevice) + self.devices.append(newdisk) + + elif devnum in MicroHAL.burnerpacketdevs: + fulldevice = os.path.join("/dev",blockdevice) + newdisk = BurnerDisk(self) + newdisk.dev = fulldevice + newdisk.major = devnum + newdisk.modelname = self.getModelName(fulldevice) + + self.devices.append(newdisk) + + return self.devices[:] + + ############################################################################ + def getPartitionSize(self,devicename): + partitionname = os.path.basename(devicename) + + if self.partitionsizelines is None: + fhandle = open('/proc/partitions') + self.partitionsizelines = fhandle.readlines() + fhandle.close() + + i = 0 + for line in self.partitionsizelines: + if i>=2: + (major, minor, blocks, name) = line.split() + if name==partitionname: + blocks = int(blocks) # 1K blocks now. + if blocks<1024: + return str(blocks)+" Kb" + if blocks<1024*1024: + return str(round(float(blocks)/1024.0,1))+" Mb" + blocks /= 1024 + if blocks<1024*1024: + return str(round(float(blocks)/1024.0,1))+" Gb" + blocks /= 1024 + return str(round(float(blocks)/1024.0,1))+" Tb" + i += 1 + return None + + ############################################################################ + def getIDEModel(self,devname): + try: + fhandle = open(os.path.join("/proc/ide",os.path.basename(devname),"model")) + model = fhandle.read() + fhandle.close() + return model.strip() + except (OSError, IOError): + return None + + ############################################################################ + def getSCSIModel(self,devname): + try: + fhandle_model = open(os.path.join("/sys/block",os.path.basename(devname),"device/model")) + fhandle_vendor = open(os.path.join("/sys/block",os.path.basename(devname),"device/vendor")) + model = fhandle_model.read()[:-1] + vendor = fhandle_vendor.read()[:-1] + fhandle_model.close() + fhandle_vendor.close() + except (OSError, IOError): + pass + if len(model) + len(vendor) == 0: + return None + return vendor + " " + model + + ############################################################################ + def getModelName(self,devname): + modelname = self.getIDEModel(devname) + if modelname is None: + modelname = self.getSCSIModel(devname) + if modelname is None: + modelname = devname + return " '"+modelname+"'" + + ############################################################################ + def getSupportedFileSystems(self): + if self.supportedfs is None: + if os.path.isfile("/proc/filesystems"): + fhandle = open("/proc/filesystems") + self.supportedfs = [] + for fs in fhandle.readlines(): + try: + self.supportedfs.append(fs.strip().split()[1]) + except IndexError: + self.supportedfs.append(fs.strip().split()[0]) + # The following filesystems aren't found there, but usually they are + # supported. + self.supportedfs.extend(('swap','shm')) + return self.supportedfs[:] + + ############################################################################ + def isSupportedFileSystem(self,fs): + # Look up the /proc and kernel driver name for the given filesystem type. + module = fs + proc = fs + for entry in self.FilesystemProcDriver: + if entry[0]==fs: + proc = entry[1] + module = entry[2] + + if proc not in self.getSupportedFileSystems(): + # The filesystem is not supported by the running kernel, + # but it might be built as module, so we try to load that. + retval, msg = SimpleCommandRunner().run(["/sbin/modprobe",module]) + if retval > 0: + print msg + print "Couldn't load driver " + module + " for filesystem " + fs + # Force refresh of list of supported filesystems + self.supportedfs = None + return proc in self.getSupportedFileSystems() + +############################################################################ +class Device(object): + def __init__(self): + self.dev = None + self.major = None + self.removable = None + self.uuid = None + self.label = None + + def getDev(self): + return self.dev + + def getMajor(self): + return self.major + + def getName(self): + return self.dev + + def getUUID(self): + if not self.uuid: + return "" + return self.uuid + + def getLabel(self): + if not self.label: + return "" + return self.label + + def isRemovable(self): + return self.removable + + def __str__(self): + return "Name: %s, Device: %s, Major: %i, " % (self.getName(), + self.getDev(), + self.getMajor()) + +############################################################################ +class Disk(Device): + def __init__(self): + super(Disk,self).__init__() + self.removable = False + self.partitions = [] + self.modelname = None + self.iconname = "hi16-hdd" + + def getModelName(self): + return self.modelname + + def getName(self): + if self.getModelName(): + return i18n("Disk ")+self.getModelName() + else: + return i18n("Unknown Disk") + + def getPartitions(self): + return self.partitions[:] + + def appendPartition(self,partition): + self.partitions.append(partition) + def cmpNum(a,b): return cmp(a.num,b.num) + self.partitions.sort(cmpNum) + + def __str__(self): + x = Device.__str__(self) + "Partitions: [" + for part in self.partitions: + x += "[" + x += str(part) + x += "], " + x += "]," + return x + +############################################################################ +class RemovableDisk(Disk): + def __init__(self): + super(RemovableDisk,self).__init__() + self.iconname = "hi16-cdrom" + self.removable = True + + def getName(self): + return "Optical Disk "+self.getModelName() + +############################################################################ +class USBDisk(Disk): + def __init__(self): + super(USBDisk,self).__init__() + self.iconname = "hi16-usbpen" + self.removable = True + + def getName(self): + return "Removable USB Disk "+self.getModelName() + +############################################################################ +class BurnerDisk(RemovableDisk): + def __init__(self): + super(BurnerDisk,self).__init__() + self.iconname = "hi16-burner" + + def getName(self): + return "Burner "+self.modelname + +############################################################################ +class Floppy(Device): + def isRemovable(self): + return True + + def getName(self): + return "Floppy" + +############################################################################ +class Partition(Device): + def __init__(self): + super(Partition,self).__init__() + self.num = None + self.size = None + self.iconname = "hi16-hdd" + + def getName(self): + return str(self.num)+" Partition "+ self.getSize() + # A group item for all of the other kernel/system mount entries. + + def getSize(self): + return self.size + + def __str__(self): + return "Device: %s, Num: %i, Size: %s, Label: %s, UUID: %s" % (self.dev, self.num, self.getSize(), + self.getLabel(), self.getUUID()) + +############################################################################ +class FakeSystemDevice(object): + def getName(self): return "System" + def getIconName(self): return "hi16-blockdevice" + +############################################################################ +class MicroHAL(object): + + # Major device numbers for Linux block devices that support partitions. + partitionblockdevs = [ + 3, # IDE harddisks + 8, # SCSI disks + 13, # 8-bit MFM/RLL/IDE controller + 14, # BIOS harddrive callback support {2.6} + 21, # Acorn MFM hard drive interface + 22, # Second IDE hard disk/CD-ROM interface + 28, # ACSI disk (68k/Atari) + 33, # Third IDE hard disk/CD-ROM interface + 34, # Fourth IDE hard disk/CD-ROM interface + 36, # MCA ESDI hard disk + 44, # Flash Translation Layer (FTL) filesystems + 45, # Parallel port IDE disk devices + 48, # Mylex DAC960 PCI RAID controller; first controller + 49, # Mylex DAC960 PCI RAID controller; second controller + 50, # Mylex DAC960 PCI RAID controller; third controller + 51, # Mylex DAC960 PCI RAID controller; fourth controller + 52, # Mylex DAC960 PCI RAID controller; fifth controller + 53, # Mylex DAC960 PCI RAID controller; sixth controller + 54, # Mylex DAC960 PCI RAID controller; seventh controller + 55, # Mylex DAC960 PCI RAID controller; eigth controller + 56, # Fifth IDE hard disk/CD-ROM interface + 57, # Sixth IDE hard disk/CD-ROM interface + 65, # SCSI disk devices (16-31) + 66, # SCSI disk devices (32-47) + 67, # SCSI disk devices (48-63) + 68, # SCSI disk devices (64-79) + 69, # SCSI disk devices (80-95) + 70, # SCSI disk devices (96-111) + 71, # SCSI disk devices (112-127) + 72, # Compaq Intelligent Drive Array, first controller + 73, # Compaq Intelligent Drive Array, second controller + 74, # Compaq Intelligent Drive Array, third controller + 75, # Compaq Intelligent Drive Array, fourth controller + 76, # Compaq Intelligent Drive Array, fifth controller + 77, # Compaq Intelligent Drive Array, sixth controller + 78, # Compaq Intelligent Drive Array, seventh controller + 79, # Compaq Intelligent Drive Array, eigth controller + 80, # I2O hard disk + 81, # I2O hard disk + 82, # I2O hard disk + 83, # I2O hard disk + 84, # I2O hard disk + 85, # I2O hard disk + 86, # I2O hard disk + 87, # I2O hard disk + 88, # Seventh IDE hard disk/CD-ROM interface + 89, # Eighth IDE hard disk/CD-ROM interface + 90, # Ninth IDE hard disk/CD-ROM interface + 91, # Tenth IDE hard disk/CD-ROM interface + 92, # PPDD encrypted disk driver + 95, # IBM S/390 DASD block storage + 101, # AMI HyperDisk RAID controller + 102, # Compressed block device + 104, # Compaq Next Generation Drive Array, first controller + 105, # Compaq Next Generation Drive Array, second controller + 106, # Compaq Next Generation Drive Array, third controller + 107, # Compaq Next Generation Drive Array, fourth controller + 108, # Compaq Next Generation Drive Array, fifth controller + 109, # Compaq Next Generation Drive Array, sixth controller + 110, # Compaq Next Generation Drive Array, seventh controller + 111, # Compaq Next Generation Drive Array, eigth controller + 112, # IBM iSeries virtual disk + 114, # IDE BIOS powered software RAID interfaces such as the Promise Fastrak + 128, # SCSI disk devices (128-143) + 129, # SCSI disk devices (144-159) + 130, # SCSI disk devices (160-175) + 131, # SCSI disk devices (176-191) + 132, # SCSI disk devices (192-207) + 133, # SCSI disk devices (208-223) + 134, # SCSI disk devices (224-239) + 135, # SCSI disk devices (240-255) + 136, # Mylex DAC960 PCI RAID controller; ninth controller + 137, # Mylex DAC960 PCI RAID controller; tenth controller + 138, # Mylex DAC960 PCI RAID controller; eleventh controller + 139, # Mylex DAC960 PCI RAID controller; twelfth controller + 140, # Mylex DAC960 PCI RAID controller; thirteenth controller + 141, # Mylex DAC960 PCI RAID controller; fourteenth controller + 142, # Mylex DAC960 PCI RAID controller; fifteenth controller + 143, # Mylex DAC960 PCI RAID controller; sixteenth controller + 160, # Promise SX8 8-port SATA Disks on First Controller + 161 # Promise SX8 8-port SATA Disks on Second Controller + ] + + floppydevs = [ + 2, # Floppy disks + 40 # Syquest EZ135 parallel port removable drive + ] + + cdromsdevs = [ + 11, # SCSI CD-ROM devices + 12, # MSCDEX CD-ROM callback support {2.6} + 15, # Sony CDU-31A/CDU-33A CD-ROM + 16, # GoldStar CD-ROM + 17, # Optics Storage CD-ROM + 18, # Sanyo CD-ROM + 20, # Hitachi CD-ROM (under development) + 23, # Mitsumi proprietary CD-ROM + 24, # Sony CDU-535 CD-ROM + 25, # First Matsushita (Panasonic/SoundBlaster) CD-ROM + 26, # Second Matsushita (Panasonic/SoundBlaster) CD-ROM + 27, # Third Matsushita (Panasonic/SoundBlaster) CD-ROM + 28, # Fourth Matsushita (Panasonic/SoundBlaster) CD-ROM + 29, # Aztech/Orchid/Okano/Wearnes CD-ROM + 30, # Philips LMS CM-205 CD-ROM + 32, # Philips LMS CM-206 CD-ROM + 41, # MicroSolutions BackPack parallel port CD-ROM + 46, # Parallel port ATAPI CD-ROM devices + 47, # Parallel port ATAPI disk devices + 48, # Mylex DAC960 PCI RAID controller; first controller + 113 # IBM iSeries virtual CD-ROM + ] + + burnerpacketdevs = [ + 97 # Packet writing for CD/DVD devices + ] + + # We provide a mapping between filesystems and kernelmodules, so filesystems + # that are built as modules can be loaded on demand. (In fact, mountconfig will + # load all filesystem modules needed to be able to mount all fstab entries.) + FilesystemProcDriver = [ + # fstab name, /proc name, kernel module name + ('auto','autofs','autofs4'), + ('iso9660','iso9660','isofs'), + ('nfs','nfsd','nfs') + ] + + ############################################################################ + def __init__(self): + self.devices = None + self.supportedfs = None + + ############################################################################ + def getDevices(self): + if self.devices is None: + self.devices = [] + + retval, msg = SimpleCommandRunner().run(["/usr/bin/lshal"]) + if retval > 0: + return [] + + partition_to_uid = {} + uid_to_disk = {} + + READING_TOP = 0 + READING_DEVICE = 1 + state = READING_TOP + + parsed_hash = None + current_uid = None + + for line in msg.split('\n'): + + if state==READING_TOP: + if line.startswith("udi ="): + parsed_hash = {} + current_uid = self._parseString(line[6:]) + state = READING_DEVICE + + elif state==READING_DEVICE: + if line=="" or not line.startswith(" "): + # Detect the end of this block of device data. + state = READING_TOP + + if u"info.category" in parsed_hash: + + new_device = None + + capabilities_string = u" ".join(parsed_hash[u"info.capabilities"]) + capabilities = self._parseStringList(capabilities_string) + + category = self._parseString(' '.join(parsed_hash[u"info.category"])) + if category==u"volume": + # Is it a volume? + + is_disc = parsed_hash.get(u"volume.is_disc") + if is_disc is not None and is_disc[0]=='true': + continue + + is_partition = parsed_hash.get(u"volume.is_partition") + if is_partition is not None: + is_partition = is_partition[0] + + if is_partition=='true': + new_device = Partition() + new_device.num = int(parsed_hash[u"volume.partition.number"][0]) + partition_to_uid[new_device] = current_uid + + if u"info.parent" in parsed_hash: + parent_uid = self._parseString(' '.join(parsed_hash[u"info.parent"])) + partition_to_uid[new_device] = parent_uid + + else: + new_device = Disk() + uid_to_disk[current_uid] = new_device + + if u"volume.uuid" in parsed_hash: + new_device.uuid = self._parseString(' '.join(parsed_hash[u"volume.uuid"])) + + if u"volume.label" in parsed_hash: + new_device.label = self._parseString(parsed_hash[u"volume.label"][0]) + + if u"volume.size" in parsed_hash: + size = parsed_hash[u"volume.size"][0] + new_device.size = self.formatSizeBytes(int(size)) + else: + new_device.size = "?" + + + # is it a storage device? + elif category==u"storage": + storage_model = self._parseString(' '.join(parsed_hash[u"storage.model"])) + storage_removable = parsed_hash[u"storage.removable"][0]==u"true" + + if u"storage.cdrom" in capabilities: + + if u"storage.cdrom.cdrw" in parsed_hash \ + and parsed_hash[u"storage.cdrom.cdrw"][0]==u"true": + new_device = BurnerDisk() + else: + new_device= RemovableDisk() + + elif u"storage.floppy" in capabilities: + new_device = FloppyDevice() + else: + if u"storage.bus" in parsed_hash \ + and self._parseString(' '.join(parsed_hash[u"storage.bus"]))==u"usb": + + new_device = USBDisk() + else: + new_device = Disk() + + new_device.modelname = storage_model + uid_to_disk[current_uid] = new_device + else: + # Not interesting, skip it. + continue + + # Handle the generic properties. + new_device.dev = self._parseString(' '.join(parsed_hash[u"block.device"])) + new_device.major = int(parsed_hash[u"block.major"][0]) + + self.devices.append(new_device) + + else: + # Keep on accumulating info about this device. + parts = line.split() + parsed_hash[ parts[0] ] = parts[2:] + + # Attach the partitions to thier devices. + for partition in partition_to_uid.keys(): + parent = partition_to_uid[partition] + if parent in uid_to_disk.keys(): + parent_device = uid_to_disk[parent] + parent_device.appendPartition(partition) + self.devices.remove(partition) + + return self.devices[:] + + ############################################################################ + def _parseStringList(self,source_string): + STATE_TOP = 0 + STATE_STRING = 1 + + state = STATE_TOP + current_string = "" + string_list = [] + for c in source_string: + if state==STATE_TOP: + if c=='}': + break + if c=="'": + state = STATE_STRING + else: + if c=="'": + state = STATE_TOP + string_list.append(current_string) + current_string = "" + else: + current_string += c + + return string_list + + ############################################################################ + def _parseString(self,source_string): + STATE_TOP = 0 + STATE_STRING = 1 + + state = STATE_TOP + current_string = "" + for c in source_string: + if state==STATE_TOP: + if c=="'": + state = STATE_STRING + else: + if c=="'": + break + else: + current_string += c + return current_string + + ############################################################################ + def formatSizeBytes(self,size): + if size<1024: + return str(size+" B") + if size<1024*1042: + return str(round(float(size)/1024.0,1))+" Kb" + size /= 1024 + if size<1024*1024: + return str(round(float(size)/1024.0,1))+" Mb" + size /= 1024 + if size<1024*1024: + return str(round(float(size)/1024.0,1))+" Gb" + size /= 1024 + return str(round(float(size)/1024.0,1))+" Tb" + + ############################################################################ + def getSupportedFileSystems(self): + if self.supportedfs is None: + if os.path.isfile("/proc/filesystems"): + fhandle = open("/proc/filesystems") + self.supportedfs = [] + for fs in fhandle.readlines(): + try: + self.supportedfs.append(fs.strip().split()[1]) + except IndexError: + self.supportedfs.append(fs.strip().split()[0]) + # The following filesystems aren't found there, but usually they are + # supported. + self.supportedfs.extend(('swap','shm')) + return self.supportedfs[:] + + ############################################################################ + def isSupportedFileSystem(self,fs): + # Look up the /proc and kernel driver name for the given filesystem type. + module = fs + proc = fs + for entry in self.FilesystemProcDriver: + if entry[0]==fs: + proc = entry[1] + module = entry[2] + + if proc not in self.getSupportedFileSystems(): + # The filesystem is not supported by the running kernel, + # but it might be built as module, so we try to load that. + retval, msg = SimpleCommandRunner().run(["/sbin/modprobe",module]) + if retval > 0: + print msg + print "Couldn't load driver " + module + " for filesystem " + fs + # Force refresh of list of supported filesystems + self.supportedfs = None + return proc in self.getSupportedFileSystems() + + ############################################################################ + def getDeviceByLabel(self, label): + for device in self.getDevices(): + if device.getLabel()==label: + return device + + if isinstance(device,Disk): + for partition in device.getPartitions(): + if partition.getLabel()==label: + return partition + return None + + def getLabelByDevice(self, device): + for item in self.getDevices(): + for partition in item.partitions: + if partition.dev==device: + return partition.label + print "No Label found for ",device + return "" + + def getUUIDByDevice(self, device): + for item in self.getDevices(): + for partition in item.partitions: + #print partition, partition.getUUID() + if partition.dev==device: + return partition.uuid + print "No UUID found for ",device + return "" + + def getDeviceByUUID(self, uuid): + for device in self.getDevices(): + if device.getUUID()==uuid: + return device + + if isinstance(device,Disk): + for partition in device.getPartitions(): + if partition.getUUID()==uuid: + return partition + + return None + +############################################################################ +if __name__=='__main__': + hal = MicroHAL() + for item in hal.getDevices(): + print(str(item)) + + print + + #""" + for item in hal.getDevices(): + for partition in item.partitions: + print partition, partition.getLabel() + #""" + #realhal = RealHAL() + #for item in realhal.getDevices(): + # print(str(item)) + + print + + |