# # partedUtils.py: helper functions for use with parted objects # # Matt Wilson # Jeremy Katz # Mike Fulbright # # Copyright 2002 Red Hat, Inc. # # This software may be freely redistributed under the terms of the GNU # library public license. # # You should have received a copy of the GNU Library Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # """Helper functions for use when dealing with parted objects.""" import parted import fsset import math from partErrors import * from translate import _ fsTypes = {} fs_type = parted.file_system_type_get_next () while fs_type: fsTypes[fs_type.name] = fs_type fs_type = parted.file_system_type_get_next (fs_type) def get_flags (part): """Retrieve a list of strings representing the flags on the partition.""" string="" if not part.is_active (): return string first=1 flag = parted.partition_flag_next (0) while flag: if part.get_flag (flag): string = string + parted.partition_flag_get_name (flag) if first: first = 0 else: string = string + ", " flag = parted.partition_flag_next (flag) return string def start_sector_to_cyl(device, sector): """Return the closest cylinder (round down) to sector on device.""" return int(math.floor((float(sector) / (device.heads * device.sectors)) + 1)) def end_sector_to_cyl(device, sector): """Return the closest cylinder (round up) to sector on device.""" return int(math.ceil(float((sector + 1)) / (device.heads * device.sectors))) def start_cyl_to_sector(device, cyl): "Return the sector corresponding to cylinder as a starting cylinder." return long((cyl - 1) * (device.heads * device.sectors)) def end_cyl_to_sector(device, cyl): "Return the sector corresponding to cylinder as a ending cylinder." return long(((cyl) * (device.heads * device.sectors)) - 1) def getPartSize(partition): """Return the size of partition in sectors.""" return partition.geom.length def getPartSizeMB(partition): """Return the size of partition in megabytes.""" return (partition.geom.length * partition.geom.disk.dev.sector_size / 1024.0 / 1024.0) def getDeviceSizeMB(dev): """Return the size of dev in megabytes.""" return (float(dev.heads * dev.cylinders * dev.sectors) / (1024 * 1024) * dev.sector_size) def get_partition_by_name(disks, partname): """Return the parted part object associated with partname. Arguments: disks -- Dictionary of diskname->PedDisk objects partname -- Name of partition to find Return: PedPartition object with name partname. None if no such partition. """ for diskname in disks.keys(): disk = disks[diskname] part = disk.next_partition() while part: if get_partition_name(part) == partname: return part part = disk.next_partition(part) return None def get_partition_name(partition): """Return the device name for the PedPartition partition.""" if (partition.geom.disk.dev.type == parted.DEVICE_DAC960 or partition.geom.disk.dev.type == parted.DEVICE_CPQARRAY): return "%sp%d" % (partition.geom.disk.dev.path[5:], partition.num) return "%s%d" % (partition.geom.disk.dev.path[5:], partition.num) def get_partition_file_system_type(part): """Return the file system type of the PedPartition part. Arguments: part -- PedPartition object Return: Filesystem object (as defined in fsset.py) """ if part.fs_type == None: return None if part.fs_type.name == "linux-swap": ptype = fsset.fileSystemTypeGet("swap") elif part.fs_type.name == "FAT": ptype = fsset.fileSystemTypeGet("vfat") else: try: ptype = fsset.fileSystemTypeGet(part.fs_type.name) except: ptype = fsset.fileSystemTypeGet("foreign") return ptype def set_partition_file_system_type(part, fstype): """Set partition type of part to PedFileSystemType implied by fstype.""" if fstype == None: return try: for flag in fstype.getPartedPartitionFlags(): if not part.is_flag_available(flag): raise PartitioningError, ("requested FileSystemType needs " "a flag that is not available.") part.set_flag(flag, 1) part.set_system(fstype.getPartedFileSystemType()) except: print "Failed to set partition type to ",fstype.getName() pass def get_partition_drive(partition): """Return the device name for disk that PedPartition partition is on.""" return "%s" %(partition.geom.disk.dev.path[5:]) def map_foreign_to_fsname(type): """Return the partition type associated with the numeric type.""" if type in allPartitionTypesDict.keys(): return allPartitionTypesDict[type] else: return _("Foreign") def filter_partitions(disk, func): rc = [] part = disk.next_partition () while part: if func(part): rc.append(part) part = disk.next_partition (part) return rc def get_logical_partitions(disk): """Return a list of logical PedPartition objects on disk.""" func = lambda part: (part.is_active() and part.type & parted.PARTITION_LOGICAL) return filter_partitions(disk, func) def get_primary_partitions(disk): """Return a list of primary PedPartition objects on disk.""" func = lambda part: part.type == parted.PARTITION_PRIMARY return filter_partitions(disk, func) def get_raid_partitions(disk): """Return a list of RAID-type PedPartition objects on disk.""" func = lambda part: (part.is_active() and part.get_flag(parted.PARTITION_RAID) == 1) return filter_partitions(disk, func) def get_lvm_partitions(disk): """Return a list of physical volume-type PedPartition objects on disk.""" func = lambda part: (part.is_active() and part.get_flag(parted.PARTITION_LVM) == 1) return filter_partitions(disk, func) # XXX is this all of the possibilities? dosPartitionTypes = [ 1, 6, 11, 12, 14, 15 ] # master list of partition types allPartitionTypesDict = { 0 : "Empty", 1: "DOS 12-bit FAT", 2: "XENIX root", 3: "XENIX usr", 4: "DOS 16-bit <32M", 5: "Extended", 6: "DOS 16-bit >=32M", 7: "NTFS/HPFS", 8: "AIX", 9: "AIX bootable", 10: "OS/2 Boot Manager", 0xb: "Win95 FAT32", 0xc: "Win95 FAT32", 0xe: "Win95 FAT16", 0xf: "Win95 Ext'd", 0x10: "OPUS", 0x11: "Hidden FAT12", 0x12: "Compaq Setup", 0x14: "Hidden FAT16 <32M", 0x16: "Hidden FAT16", 0x17: "Hidden HPFS/NTFS", 0x18: "AST SmartSleep", 0x1b: "Hidden Win95 FAT32", 0x1c: "Hidden Win95 FAT32 (LBA)", 0x1e: "Hidden Win95 FAT16 (LBA)", 0x24: "NEC_DOS", 0x39: "Plan 9", 0x40: "Venix 80286", 0x41: "PPC_PReP Boot", 0x42: "SFS", 0x4d: "QNX4.x", 0x4e: "QNX4.x 2nd part", 0x4f: "QNX4.x 2nd part", 0x51: "Novell?", 0x52: "Microport", 0x63: "GNU HURD", 0x64: "Novell Netware 286", 0x65: "Novell Netware 386", 0x75: "PC/IX", 0x80: "Old MINIX", 0x81: "Linux/MINIX", 0x82: "Linux swap", 0x83: "Linux native", 0x84: "OS/2 hidden C:", 0x85: "Linux Extended", 0x86: "NTFS volume set", 0x87: "NTFS volume set", 0x8e: "Linux LVM", 0x93: "Amoeba", 0x94: "Amoeba BBT", 0x9f: "BSD/OS", 0xa0: "IBM Thinkpad hibernation", 0xa5: "BSD/386", 0xa6: "OpenBSD", 0xb7: "BSDI fs", 0xb8: "BSDI swap", 0xc7: "Syrinx", 0xdb: "CP/M", 0xde: "Dell Utility", 0xe1: "DOS access", 0xe3: "DOS R/O", 0xeb: "BEOS", 0xee: "EFI GPT", 0xef: "EFI (FAT-12/16/32)", 0xf2: "DOS secondary", 0xfd: "Linux RAID", 0xff: "BBT" }