def resourceExists(self, resourceName): try: lvm.getLV(self._vg, resourceName) res = True except se.LogicalVolumeDoesNotExistError: res = False return res
def create( cls, repoPath, sdUUID, imgUUID, size, volFormat, preallocate, diskType, volUUID, desc, srcImgUUID, srcVolUUID ): """ Create a new volume with given size or snapshot 'size' - in sectors 'volFormat' - volume format COW / RAW 'preallocate' - Prealocate / Sparse 'diskType' - string that describes disk type System|Data|Shared|Swap|Temp 'srcImgUUID' - source image UUID 'srcVolUUID' - source volume UUID """ if not volUUID: volUUID = str(uuid.uuid4()) if volUUID == volume.BLANK_UUID: raise se.InvalidParameterException("volUUID", volUUID) # Validate volume parameters should be checked here for all # internal flows using volume creation. cls.validateCreateVolumeParams(volFormat, preallocate, srcVolUUID) mysd = sdCache.produce(sdUUID=sdUUID) try: lvm.getLV(sdUUID, volUUID) except se.LogicalVolumeDoesNotExistError: pass # OK, this is a new volume else: raise se.VolumeAlreadyExists(volUUID) imageDir = image.Image(repoPath).create(sdUUID, imgUUID) vol_path = os.path.join(imageDir, volUUID) pvol = None voltype = "LEAF" try: if srcVolUUID != volume.BLANK_UUID: # We have a parent if srcImgUUID == volume.BLANK_UUID: srcImgUUID = imgUUID pvol = BlockVolume(repoPath, sdUUID, srcImgUUID, srcVolUUID) # Cannot create snapshot for ILLEGAL volume if not pvol.isLegal(): raise se.createIllegalVolumeSnapshotError(pvol.volUUID) if imgUUID != srcImgUUID: pvol.share(imageDir, hard=False) pvol = BlockVolume(repoPath, sdUUID, imgUUID, srcVolUUID) # override size param by parent's size size = pvol.getSize() except se.StorageException: cls.log.error("Unexpected error", exc_info=True) raise except Exception, e: cls.log.error("Unexpected error", exc_info=True) raise se.VolumeCannotGetParent( "blockVolume can't get parent %s for volume %s: %s" % (srcVolUUID, volUUID, str(e)) )
def volumeExists(self, imgPath, volUUID): """ Return True if the volume volUUID exists """ try: lvm.getLV(self.sdUUID, volUUID) except se.LogicalVolumeDoesNotExistError: return False return True
def create(cls, repoPath, sdUUID, imgUUID, size, volFormat, preallocate, diskType, volUUID, desc, srcImgUUID, srcVolUUID): """ Create a new volume with given size or snapshot 'size' - in sectors 'volFormat' - volume format COW / RAW 'preallocate' - Prealocate / Sparse 'diskType' - string that describes disk type System|Data|Shared|Swap|Temp 'srcImgUUID' - source image UUID 'srcVolUUID' - source volume UUID """ if not volUUID: volUUID = str(uuid.uuid4()) if volUUID == volume.BLANK_UUID: raise se.InvalidParameterException("volUUID", volUUID) # Validate volume parameters should be checked here for all # internal flows using volume creation. cls.validateCreateVolumeParams(volFormat, preallocate, srcVolUUID) mysd = sdCache.produce(sdUUID=sdUUID) try: lvm.getLV(sdUUID, volUUID) except se.LogicalVolumeDoesNotExistError: pass #OK, this is a new volume else: raise se.VolumeAlreadyExists(volUUID) imageDir = image.Image(repoPath).create(sdUUID, imgUUID) vol_path = os.path.join(imageDir, volUUID) pvol = None voltype = "LEAF" try: if srcVolUUID != volume.BLANK_UUID: # We have a parent if srcImgUUID == volume.BLANK_UUID: srcImgUUID = imgUUID pvol = BlockVolume(repoPath, sdUUID, srcImgUUID, srcVolUUID) # Cannot create snapshot for ILLEGAL volume if not pvol.isLegal(): raise se.createIllegalVolumeSnapshotError(pvol.volUUID) if imgUUID != srcImgUUID: pvol.share(imageDir, hard=False) pvol = BlockVolume(repoPath, sdUUID, imgUUID, srcVolUUID) # override size param by parent's size size = pvol.getSize() except se.StorageException: cls.log.error("Unexpected error", exc_info=True) raise except Exception, e: cls.log.error("Unexpected error", exc_info=True) raise se.VolumeCannotGetParent( "blockVolume can't get parent %s for volume %s: %s" % (srcVolUUID, volUUID, str(e)))
def halfbakedVolumeRollback(cls, taskObj, sdUUID, volUUID, volPath): cls.log.info("sdUUID=%s volUUID=%s volPath=%s" % (sdUUID, volUUID, volPath)) try: #Fix me: assert resource lock. lvm.getLV(sdUUID, volUUID) lvm.removeLVs(sdUUID, volUUID) except se.LogicalVolumeDoesNotExistError, e: pass #It's OK: inexistent LV, don't try to remove.
def findImagesByVolume(self, legal=False): """ Find the image(s) UUID by one of its volume UUID. Templated and shared disks volumes may result more then one image. """ lvs = lvm.getLV(self.sdUUID) imgUUIDs = [self.imgUUID] #Add volume image for lv in lvs: imgUUID = "" parent = "" for tag in lv.tags: if tag.startswith(TAG_PREFIX_IMAGE): imgUUID = tag[len(TAG_PREFIX_IMAGE):] elif tag.startswith(TAG_PREFIX_PARENT): if tag[len(TAG_PREFIX_PARENT):] != self.volUUID: break #Not a child parent = tag[len(TAG_PREFIX_PARENT):] if parent and image: if imgUUID not in imgUUIDs: imgUUIDs.append(imgUUID) break # Check image legallity, if needed if legal: for imgUUID in imgUUIDs[:]: if not image.Image(self.repoPath).isLegal( self.sdUUID, imgUUID): imgUUIDs.remove(imgUUID) return imgUUIDs
def _postZero(sdUUID, volumes): # Assumed that there is no any thread that can deactivate these LVs # on this host or change the rw permission on this or any other host. lvNames = tuple(vol.volUUID for vol in volumes) # Assert volumes are writable. (Don't do this at home.) try: lvm.changelv(sdUUID, lvNames, ("--permission", "rw")) except se.StorageException: # Hope this only means that some volumes were already writable. pass lvm.activateLVs(sdUUID, lvNames) for lv in lvm.getLV(sdUUID): if lv.name in lvNames: # wipe out the whole volume try: misc.ddWatchCopy( "/dev/zero", lvm.lvPath(sdUUID, lv.name), vars.task.aborting, int(lv.size), recoveryCallback=volume.baseAsyncTasksRollback) except utils.ActionStopped: raise except Exception: raise se.VolumesZeroingError(lv.name)
def halfbakedVolumeRollback(cls, taskObj, sdUUID, volUUID, volPath): cls.log.info("sdUUID=%s volUUID=%s volPath=%s" % (sdUUID, volUUID, volPath)) try: # Fix me: assert resource lock. lvm.getLV(sdUUID, volUUID) lvm.removeLVs(sdUUID, volUUID) except se.LogicalVolumeDoesNotExistError: pass # It's OK: inexistent LV, don't try to remove. except se.CannotRemoveLogicalVolume as e: cls.log.warning("Remove logical volume failed %s/%s %s", sdUUID, volUUID, str(e)) if os.path.lexists(volPath): os.unlink(volPath)
def _getOccupiedMetadataSlots(self): stripPrefix = lambda s, pfx: s[len(pfx):] occupiedSlots = [] for lv in lvm.getLV(self.sdUUID): if lv.name in SPECIAL_LVS: # Special LVs have no mapping continue offset = None size = blockVolume.VOLUME_MDNUMBLKS for tag in lv.tags: if tag.startswith(blockVolume.TAG_PREFIX_MD): offset = int(stripPrefix(tag, blockVolume.TAG_PREFIX_MD)) if tag.startswith(blockVolume.TAG_PREFIX_MDNUMBLKS): size = int(stripPrefix(tag, blockVolume.TAG_PREFIX_MDNUMBLKS)) if offset is not None and size != blockVolume.VOLUME_MDNUMBLKS: # I've found everything I need break if offset is None: self.log.warn("Could not find mapping for lv %s/%s", self.sdUUID, lv.name) continue occupiedSlots.append((offset, size)) occupiedSlots.sort(key=itemgetter(0)) return occupiedSlots
def format(cls, sdUUID): """Format detached storage domain. This removes all data from the storage domain. """ # Remove the directory tree try: domaindir = cls.findDomainPath(sdUUID) except (se.StorageDomainDoesNotExist): pass else: fileUtils.cleanupdir(domaindir, ignoreErrors=True) # Remove special metadata and service volumes # Remove all volumes LV if exists _removeVMSfs(lvm.lvPath(sdUUID, MASTERLV)) try: lvs = lvm.getLV(sdUUID) except se.LogicalVolumeDoesNotExistError: lvs = () # No LVs in this VG (domain) for lv in lvs: # Fix me: Should raise and get resource lock. try: lvm.removeLVs(sdUUID, lv.name) except se.CannotRemoveLogicalVolume as e: cls.log.warning("Remove logical volume failed %s/%s %s", sdUUID, lv.name, str(e)) lvm.removeVG(sdUUID) return True
def findImagesByVolume(self, legal=False): """ Find the image(s) UUID by one of its volume UUID. Templated and shared disks volumes may result more then one image. """ lvs = lvm.getLV(self.sdUUID) imgUUIDs = [self.imgUUID] #Add volume image for lv in lvs: imgUUID = "" parent = "" for tag in lv.tags: if tag.startswith(TAG_PREFIX_IMAGE): imgUUID = tag[len(TAG_PREFIX_IMAGE):] elif tag.startswith(TAG_PREFIX_PARENT): if tag[len(TAG_PREFIX_PARENT):] != self.volUUID: break #Not a child parent = tag[len(TAG_PREFIX_PARENT):] if parent and image: if imgUUID not in imgUUIDs: imgUUIDs.append(imgUUID) break # Check image legallity, if needed if legal: for imgUUID in imgUUIDs[:]: if not image.Image(self.repoPath).isLegal(self.sdUUID, imgUUID): imgUUIDs.remove(imgUUID) return imgUUIDs
def getVolumeTag(sdUUID, volUUID, tagPrefix): tags = lvm.getLV(sdUUID, volUUID).tags if sc.TAG_VOL_UNINIT in tags: log.warning("Reloading uninitialized volume %s/%s", sdUUID, volUUID) lvm.invalidateVG(sdUUID) tags = lvm.getLV(sdUUID, volUUID).tags if sc.TAG_VOL_UNINIT in tags: log.error("Found uninitialized volume: %s/%s", sdUUID, volUUID) raise se.VolumeDoesNotExist("%s/%s" % (sdUUID, volUUID)) for tag in tags: if tag.startswith(tagPrefix): return tag[len(tagPrefix):] else: log.error("Missing tag %s in volume: %s/%s. tags: %s", tagPrefix, sdUUID, volUUID, tags) raise se.MissingTagOnLogicalVolume(volUUID, tagPrefix)
def _getVolumeTag(sdUUID, volUUID, tagPrefix): tags = lvm.getLV(sdUUID, volUUID).tags if TAG_VOL_UNINIT in tags: log.warning("Reloading uninitialized volume %s/%s", sdUUID, volUUID) lvm.invalidateVG(sdUUID) tags = lvm.getLV(sdUUID, volUUID).tags if TAG_VOL_UNINIT in tags: log.error("Found uninitialized volume: %s/%s", sdUUID, volUUID) raise se.VolumeDoesNotExist("%s/%s" % (sdUUID, volUUID)) for tag in tags: if tag.startswith(tagPrefix): return tag[len(tagPrefix):] else: log.error("Missing tag %s in volume: %s/%s. tags: %s", tagPrefix, sdUUID, volUUID, tags) raise se.MissingTagOnLogicalVolume(volUUID, tagPrefix)
def getMetaOffset(self): if self.metaoff: return self.metaoff l = lvm.getLV(self.sdUUID, self.volUUID).tags for t in l: if t.startswith(TAG_PREFIX_MD): return int(t[3:]) self.log.error("missing offset tag on volume %s", self.volUUID) raise se.VolumeMetadataReadError("missing offset tag on volume %s" % self.volUUID)
def validate(self): try: lv = lvm.getLV(self.sdUUID, self.volUUID) except se.LogicalVolumeDoesNotExistError: raise se.VolumeDoesNotExist(self.volUUID) else: if sc.TEMP_VOL_LVTAG in lv.tags: self.log.warning("Tried to produce a volume artifact: %s/%s", self.sdUUID, self.volUUID) raise se.VolumeDoesNotExist(self.volUUID) volume.VolumeManifest.validate(self)
def getVSize(cls, sdobj, imgUUID, volUUID, bs=512): try: return _getDeviceSize(lvm.lvPath(sdobj.sdUUID, volUUID)) / bs except OSError: # This is OK, the volume might not be active. Try the traditional # way pass except Exception: cls.log.warn( "Could not get size for vol %s/%s using optimized methods", sdobj.sdUUID, volUUID, exc_info=True ) return int(int(lvm.getLV(sdobj.sdUUID, volUUID).size) / bs)
def getVSize(self, imgUUID, volUUID): """ Return the block volume size in bytes. """ try: size = _tellEnd(lvm.lvPath(self.sdUUID, volUUID)) except IOError as e: if e.errno == os.errno.ENOENT: # Inactive volume has no /dev entry. Fallback to lvm way. size = lvm.getLV(self.sdUUID, volUUID).size else: self.log.warn("Could not get size for vol %s/%s", self.sdUUID, volUUID, exc_info=True) raise return int(size)
def changeVolumeTag(self, tagPrefix, uuid): if tagPrefix not in VOLUME_TAGS: raise se.LogicalVolumeWrongTagError(tagPrefix) oldTag = "" for tag in lvm.getLV(self.sdUUID, self.volUUID).tags: if tag.startswith(tagPrefix): oldTag = tag break if not oldTag: raise se.MissingTagOnLogicalVolume(self.volUUID, tagPrefix) newTag = tagPrefix + uuid if oldTag != newTag: lvm.replaceLVTag(self.sdUUID, self.volUUID, oldTag, newTag)
def getVSize(cls, sdobj, imgUUID, volUUID, bs=BLOCK_SIZE): """ Returns size in block units. Returns the largest integer value less than or equal to size [blocks]. """ try: size = _tellEnd(lvm.lvPath(sdobj.sdUUID, volUUID)) / bs except IOError as e: if e.errno == os.errno.ENOENT: # Inactive volume has no /dev entry. Fallback to lvm way. size = int(int(lvm.getLV(sdobj.sdUUID, volUUID).size) / bs) else: cls.log.warn("Could not get size for vol %s/%s", sdobj.sdUUID, volUUID, exc_info=True) raise return size
def getAllImages(self): """ Get list of all images """ try: lvs = lvm.getLV(self.sdUUID) except se.LogicalVolumeDoesNotExistError: lvs = () # No LVs in this VG (domain) # Collect all the tags from all the volumes, but ignore duplicates # set conveniently does exactly that tags = set() for lv in lvs: tags.update(lv.tags) # Drop non image tags and strip prefix taglen = len(blockVolume.TAG_PREFIX_IMAGE) images = [i[taglen:] for i in tags if i.startswith(blockVolume.TAG_PREFIX_IMAGE)] return images
def _getVolsTree(sdUUID): lvs = lvm.getLV(sdUUID) vols = {} for lv in lvs: image = "" parent = "" for tag in lv.tags: if tag.startswith(blockVolume.TAG_PREFIX_IMAGE): image = tag[len(blockVolume.TAG_PREFIX_IMAGE) :] elif tag.startswith(blockVolume.TAG_PREFIX_PARENT): parent = tag[len(blockVolume.TAG_PREFIX_PARENT) :] if parent and image: vols[lv.name] = BlockSDVol(lv.name, image, parent) break else: if lv.name not in SPECIAL_LVS: log.warning("Ignoring Volume %s that lacks minimal tag set" "tags %s" % (lv.name, lv.tags)) return vols
def _getVolsTree(sdUUID): lvs = lvm.getLV(sdUUID) vols = {} for lv in lvs: image = "" parent = "" for tag in lv.tags: if tag.startswith(blockVolume.TAG_PREFIX_IMAGE): image = tag[len(blockVolume.TAG_PREFIX_IMAGE):] elif tag.startswith(blockVolume.TAG_PREFIX_PARENT): parent = tag[len(blockVolume.TAG_PREFIX_PARENT):] if parent and image: vols[lv.name] = BlockSDVol(lv.name, image, parent) break else: if lv.name not in SPECIAL_LVS: log.warning("Ignoring Volume %s that lacks minimal tag set" "tags %s" % (lv.name, lv.tags)) return vols
def halfbakedVolumeRollback(cls, taskObj, sdUUID, volUUID, volPath): cls.log.info("sdUUID=%s volUUID=%s volPath=%s" % (sdUUID, volUUID, volPath)) try: # Fix me: assert resource lock. tags = lvm.getLV(sdUUID, volUUID).tags except se.LogicalVolumeDoesNotExistError: pass # It's OK: inexistent LV, don't try to remove. else: if TAG_VOL_UNINIT in tags: try: lvm.removeLVs(sdUUID, volUUID) except se.CannotRemoveLogicalVolume as e: cls.log.warning("Remove logical volume failed %s/%s %s", sdUUID, volUUID, str(e)) if os.path.lexists(volPath): cls.log.debug("Unlinking half baked volume: %s", volPath) os.unlink(volPath)
def getAllImages(self): """ Get list of all images """ try: lvs = lvm.getLV(self.sdUUID) except se.LogicalVolumeDoesNotExistError: lvs = () #No LVs in this VG (domain) # Collect all the tags from all the volumes, but ignore duplicates # set conveniently does exactly that tags = set() for lv in lvs: tags.update(lv.tags) # Drop non image tags and strip prefix taglen = len(blockVolume.TAG_PREFIX_IMAGE) images = [ i[taglen:] for i in tags if i.startswith(blockVolume.TAG_PREFIX_IMAGE) ] return images
def validate(self): try: lvm.getLV(self.sdUUID, self.volUUID) except se.LogicalVolumeDoesNotExistError: raise se.VolumeDoesNotExist(self.volUUID) #Fix me volume.Volume.validate(self)
def getLeasesFileSize(self): lv = lvm.getLV(self.sdUUID, sd.LEASES) return int(lv.size)
def create(cls, sdUUID, domainName, domClass, vgUUID, storageType, version): """ Create new storage domain 'sdUUID' - Storage Domain UUID 'domainName' - storage domain name 'domClass' - Data/Iso 'vgUUID' - volume group UUID 'storageType' - NFS_DOMAIN, LOCALFS_DOMAIN, &etc. 'version' - DOMAIN_VERSIONS """ cls.log.info("sdUUID=%s domainName=%s domClass=%s vgUUID=%s " "storageType=%s version=%s", sdUUID, domainName, domClass, vgUUID, storageType, version) if not misc.isAscii(domainName) and not sd.supportsUnicode(version): raise se.UnicodeArgumentException() if len(domainName) > sd.MAX_DOMAIN_DESCRIPTION_SIZE: raise se.StorageDomainDescriptionTooLongError() sd.validateDomainVersion(version) vg = lvm.getVGbyUUID(vgUUID) vgName = vg.name if set((STORAGE_UNREADY_DOMAIN_TAG,)) != set(vg.tags): raise se.VolumeGroupHasDomainTag(vgUUID) try: lvm.getLV(vgName) raise se.StorageDomainNotEmpty(vgUUID) except se.LogicalVolumeDoesNotExistError: pass numOfPVs = len(lvm.listPVNames(vgName)) if version in VERS_METADATA_LV and numOfPVs > MAX_PVS: cls.log.debug("%d > %d", numOfPVs, MAX_PVS) raise se.StorageDomainIsMadeFromTooManyPVs() # Create metadata service volume metasize = cls.metaSize(vgName) lvm.createLV(vgName, sd.METADATA, "%s" % (metasize)) # Create the mapping right now so the index 0 is guaranteed # to belong to the metadata volume. Since the metadata is at # least SDMETADATA/METASIZE units, we know we can use the first # SDMETADATA bytes of the metadata volume for the SD metadata. # pass metadata's dev to ensure it is the first mapping mapping = cls.getMetaDataMapping(vgName) # Create the rest of the BlockSD internal volumes lvm.createLV(vgName, sd.LEASES, sd.LEASES_SIZE) lvm.createLV(vgName, sd.IDS, sd.IDS_SIZE) lvm.createLV(vgName, sd.INBOX, sd.INBOX_SIZE) lvm.createLV(vgName, sd.OUTBOX, sd.OUTBOX_SIZE) lvm.createLV(vgName, MASTERLV, MASTERLV_SIZE) # Create VMS file system _createVMSfs(os.path.join("/dev", vgName, MASTERLV)) lvm.deactivateLVs(vgName, MASTERLV) path = lvm.lvPath(vgName, sd.METADATA) # Zero out the metadata and special volumes before use try: misc.ddCopy("/dev/zero", path, RESERVED_METADATA_SIZE) path = lvm.lvPath(vgName, sd.INBOX) misc.ddCopy("/dev/zero", path, RESERVED_MAILBOX_SIZE) path = lvm.lvPath(vgName, sd.OUTBOX) misc.ddCopy("/dev/zero", path, RESERVED_MAILBOX_SIZE) except utils.ActionStopped: raise except se.StorageException: raise se.VolumesZeroingError(path) if version in VERS_METADATA_LV: md = LvBasedSDMetadata(vgName, sd.METADATA) elif version in VERS_METADATA_TAG: md = TagBasedSDMetadata(vgName) logBlkSize, phyBlkSize = lvm.getVGBlockSizes(vgName) # create domain metadata # FIXME : This is 99% like the metadata in file SD # Do we really need to keep the VGUUID? # no one reads it from here anyway initialMetadata = { sd.DMDK_VERSION: version, sd.DMDK_SDUUID: sdUUID, sd.DMDK_TYPE: storageType, sd.DMDK_CLASS: domClass, sd.DMDK_DESCRIPTION: domainName, sd.DMDK_ROLE: sd.REGULAR_DOMAIN, sd.DMDK_POOLS: [], sd.DMDK_LOCK_POLICY: '', sd.DMDK_LOCK_RENEWAL_INTERVAL_SEC: sd.DEFAULT_LEASE_PARAMS[ sd.DMDK_LOCK_RENEWAL_INTERVAL_SEC], sd.DMDK_LEASE_TIME_SEC: sd.DEFAULT_LEASE_PARAMS[ sd.DMDK_LEASE_TIME_SEC], sd.DMDK_IO_OP_TIMEOUT_SEC: sd.DEFAULT_LEASE_PARAMS[ sd.DMDK_IO_OP_TIMEOUT_SEC], sd.DMDK_LEASE_RETRIES: sd.DEFAULT_LEASE_PARAMS[ sd.DMDK_LEASE_RETRIES], DMDK_VGUUID: vgUUID, DMDK_LOGBLKSIZE: logBlkSize, DMDK_PHYBLKSIZE: phyBlkSize, } initialMetadata.update(mapping) md.update(initialMetadata) # Mark VG with Storage Domain Tag try: lvm.replaceVGTag(vgName, STORAGE_UNREADY_DOMAIN_TAG, STORAGE_DOMAIN_TAG) except se.StorageException: raise se.VolumeGroupUninitialized(vgName) bsd = BlockStorageDomain(sdUUID) bsd.initSPMlease() return bsd
def _getVolumeTag(sdUUID, volUUID, tagPrefix): for tag in lvm.getLV(sdUUID, volUUID).tags: if tag.startswith(tagPrefix): return tag[len(tagPrefix):] raise se.MissingTagOnLogicalVolume(volUUID, tagPrefix)
return tag[len(tagPrefix):] raise se.MissingTagOnLogicalVolume(volUUID, tagPrefix) def _postZero(sdUUID, volumes): #Assumed here that the volume is active. #To activate all the volumes of an image at once get its resource. #See http://gerrit.usersys.redhat.com/771 #Assert volumes are writable. (Don't do this at home.) lvNames = (vol.volUUID for vol in volumes) try: lvm.changelv(sdUUID, lvNames, "--permission", "rw") except se.StorageException, e: #Hope this only means that some volumes were already writable pass for lv in lvm.getLV(sdUUID): if lv.name in lvNames: # wipe out the whole volume try: misc.ddWatchCopy("/dev/zero", lvm.lvPath(sdUUID, lv.name), vars.task.aborting, int(lv.size), recoveryCallback=volume.baseAsyncTasksRollback) except se.ActionStopped, e: raise e except Exception, e: raise se.VolumesZeroingError(lv.name) def deleteMultipleVolumes(sdUUID, volumes, postZero): "Delete multiple volumes (LVs) in the same domain (VG).""" if postZero: _postZero(sdUUID, volumes) lvNames = [vol.volUUID for vol in volumes]
def validate(self): try: lvm.getLV(self.sdUUID, self.volUUID) except se.LogicalVolumeDoesNotExistError: raise se.VolumeDoesNotExist(self.volUUID) volume.VolumeMetadata.validate(self)
def create(cls, sdUUID, domainName, domClass, vgUUID, storageType, version): """ Create new storage domain 'sdUUID' - Storage Domain UUID 'domainName' - storage domain name 'vgUUID' - volume group UUID 'domClass' - Data/Iso """ cls.log.info("sdUUID=%s domainName=%s domClass=%s vgUUID=%s " "storageType=%s version=%s", sdUUID, domainName, domClass, vgUUID, storageType, version) if len(domainName) > sd.MAX_DOMAIN_DESCRIPTION_SIZE: raise se.StorageDomainDescriptionTooLongError() sd.validateDomainVersion(version) vg = lvm.getVGbyUUID(vgUUID) vgName = vg.name if set((STORAGE_UNREADY_DOMAIN_TAG,)) != set(vg.tags): raise se.VolumeGroupHasDomainTag(vgUUID) try: lvm.getLV(vgName) raise se.StorageDomainNotEmpty(vgUUID) except se.LogicalVolumeDoesNotExistError: pass numOfPVs = len(lvm.listPVNames(vgName)) if version in VERS_METADATA_LV and numOfPVs > MAX_PVS: cls.log.debug("%d > %d" , numOfPVs, MAX_PVS) raise se.StorageDomainIsMadeFromTooManyPVs() # Set the name of the VG to be the same as sdUUID if vgName != sdUUID: lvm.renameVG(vgName, sdUUID) vgName = sdUUID # Create metadata service volume metasize = cls.metaSize(vgName) lvm.createLV(vgName, sd.METADATA, "%s" % (metasize)) # Create the mapping right now so the index 0 is guaranteed # to belong to the metadata volume. Since the metadata is at # least SDMETADATA/METASIZE units, we know we can use the first # SDMETADATA bytes of the metadata volume for the SD metadata. # pass metadata's dev to ensure it is the first mapping mapping = cls.getMetaDataMapping(vgName) # Create the rest of the BlockSD internal volumes lvm.createLV(vgName, sd.LEASES, sd.LEASES_SIZE) lvm.createLV(vgName, sd.IDS, sd.IDS_SIZE) lvm.createLV(vgName, sd.INBOX, sd.INBOX_SIZE) lvm.createLV(vgName, sd.OUTBOX, sd.OUTBOX_SIZE) lvm.createLV(vgName, MASTERLV, MASTERLV_SIZE) # Create VMS file system _createVMSfs(os.path.join("/dev", vgName, MASTERLV)) lvm.deactivateLVs(vgName, MASTERLV) path = lvm.lvPath(vgName, sd.METADATA) # Zero out the metadata and special volumes before use try: misc.ddCopy("/dev/zero", path, RESERVED_METADATA_SIZE) path = lvm.lvPath(vgName, sd.INBOX) misc.ddCopy("/dev/zero", path, RESERVED_MAILBOX_SIZE) path = lvm.lvPath(vgName, sd.OUTBOX) misc.ddCopy("/dev/zero", path, RESERVED_MAILBOX_SIZE) except se.ActionStopped, e: raise e
raise se.MissingTagOnLogicalVolume(volUUID, tagPrefix) def _postZero(sdUUID, volumes): #Assumed here that the volume is active. #To activate all the volumes of an image at once get its resource. #See http://gerrit.usersys.redhat.com/771 #Assert volumes are writable. (Don't do this at home.) lvNames = (vol.volUUID for vol in volumes) try: lvm.changelv(sdUUID, lvNames, "--permission", "rw") except se.StorageException, e: #Hope this only means that some volumes were already writable pass for lv in lvm.getLV(sdUUID): if lv.name in lvNames: # wipe out the whole volume try: misc.ddWatchCopy( "/dev/zero", lvm.lvPath(sdUUID, lv.name), vars.task.aborting, int(lv.size), recoveryCallback=volume.baseAsyncTasksRollback) except se.ActionStopped, e: raise e except Exception, e: raise se.VolumesZeroingError(lv.name)
def getVSize(cls, sdobj, imgUUID, volUUID, bs=512): return int(int(lvm.getLV(sdobj.sdUUID, volUUID).size) / bs)
def create(cls, sdUUID, domainName, domClass, vgUUID, storageType, version): """ Create new storage domain 'sdUUID' - Storage Domain UUID 'domainName' - storage domain name 'domClass' - Data/Iso 'vgUUID' - volume group UUID 'storageType' - NFS_DOMAIN, LOCALFS_DOMAIN, &etc. 'version' - DOMAIN_VERSIONS """ cls.log.info("sdUUID=%s domainName=%s domClass=%s vgUUID=%s " "storageType=%s version=%s", sdUUID, domainName, domClass, vgUUID, storageType, version) if not misc.isAscii(domainName) and not sd.supportsUnicode(version): raise se.UnicodeArgumentException() if len(domainName) > sd.MAX_DOMAIN_DESCRIPTION_SIZE: raise se.StorageDomainDescriptionTooLongError() sd.validateDomainVersion(version) vg = lvm.getVGbyUUID(vgUUID) vgName = vg.name if set((STORAGE_UNREADY_DOMAIN_TAG,)) != set(vg.tags): raise se.VolumeGroupHasDomainTag(vgUUID) try: lvm.getLV(vgName) raise se.StorageDomainNotEmpty(vgUUID) except se.LogicalVolumeDoesNotExistError: pass numOfPVs = len(lvm.listPVNames(vgName)) if version in VERS_METADATA_LV and numOfPVs > MAX_PVS: cls.log.debug("%d > %d", numOfPVs, MAX_PVS) raise se.StorageDomainIsMadeFromTooManyPVs() # Create metadata service volume metasize = cls.metaSize(vgName) lvm.createLV(vgName, sd.METADATA, "%s" % (metasize)) # Create the mapping right now so the index 0 is guaranteed # to belong to the metadata volume. Since the metadata is at # least SDMETADATA/METASIZE units, we know we can use the first # SDMETADATA bytes of the metadata volume for the SD metadata. # pass metadata's dev to ensure it is the first mapping mapping = cls.getMetaDataMapping(vgName) # Create the rest of the BlockSD internal volumes for metaFile, metaSizeMb in sd.SPECIAL_VOLUME_SIZES_MIB.iteritems(): lvm.createLV(vgName, metaFile, metaSizeMb) lvm.createLV(vgName, MASTERLV, MASTERLV_SIZE) # Create VMS file system _createVMSfs(os.path.join("/dev", vgName, MASTERLV)) lvm.deactivateLVs(vgName, MASTERLV) path = lvm.lvPath(vgName, sd.METADATA) # Zero out the metadata and special volumes before use try: misc.ddCopy("/dev/zero", path, RESERVED_METADATA_SIZE) path = lvm.lvPath(vgName, sd.INBOX) misc.ddCopy("/dev/zero", path, RESERVED_MAILBOX_SIZE) path = lvm.lvPath(vgName, sd.OUTBOX) misc.ddCopy("/dev/zero", path, RESERVED_MAILBOX_SIZE) except utils.ActionStopped: raise except se.StorageException: raise se.VolumesZeroingError(path) if version in VERS_METADATA_LV: md = LvBasedSDMetadata(vgName, sd.METADATA) elif version in VERS_METADATA_TAG: md = TagBasedSDMetadata(vgName) logBlkSize, phyBlkSize = lvm.getVGBlockSizes(vgName) # create domain metadata # FIXME : This is 99% like the metadata in file SD # Do we really need to keep the VGUUID? # no one reads it from here anyway initialMetadata = { sd.DMDK_VERSION: version, sd.DMDK_SDUUID: sdUUID, sd.DMDK_TYPE: storageType, sd.DMDK_CLASS: domClass, sd.DMDK_DESCRIPTION: domainName, sd.DMDK_ROLE: sd.REGULAR_DOMAIN, sd.DMDK_POOLS: [], sd.DMDK_LOCK_POLICY: '', sd.DMDK_LOCK_RENEWAL_INTERVAL_SEC: sd.DEFAULT_LEASE_PARAMS[ sd.DMDK_LOCK_RENEWAL_INTERVAL_SEC], sd.DMDK_LEASE_TIME_SEC: sd.DEFAULT_LEASE_PARAMS[ sd.DMDK_LEASE_TIME_SEC], sd.DMDK_IO_OP_TIMEOUT_SEC: sd.DEFAULT_LEASE_PARAMS[ sd.DMDK_IO_OP_TIMEOUT_SEC], sd.DMDK_LEASE_RETRIES: sd.DEFAULT_LEASE_PARAMS[ sd.DMDK_LEASE_RETRIES], DMDK_VGUUID: vgUUID, DMDK_LOGBLKSIZE: logBlkSize, DMDK_PHYBLKSIZE: phyBlkSize, } initialMetadata.update(mapping) md.update(initialMetadata) # Mark VG with Storage Domain Tag try: lvm.replaceVGTag(vgName, STORAGE_UNREADY_DOMAIN_TAG, STORAGE_DOMAIN_TAG) except se.StorageException: raise se.VolumeGroupUninitialized(vgName) bsd = BlockStorageDomain(sdUUID) bsd.initSPMlease() return bsd
def create(cls, sdUUID, domainName, domClass, vgUUID, storageType, version): """ Create new storage domain 'sdUUID' - Storage Domain UUID 'domainName' - storage domain name 'vgUUID' - volume group UUID 'domClass' - Data/Iso """ cls.log.info( "sdUUID=%s domainName=%s domClass=%s vgUUID=%s " "storageType=%s version=%s", sdUUID, domainName, domClass, vgUUID, storageType, version) if len(domainName) > sd.MAX_DOMAIN_DESCRIPTION_SIZE: raise se.StorageDomainDescriptionTooLongError() sd.validateDomainVersion(version) vg = lvm.getVGbyUUID(vgUUID) vgName = vg.name if set((STORAGE_UNREADY_DOMAIN_TAG, )) != set(vg.tags): raise se.VolumeGroupHasDomainTag(vgUUID) try: lvm.getLV(vgName) raise se.StorageDomainNotEmpty(vgUUID) except se.LogicalVolumeDoesNotExistError: pass numOfPVs = len(lvm.listPVNames(vgName)) if version in VERS_METADATA_LV and numOfPVs > MAX_PVS: cls.log.debug("%d > %d", numOfPVs, MAX_PVS) raise se.StorageDomainIsMadeFromTooManyPVs() # Set the name of the VG to be the same as sdUUID if vgName != sdUUID: lvm.renameVG(vgName, sdUUID) vgName = sdUUID # Create metadata service volume metasize = cls.metaSize(vgName) lvm.createLV(vgName, sd.METADATA, "%s" % (metasize)) # Create the mapping right now so the index 0 is guaranteed # to belong to the metadata volume. Since the metadata is at # least SDMETADATA/METASIZE units, we know we can use the first # SDMETADATA bytes of the metadata volume for the SD metadata. # pass metadata's dev to ensure it is the first mapping mapping = cls.getMetaDataMapping(vgName) # Create the rest of the BlockSD internal volumes lvm.createLV(vgName, sd.LEASES, sd.LEASES_SIZE) lvm.createLV(vgName, sd.IDS, sd.IDS_SIZE) lvm.createLV(vgName, sd.INBOX, sd.INBOX_SIZE) lvm.createLV(vgName, sd.OUTBOX, sd.OUTBOX_SIZE) lvm.createLV(vgName, MASTERLV, MASTERLV_SIZE) # Create VMS file system _createVMSfs(os.path.join("/dev", vgName, MASTERLV)) lvm.deactivateLVs(vgName, MASTERLV) path = lvm.lvPath(vgName, sd.METADATA) # Zero out the metadata and special volumes before use try: misc.ddCopy("/dev/zero", path, RESERVED_METADATA_SIZE) path = lvm.lvPath(vgName, sd.INBOX) misc.ddCopy("/dev/zero", path, RESERVED_MAILBOX_SIZE) path = lvm.lvPath(vgName, sd.OUTBOX) misc.ddCopy("/dev/zero", path, RESERVED_MAILBOX_SIZE) except se.ActionStopped, e: raise e