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)
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
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")
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)
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)
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
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
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)
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))