summaryrefslogtreecommitdiffstats
path: root/mountconfig/MicroHAL.py
diff options
context:
space:
mode:
Diffstat (limited to 'mountconfig/MicroHAL.py')
-rwxr-xr-xmountconfig/MicroHAL.py884
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
+
+