KGRKJGETMRETU895U-589TY5MIGM5JGB5SDFESFREWTGR54TY
Server : Apache/2.2.17 (Unix) mod_ssl/2.2.17 OpenSSL/0.9.8e-fips-rhel5 DAV/2 PHP/5.2.17
System : Linux localhost 2.6.18-419.el5 #1 SMP Fri Feb 24 22:47:42 UTC 2017 x86_64
User : nobody ( 99)
PHP Version : 5.2.17
Disable Function : NONE
Directory :  /proc/22697/root/usr/share/system-config-lvm/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : //proc/22697/root/usr/share/system-config-lvm/BlockDevice.py
import copy

from fdisk_wrapper import FDisk
from parted_wrapper import Parted
from Partition import *



class BlockDeviceErr:
    pass
class BlockDeviceErr_occupied(BlockDeviceErr):
    pass
class BlockDeviceErr_cannotFit(BlockDeviceErr):
    pass
class BlockDeviceErr_extended(BlockDeviceErr):
    pass
class BlockDeviceErr_extendedNumsMissing(BlockDeviceErr):
    pass
class BlockDeviceErr_num(BlockDeviceErr):
    pass
class BlockDeviceErr_partFormat(BlockDeviceErr):
    pass



class BlockDevice:
    
    def __init__(self, devpath):
        self.__segs = list()
        self.dev = devpath
        
        self.sectors = 0
        self.sectorSize = 0
        self.cyls = 0
        self.spt = 0   # sectors per track
        self.spc = 0   # sectors per cylinder
        
        self.useParted = False
        
        self.reload()
    
    # discard changes
    def reload(self):
        fdisk = FDisk()
        self.__segs = list()
        # get disk geometry
        self.sectors, self.sectorSize, self.cyls, self.spt, self.spc = fdisk.getDeviceGeometry(self.dev)
        # allocate all space
        new_seg = BlockDeviceSegment(1, self.sectors-1, self.sectorSize)
        new_seg.wholeDevice = True
        self.__segs.append(new_seg)
        # get partitions
        parts = fdisk.getPartitions(self.dev)
        # then insert extended partitions
        for part in parts:
            if part.id in ID_EXTENDS:
                self.addNoAlign(part.beg, part.end, part.id, part.bootable, part.num)
        # insert other partitions
        for part in parts:
            if part.id not in ID_EXTENDS:
                self.addNoAlign(part.beg, part.end, part.id, part.bootable, part.num)
        self.__sortSegs()
        
        # check for gpt tables
        if self.__segs[0].id == ID_GPT:
            # gpt table already present
            self.__parted_reload()
        if self.sectors * self.sectorSize > 2 * 1024 * 1024 * 1024 * 1024:
            # msdos partition label handles up to 2 TB
            # use gpt table
            self.__parted_reload()
    
    def __parted_reload(self):
        self.useParted = True
        # allocate all space
        new_seg = BlockDeviceSegment(1, self.sectors-1, self.sectorSize)
        new_seg.wholeDevice = True
        self.__segs = [new_seg]
        # get partitions
        parts = Parted().getPartitions(self.dev)
        # insert partitions
        for part in parts:
            self.addNoAlign(part.beg, part.end, part.id, part.bootable, part.num)
        self.__sortSegs()
                
    
    # !!! save partition to disk !!!
    def saveTable(self):
        # make sure extended partitions don't have gaps in numbering
        nums = self.getPartNums()
        max_part = 4
        for i in nums:
            if i > max_part:
                max_part = i
        for i in range(5, max_part + 1):
            if i not in nums:
                raise BlockDeviceErr_extendedNumsMissing()
        
        if self.useParted:
            Parted().savePartTable(self.dev, self.getSegments())
        else:
            FDisk().savePartTable(self.dev, self.getSegments())
    
    def renumberExtends(self):
        self.__sortSegs()
        i = 5
        for part in self.__segs:
            if part.id in ID_EXTENDS:
                for p in part.children:
                    if p.id != ID_EMPTY:
                        p.num = i
                        p.children[1].num = i
                        i = i + 1
    
    def getSegments(self):
        segs_copy = copy.deepcopy(self.__sortSegs())
        return self.__getSegments(segs_copy, False)
    def __getSegments(self, segs, extended):
        if extended:
            # clean up
            for seg in segs:
                if seg.id != ID_EMPTY:
                    seg.beg = seg.children[1].beg
                    seg.children = list()
        # remove small unallocatable segments
        for seg in segs[:]:
            seg.children = self.__getSegments(seg.children, True)
            if (seg.id == ID_EMPTY) and (seg.getSize() <= self.spc):
                segs.remove(seg)
        return segs
    
    def getPartNums(self):
        nums = list()
        for seg in self.__segs:
            if seg.id != ID_EMPTY:
                nums.append(seg.num)
            if seg.id in ID_EXTENDS:
                for s in seg.children:
                    if s.id != ID_EMPTY:
                        nums.append(s.num)
        return nums
    
    def addAlign(self, beg, end, id, bootable, num = None):
        beg = self.__alignLowerBound(beg)
        if end != self.sectors - 1:
            end = self.__alignUpperBound(end)
        return self.addNoAlign(beg, end, id, bootable, num)
    
    def addNoAlign(self, beg, end, id, bootable, num = None):
        if beg >= end or beg == None or end == None:
            raise BlockDeviceErr_partFormat()
        if id == None or id < 1 or (id > 255 and id != ID_UNKNOWN):
            raise BlockDeviceErr_partFormat()
        if (bootable != True) and (bootable != False):
            raise BlockDeviceErr_partFormat()
        if (num != None) and (num < 1):
            raise BlockDeviceErr_partFormat()
        
        if beg >= end or id == ID_EMPTY:
            return None
        
        if id in ID_EXTENDS:
            bootable = False
            for seg in self.__segs:
                if seg.id in ID_EXTENDS:
                    # only one extended allowed
                    raise BlockDeviceErr_extended()
        
        intoExtended = False
        for seg in self.__segs:
            if seg.id in ID_EXTENDS:
                if beg >= seg.beg and beg <= seg.end:
                    intoExtended = True
        
        # autodetermine partition number
        if num == None:
            avail_nums = list()
            if not self.useParted:
                if intoExtended:
                    avail_nums = range(5, 100)
                    for i in self.getPartNums():
                        if i > 4:
                            avail_nums.remove(i)
                else:
                    avail_nums = range(1,5)
                    for i in self.getPartNums():
                        if i < 5:
                            avail_nums.remove(i)
            else:
                avail_nums = range(1,100)
                for i in self.getPartNums():
                    avail_nums.remove(i)
            
            if len(avail_nums) == 0:
                raise BlockDeviceErr_num()
            num = avail_nums[0]
        
        if num in self.getPartNums():
            raise BlockDeviceErr_num()
        if not self.useParted:
            if (id in ID_EXTENDS) and (num > 4):
                raise BlockDeviceErr_extended()
            if intoExtended and num < 5:
                raise BlockDeviceErr_extended()
            if (not intoExtended) and (num > 4):
                raise BlockDeviceErr_extended()
        
        part = Partition(beg, end, id, num, bootable, self.sectorSize)
        if part.id in ID_EXTENDS:
            new_seg = BlockDeviceSegment(part.beg, part.end, self.sectorSize)
            part.children = [new_seg]
        self.__insert(part)
        return num
    
    # no allignment is performed
    def __insert(self, part):
        self.__insert2(part, self.__segs, False)
    def __insert2(self, part, segs, extended):
        for seg in segs:
            if (part.beg >= seg.beg) and (part.end <= seg.end):
                if seg.id in ID_EXTENDS:
                    self.__insert2(part, seg.children, True)
                    return
                elif seg.id == ID_EMPTY:
                    if extended:
                        if part.beg == seg.beg:
                            part.beg = part.beg + 1
                        new_part = Partition(part.beg-1, part.end, part.id, part.num, part.bootable, part.sectorSize)
                        new_seg = BlockDeviceSegment(new_part.beg, new_part.end, new_part.sectorSize)
                        new_part.children.append(new_seg)
                        self.__insert2(part, new_part.children, False)
                        part = new_part
                    if seg.beg < part.beg:
                        # add seg before
                        new_seg = BlockDeviceSegment(seg.beg, part.beg - 1, self.sectorSize)
                        segs.append(new_seg)
                    if seg.end > part.end:
                        # add seg after
                        new_seg = BlockDeviceSegment(part.end + 1, seg.end, self.sectorSize)
                        segs.append(new_seg)
                    # replace current seg with part
                    segs.remove(seg)
                    segs.append(part)
                    return
                else:
                    raise BlockDeviceErr_occupied()
        raise BlockDeviceErr_cannotFit()
    
    
    def remove(self, partNum):
        self.__sortSegs() # make sure to sort first
        self.__remove(partNum, self.__segs)
        self.__sortSegs()
    def __remove(self, partNum, segs):
        length = len(segs)
        for i in range(length):
            seg = segs[i]
            if seg.id == ID_EMPTY:
                continue
            if seg.num == partNum:
                beg = seg.beg
                end = seg.end
                remove_list = [seg]
                # merge with preceding empty segment
                if i-1 >= 0:
                    if segs[i-1].id == ID_EMPTY:
                        beg = segs[i-1].beg
                        remove_list.append(segs[i-1])
                # merge with following empty segment
                if i+1 < length:
                    if segs[i+1].id == ID_EMPTY:
                        end = segs[i+1].end
                        remove_list.append(segs[i+1])
                for rem in remove_list:
                    segs.remove(rem)
                new_seg = BlockDeviceSegment(beg, end, self.sectorSize)
                if (new_seg.beg == 1) and (new_seg.end == self.sectors - 1):
                    new_seg.wholeDevice = True
                segs.append(new_seg)
                return
            elif seg.id in ID_EXTENDS:
                self.__remove(partNum, seg.children)
        
    
    def printout(self):
        print 'device: ' + self.dev
        print str(self.sectorSize * self.sectors), 'bytes,', str(self.sectors), 'sectors,', str(self.cyls), 'cylinders,', str(self.spt), 'sectors/track,', str(self.spc), 'sectors/cylinder'
        print 'partitions:'
        for seg in self.__segs:
            seg.printout()

    
    def __alignLowerBound(self, num):
        if num == self.spt:
            return num
        val = (num / self.spc) * self.spc
        if num == val + 1:
            return num
        val = ((num + self.spc - 1) / self.spc) * self.spc
        if val < 1:
            val = 1
        return val
    def __alignUpperBound(self, num):
        if (num + 1) % self.spc == 0:
            return num
        else:
            return (num / self.spc) * self.spc - 1
    
    def __sortSegs(self):
        return self.__sortSegs2(self.__segs)
    def __sortSegs2(self, segs):
        for seg in segs:
            self.__sortSegs2(seg.children)
        for i in range(len(segs) - 1, 0, -1):
            for j in range(i):
                if segs[j].beg < segs[j+1].beg:
                    tmp = segs[j + 1]
                    segs[j + 1] = segs[j]
                    segs[j] = tmp
        segs.reverse()
        return segs

Anon7 - 2021