Ejemplo n.º 1
0
    def __init__(self, name, vgdev, size=None, uuid=None,
                 stripes=1, logSize=0, snapshotSpace=0,
                 format=None, exists=None, sysfsPath='',
                 grow=None, maxsize=None, percent=None):
        """ Create a LogicalVolume instance.

            Arguments:

                name -- the device name (generally a device node's basename)
                vgdev -- volume group (VolumeGroup instance)

            Keyword Arguments:

                size -- the device's size (in MB)
                uuid -- the device's UUID
                stripes -- number of copies in the vg (>1 for mirrored lvs)
                logSize -- size of log volume (for mirrored lvs)
                snapshotSpace -- sum of sizes of snapshots of this lv
                sysfsPath -- sysfs device path
                format -- a DeviceFormat instance
                exists -- indicates whether this is an existing device

                For new (non-existent) LVs only:

                    grow -- whether to grow this LV
                    maxsize -- maximum size for growable LV (in MB)
                    percent -- percent of VG space to take

        """
        if isinstance(vgdev, list):
            if len(vgdev) != 1:
                raise ValueError("constructor requires a single VolumeGroup instance")
            elif not isinstance(vgdev[0], VolumeGroup):
                raise ValueError("constructor requires a VolumeGroup instance")
        elif not isinstance(vgdev, VolumeGroup):
            raise ValueError("constructor requires a VolumeGroup instance")

        DeviceMapper.__init__(self, name, size=size, format=format,
                              sysfsPath=sysfsPath, parents=vgdev, exists=exists)

        self.uuid = uuid
        self.snapshotSpace = snapshotSpace
        self.stripes = stripes
        self.logSize = logSize

        self.req_grow = None
        self.req_max_size = 0
        self.req_size = 0   
        self.req_percent = 0

        if not self.exists:
            self.req_grow = grow
            self.req_max_size = numeric_type(maxsize)
            # XXX should we enforce that req_size be pe-aligned?
            self.req_size = self._size
            self.req_percent = numeric_type(percent)

        # here we go with the circular references
        self.vg._addLogicalVolume(self)
Ejemplo n.º 2
0
    def __init__(self, name, vgdev, size=None, uuid=None,
                 stripes=1, logSize=0, snapshotSpace=0,
                 format=None, exists=None, sysfsPath='',
                 grow=None, maxsize=None, percent=None):
        """ Create a LogicalVolume instance.

            Arguments:

                name -- the device name (generally a device node's basename)
                vgdev -- volume group (VolumeGroup instance)

            Keyword Arguments:

                size -- the device's size (in MB)
                uuid -- the device's UUID
                stripes -- number of copies in the vg (>1 for mirrored lvs)
                logSize -- size of log volume (for mirrored lvs)
                snapshotSpace -- sum of sizes of snapshots of this lv
                sysfsPath -- sysfs device path
                format -- a DeviceFormat instance
                exists -- indicates whether this is an existing device

                For new (non-existent) LVs only:

                    grow -- whether to grow this LV
                    maxsize -- maximum size for growable LV (in MB)
                    percent -- percent of VG space to take

        """
        if isinstance(vgdev, list):
            if len(vgdev) != 1:
                raise ValueError("constructor requires a single VolumeGroup instance")
            elif not isinstance(vgdev[0], VolumeGroup):
                raise ValueError("constructor requires a VolumeGroup instance")
        elif not isinstance(vgdev, VolumeGroup):
            raise ValueError("constructor requires a VolumeGroup instance")

        DeviceMapper.__init__(self, name, size=size, format=format,
                              sysfsPath=sysfsPath, parents=vgdev, exists=exists)

        self.uuid = uuid
        self.snapshotSpace = snapshotSpace
        self.stripes = stripes
        self.logSize = logSize

        self.req_grow = None
        self.req_max_size = 0
        self.req_size = 0   
        self.req_percent = 0

        if not self.exists:
            self.req_grow = grow
            self.req_max_size = numeric_type(maxsize)
            # XXX should we enforce that req_size be pe-aligned?
            self.req_size = self._size
            self.req_percent = numeric_type(percent)

        # here we go with the circular references
        self.vg._addLogicalVolume(self)
Ejemplo n.º 3
0
    def __init__(self, device, parents=None, format=None,
                 exists=False, size=None, major=None, minor=None,
                 serial=None, model="", vendor="", bus="", sysfsPath = ''):
        """ Create a Device instance.

            Arguments:

                device  -- the device (generally device node base name)

            Keyword Arguments:


                size -- the device's size (units/format TBD)
                major -- the device major
                minor -- the device minor
                serial -- the ID_SERIAL_SHORT for this device
                vendor -- the manufacturer of this Device
                model -- manufacturer's device model string
                bus -- the interconnect this device uses
                sysfsPath -- sysfs device path
                parents -- a list of required Device instances
                format  -- a Format instance
                exists  -- is existing?
        """
        if isinstance(parents, Device):
            parents = [parents]

        self.exists = exists
        AbstractDevice.__init__(self, device, parents=parents)

        self.uuid = None
        self._format = None
        self._size = numeric_type(size)
        self.major = numeric_type(major)
        self.minor = numeric_type(minor)
        self._serial = serial
        self._vendor = vendor
        self._model = model
        self.sysfsPath = sysfsPath

        self.protected = False
        self.immutable = None

        self.format = format
        self.originalFormat = self.format
        self.fstabComment = ""
        self._targetSize = self._size

        self._partedDevice = None
Ejemplo n.º 4
0
 def _setSize(self, size):
     size = self.vg.align(numeric_type(size))
     ctx.logger.debug("trying to set lv %s size to %dMB" % (self.name, size))
     if size <= (self.vg.freeSpace + self._size):
         self._size = size
         self.targetSize = size
     else:
         ctx.logger.debug("failed to set size: %dMB short" % (size - (self.vg.freeSpace + self._size),))
         raise ValueError("not enough free space in volume group")
Ejemplo n.º 5
0
 def _setSize(self, size):
     size = self.vg.align(numeric_type(size))
     ctx.logger.debug("trying to set lv %s size to %dMB" % (self.name, size))
     if size <= (self.vg.freeSpace + self._size):
         self._size = size
         self.targetSize = size
     else:
         ctx.logger.debug("failed to set size: %dMB short" % (size - (self.vg.freeSpace + self._size),))
         raise ValueError("not enough free space in volume group")
Ejemplo n.º 6
0
    def align(self, size, roundup=None):
        """ Align a size to a multiple of physical extent size. """
        size = numeric_type(size)

        if roundup:
            round = math.ceil
        else:
            round = math.floor

        # we want Kbytes as a float for our math
        size *= 1024.0
        pesize = self.peSize * 1024.0
        return long((round(size / pesize) * pesize) / 1024)
Ejemplo n.º 7
0
    def align(self, size, roundup=None):
        """ Align a size to a multiple of physical extent size. """
        size = numeric_type(size)

        if roundup:
            round = math.ceil
        else:
            round = math.floor

        # we want Kbytes as a float for our math
        size *= 1024.0
        pesize = self.peSize * 1024.0
        return long((round(size / pesize) * pesize) / 1024)
Ejemplo n.º 8
0
    def __init__(self,
                 name,
                 parents,
                 size=None,
                 free=None,
                 peSize=None,
                 peCount=None,
                 peFree=None,
                 pvCount=None,
                 uuid=None,
                 exists=None,
                 sysfsPath=''):
        """ Create a VolumeGroup instance.

            Arguments:

                name -- the device name (generally a device node's basename)
                parents -- a list of physical volumes (Device)

            Keyword Arguments:

                peSize -- physical extent size (in MB)
                exists -- indicates whether this is an existing device
                sysfsPath -- sysfs device path

                For existing VG's only:

                    size -- the VG's size (in MB)
                    free -- amount of free space in the VG
                    peFree -- number of free extents
                    peCount -- total number of extents
                    pvCount -- number of PVs in this VG
                    uuid -- the VG's UUID

        """
        self.pvClass = get_device_format("lvmpv")
        if not self.pvClass:
            raise VolumeGroupError("cannot find 'lvmpv' class")

        if isinstance(parents, list):
            for dev in parents:
                if not isinstance(dev.format, self.pvClass):
                    raise ValueError("constructor requires a list of PVs")
        elif not isinstance(parents.format, self.pvClass):
            raise ValueError("constructor requires a list of PVs")

        DeviceMapper.__init__(self,
                              name,
                              parents=parents,
                              exists=exists,
                              sysfsPath=sysfsPath)

        self.uuid = uuid
        self.free = numeric_type(free)
        self.peSize = numeric_type(peSize)
        self.peCount = numeric_type(peCount)
        self.peFree = numeric_type(peFree)
        self.pvCount = numeric_type(pvCount)
        self.lv_names = []
        self.lv_uuids = []
        self.lv_sizes = []
        self.lv_attr = []
        self.hasDuplicate = False

        # circular references, here I come
        self._lvs = []

        # TODO: validate peSize if given
        if not self.peSize:
            self.peSize = 32.0  # MB

        if not self.exists:
            self.pvCount = len(self.parents)
Ejemplo n.º 9
0
    def __init__(self, name, format=None,
             size=None, grow=False, maxsize=None,
             major=None, minor=None, bootable=None,
             sysfsPath='', parents=None, exists=None,
             partType=None, primary=False, weight=0):

        """ Create a Partition instance.

            Arguments:

                name -- the device name (generally a device node's basename)

            Keyword Arguments:

                exists -- indicates whether this is an existing device
                format -- the device's format (DeviceFormat instance)

                For existing partitions:

                    parents -- the disk that contains this partition
                    major -- the device major
                    minor -- the device minor
                    sysfsPath -- sysfs device path

                For new partitions:

                    partType -- primary,extended,&c (as parted constant)
                    grow -- whether or not to grow the partition
                    maxsize -- max size for growable partitions (in MB)
                    size -- the device's size (in MB)
                    bootable -- whether the partition is bootable
                    parents -- a list of potential containing disks
                    weight -- an initial sorting weight to assign
        """
        self.req_disks = []
        self.req_partType = None
        self.req_primary = None
        self.req_grow = None
        self.req_bootable = None
        self.req_size = 0
        self.req_base_size = 0
        self.req_max_size = 0
        self.req_base_weight = 0

        self._bootable = False

        Device.__init__(self, name, format=format, size=size,
                        major=major, minor=minor, exists=exists,
                        sysfsPath=sysfsPath, parents=parents)
        if not exists:
            # this is a request, not a partition -- it has no parents
            self.req_disks = self.parents[:]
            for dev in self.parents:
                dev.removeChild()
            self.parents = []

        # FIXME: Validate partType, but only if this is a new partition
        #        Otherwise, overwrite it with the partition's type.
        self._partType = None
        self.partedFlags = {}
        self._partedPartition = None
        self._origPath = None
        self._currentSize = 0

        # FIXME: Validate size, but only if this is a new partition.
        #        For existing partitions we will get the size from
        #        parted.

        if self.exists:
            ctx.logger.debug("looking up parted Partition: %s" % self.path)
            self._partedPartition = self.disk.format.partedDisk.getPartitionByPath(self.path)
            if not self._partedPartition:
                raise PartitionError("cannot find parted partition instance", self.name)

            self._origPath = self.path
            self.probe()
            if self.getFlag(parted.PARTITION_PREP):
                # the only way to identify a PPC PReP Boot partition is to
                # check the partition type/flags, so do it here.
                self.format = getFormat("prepboot", device=self.path, exists=True)
        else:
            # XXX It might be worthwhile to create a shit-simple
            #     PartitionRequest class and pass one to this constructor
            #     for new partitions.
            if not self._size:
                # default size for new partition requests
                self._size = self.defaultSize
            self.req_name = name
            self.req_partType = partType
            self.req_primary = primary
            self.req_max_size = numeric_type(maxsize)
            self.req_grow = grow
            self.req_bootable = bootable

            # req_size may be manipulated in the course of partitioning
            self.req_size = self._size

            # req_base_size will always remain constant
            self.req_base_size = self._size

            self.req_base_weight = weight
Ejemplo n.º 10
0
    def __init__(self,
                 name,
                 format=None,
                 size=None,
                 grow=False,
                 maxsize=None,
                 major=None,
                 minor=None,
                 bootable=None,
                 sysfsPath='',
                 parents=None,
                 exists=None,
                 partType=None,
                 primary=False,
                 weight=0):
        """ Create a Partition instance.

            Arguments:

                name -- the device name (generally a device node's basename)

            Keyword Arguments:

                exists -- indicates whether this is an existing device
                format -- the device's format (DeviceFormat instance)

                For existing partitions:

                    parents -- the disk that contains this partition
                    major -- the device major
                    minor -- the device minor
                    sysfsPath -- sysfs device path

                For new partitions:

                    partType -- primary,extended,&c (as parted constant)
                    grow -- whether or not to grow the partition
                    maxsize -- max size for growable partitions (in MB)
                    size -- the device's size (in MB)
                    bootable -- whether the partition is bootable
                    parents -- a list of potential containing disks
                    weight -- an initial sorting weight to assign
        """
        self.req_disks = []
        self.req_partType = None
        self.req_primary = None
        self.req_grow = None
        self.req_bootable = None
        self.req_size = 0
        self.req_base_size = 0
        self.req_max_size = 0
        self.req_base_weight = 0

        self._bootable = False

        Device.__init__(self,
                        name,
                        format=format,
                        size=size,
                        major=major,
                        minor=minor,
                        exists=exists,
                        sysfsPath=sysfsPath,
                        parents=parents)
        if not exists:
            # this is a request, not a partition -- it has no parents
            self.req_disks = self.parents[:]
            for dev in self.parents:
                dev.removeChild()
            self.parents = []

        # FIXME: Validate partType, but only if this is a new partition
        #        Otherwise, overwrite it with the partition's type.
        self._partType = None
        self.partedFlags = {}
        self._partedPartition = None
        self._origPath = None
        self._currentSize = 0

        # FIXME: Validate size, but only if this is a new partition.
        #        For existing partitions we will get the size from
        #        parted.

        if self.exists:
            ctx.logger.debug("looking up parted Partition: %s" % self.path)
            self._partedPartition = self.disk.format.partedDisk.getPartitionByPath(
                self.path)
            if not self._partedPartition:
                raise PartitionError("cannot find parted partition instance",
                                     self.name)

            self._origPath = self.path
            self.probe()
            if self.getFlag(parted.PARTITION_PREP):
                # the only way to identify a PPC PReP Boot partition is to
                # check the partition type/flags, so do it here.
                self.format = getFormat("prepboot",
                                        device=self.path,
                                        exists=True)
        else:
            # XXX It might be worthwhile to create a shit-simple
            #     PartitionRequest class and pass one to this constructor
            #     for new partitions.
            if not self._size:
                # default size for new partition requests
                self._size = self.defaultSize
            self.req_name = name
            self.req_partType = partType
            self.req_primary = primary
            self.req_max_size = numeric_type(maxsize)
            self.req_grow = grow
            self.req_bootable = bootable

            # req_size may be manipulated in the course of partitioning
            self.req_size = self._size

            # req_base_size will always remain constant
            self.req_base_size = self._size

            self.req_base_weight = weight
Ejemplo n.º 11
0
    def __init__(
        self,
        name,
        parents,
        size=None,
        free=None,
        peSize=None,
        peCount=None,
        peFree=None,
        pvCount=None,
        uuid=None,
        exists=None,
        sysfsPath="",
    ):
        """ Create a VolumeGroup instance.

            Arguments:

                name -- the device name (generally a device node's basename)
                parents -- a list of physical volumes (Device)

            Keyword Arguments:

                peSize -- physical extent size (in MB)
                exists -- indicates whether this is an existing device
                sysfsPath -- sysfs device path

                For existing VG's only:

                    size -- the VG's size (in MB)
                    free -- amount of free space in the VG
                    peFree -- number of free extents
                    peCount -- total number of extents
                    pvCount -- number of PVs in this VG
                    uuid -- the VG's UUID

        """
        self.pvClass = get_device_format("lvmpv")
        if not self.pvClass:
            raise VolumeGroupError("cannot find 'lvmpv' class")

        if isinstance(parents, list):
            for dev in parents:
                if not isinstance(dev.format, self.pvClass):
                    raise ValueError("constructor requires a list of PVs")
        elif not isinstance(parents.format, self.pvClass):
            raise ValueError("constructor requires a list of PVs")

        DeviceMapper.__init__(self, name, parents=parents, exists=exists, sysfsPath=sysfsPath)

        self.uuid = uuid
        self.free = numeric_type(free)
        self.peSize = numeric_type(peSize)
        self.peCount = numeric_type(peCount)
        self.peFree = numeric_type(peFree)
        self.pvCount = numeric_type(pvCount)
        self.lv_names = []
        self.lv_uuids = []
        self.lv_sizes = []
        self.lv_attr = []
        self.hasDuplicate = False

        # circular references, here I come
        self._lvs = []

        # TODO: validate peSize if given
        if not self.peSize:
            self.peSize = 32.0  # MB

        if not self.exists:
            self.pvCount = len(self.parents)
Ejemplo n.º 12
0
    def __init__(self, name, level=None, major=None, minor=None, size=None,
                 memberDevices=None, totalDevices=None,
                 uuid=None, format=None, exists=None,
                 parents=None, sysfsPath=''):
        """ Create a RaidArray instance.

            Arguments:

                name -- the device name (generally a device node's basename)

            Keyword Arguments:

                level -- the device's RAID level (a string, eg: '1' or 'raid1')
                parents -- list of member devices (Device instances)
                size -- the device's size (units/format TBD)
                uuid -- the device's UUID
                minor -- the device minor
                sysfsPath -- sysfs device path
                format -- a DeviceFormat instance
                exists -- indicates whether this is an existing device
        """
        Device.__init__(self, name, format=format, exists=exists,
                               major=major, minor=minor, size=size,
                               parents=parents, sysfsPath=sysfsPath)

        self.level = level
        if level == "container":
            self._type = "mdcontainer"
        elif level is not None:
            self.level = raid.raidLevel(level)

        # For new arrays check if we have enough members
        if (not exists and parents and
                len(parents) < raid.get_raid_min_members(self.level)):
            raise ValueError, _("A RAID%(level)d set requires at least %(min_member)d member") % \
                                {"level":self.level, "min_member":raid.get_raid_min_members(self.level)}

        self.uuid = uuid
        self._totalDevices = numeric_type(totalDevices)
        self._memberDevices = numeric_type(memberDevices)
        self.sysfsPath = "/devices/virtual/block/%s" % name
        self.chunkSize = 512.0 / 1024.0         # chunk size in MB
        self.superBlockSize = 2.0               # superblock size in MB

        self.createMetadataVer = "1.1"
        # bitmaps are not meaningful on raid0 according to mdadm-3.0.3
        self.createBitmap = self.level != 0

        # For container members probe size now, as we cannot determine it
        # when teared down.
        if self.parents and self.parents[0].type == "mdcontainer":
            self._size = self.currentSize
            self._type = "mdbiosraidarray"

        self.formatClass = get_device_format("mdmember")
        if not self.formatClass:
            raise RaidArrayError("cannot find class for 'mdmember'", self.name)

        if self.exists and self.uuid:
            # this is a hack to work around mdadm's insistence on giving
            # really high minors to arrays it has no config entry for
            open("/etc/mdadm.conf", "a").write("ARRAY %s UUID=%s\n"
                                                % (self.path, self.uuid))
Ejemplo n.º 13
0
    def __init__(self,
                 name,
                 level=None,
                 major=None,
                 minor=None,
                 size=None,
                 memberDevices=None,
                 totalDevices=None,
                 uuid=None,
                 format=None,
                 exists=None,
                 parents=None,
                 sysfsPath=''):
        """ Create a RaidArray instance.

            Arguments:

                name -- the device name (generally a device node's basename)

            Keyword Arguments:

                level -- the device's RAID level (a string, eg: '1' or 'raid1')
                parents -- list of member devices (Device instances)
                size -- the device's size (units/format TBD)
                uuid -- the device's UUID
                minor -- the device minor
                sysfsPath -- sysfs device path
                format -- a DeviceFormat instance
                exists -- indicates whether this is an existing device
        """
        Device.__init__(self,
                        name,
                        format=format,
                        exists=exists,
                        major=major,
                        minor=minor,
                        size=size,
                        parents=parents,
                        sysfsPath=sysfsPath)

        self.level = level
        if level == "container":
            self._type = "mdcontainer"
        elif level is not None:
            self.level = raid.raidLevel(level)

        # For new arrays check if we have enough members
        if (not exists and parents
                and len(parents) < raid.get_raid_min_members(self.level)):
            raise ValueError, _("A RAID%(level)d set requires at least %(min_member)d member") % \
                                {"level":self.level, "min_member":raid.get_raid_min_members(self.level)}

        self.uuid = uuid
        self._totalDevices = numeric_type(totalDevices)
        self._memberDevices = numeric_type(memberDevices)
        self.sysfsPath = "/devices/virtual/block/%s" % name
        self.chunkSize = 512.0 / 1024.0  # chunk size in MB
        self.superBlockSize = 2.0  # superblock size in MB

        self.createMetadataVer = "1.1"
        # bitmaps are not meaningful on raid0 according to mdadm-3.0.3
        self.createBitmap = self.level != 0

        # For container members probe size now, as we cannot determine it
        # when teared down.
        if self.parents and self.parents[0].type == "mdcontainer":
            self._size = self.currentSize
            self._type = "mdbiosraidarray"

        self.formatClass = get_device_format("mdmember")
        if not self.formatClass:
            raise RaidArrayError("cannot find class for 'mdmember'", self.name)

        if self.exists and self.uuid:
            # this is a hack to work around mdadm's insistence on giving
            # really high minors to arrays it has no config entry for
            open("/etc/mdadm.conf",
                 "a").write("ARRAY %s UUID=%s\n" % (self.path, self.uuid))