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 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 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) imageDir = image.Image(repoPath).create(sdUUID, imgUUID) vol_path = os.path.join(imageDir, volUUID) voltype = "LEAF" pvol = None # Check if volume already exists if oop.getProcessPool(sdUUID).fileUtils.pathExists(vol_path): raise se.VolumeAlreadyExists(vol_path) # Check if snapshot creation required if srcVolUUID != volume.BLANK_UUID: if srcImgUUID == volume.BLANK_UUID: srcImgUUID = imgUUID pvol = FileVolume(repoPath, sdUUID, srcImgUUID, srcVolUUID) # Cannot create snapshot for ILLEGAL volume if not pvol.isLegal(): raise se.createIllegalVolumeSnapshotError(pvol.volUUID) # create volume rollback vars.task.pushRecovery( task.Recovery("halfbaked volume rollback", "fileVolume", "FileVolume", "halfbakedVolumeRollback", [vol_path])) if preallocate == volume.PREALLOCATED_VOL: try: # ddWatchCopy expects size to be in bytes misc.ddWatchCopy("/dev/zero", vol_path, vars.task.aborting, (int(size) * 512)) except se.ActionStopped, e: raise e except Exception, e: cls.log.error("Unexpected error", exc_info=True) raise se.VolumesZeroingError(vol_path)
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) imageDir = image.Image(repoPath).create(sdUUID, imgUUID) vol_path = os.path.join(imageDir, volUUID) voltype = "LEAF" pvol = None # Check if volume already exists if oop.getProcessPool(sdUUID).fileUtils.pathExists(vol_path): raise se.VolumeAlreadyExists(vol_path) # Check if snapshot creation required if srcVolUUID != volume.BLANK_UUID: if srcImgUUID == volume.BLANK_UUID: srcImgUUID = imgUUID pvol = FileVolume(repoPath, sdUUID, srcImgUUID, srcVolUUID) # Cannot create snapshot for ILLEGAL volume if not pvol.isLegal(): raise se.createIllegalVolumeSnapshotError(pvol.volUUID) # Rollback sentinel, just to mark the start of the task vars.task.pushRecovery(task.Recovery(task.ROLLBACK_SENTINEL, "fileVolume", "FileVolume", "startCreateVolumeRollback", [sdUUID, imgUUID, volUUID])) # create volume rollback vars.task.pushRecovery(task.Recovery("halfbaked volume rollback", "fileVolume", "FileVolume", "halfbakedVolumeRollback", [vol_path])) if preallocate == volume.PREALLOCATED_VOL: try: # ddWatchCopy expects size to be in bytes misc.ddWatchCopy("/dev/zero", vol_path, vars.task.aborting, (int(size) * 512)) except se.ActionStopped, e: raise e except Exception, e: cls.log.error("Unexpected error", exc_info=True) raise se.VolumesZeroingError(vol_path)
def create(cls, repoPath, sdUUID, imgUUID, size, volFormat, preallocate, diskType, volUUID, desc, srcImgUUID, srcVolUUID, initialSize=None): """ Create a new volume with given size or snapshot 'size' - in sectors 'volFormat' - volume format COW / RAW 'preallocate' - Preallocate / Sparse 'diskType' - enum (API.Image.DiskTypes) 'srcImgUUID' - source image UUID 'srcVolUUID' - source volume UUID 'initialSize' - initial volume size in sectors, in case of thin provisioning """ dom = sdCache.produce(sdUUID) dom.validateCreateVolumeParams(volFormat, srcVolUUID, preallocate=preallocate) imgPath = image.Image(repoPath).create(sdUUID, imgUUID) volPath = os.path.join(imgPath, volUUID) volParent = None volType = type2name(LEAF_VOL) # Get the specific class name and class module to be used in the # Recovery tasks. clsModule, clsName = cls._getModuleAndClass() try: if srcVolUUID != BLANK_UUID: # When the srcImgUUID isn't specified we assume it's the same # as the imgUUID if srcImgUUID == BLANK_UUID: srcImgUUID = imgUUID volParent = cls(repoPath, sdUUID, srcImgUUID, srcVolUUID) if not volParent.isLegal(): raise se.createIllegalVolumeSnapshotError( volParent.volUUID) if imgUUID != srcImgUUID: volParent.share(imgPath) volParent = cls(repoPath, sdUUID, imgUUID, srcVolUUID) # Override the size with the size of the parent size = volParent.getSize() except se.StorageException: cls.log.error("Unexpected error", exc_info=True) raise except Exception as e: cls.log.error("Unexpected error", exc_info=True) raise se.VolumeCannotGetParent( "Couldn't get parent %s for volume %s: %s" % (srcVolUUID, volUUID, e)) try: cls.log.info("Creating volume %s", volUUID) # Rollback sentinel to mark the start of the task vars.task.pushRecovery( task.Recovery(task.ROLLBACK_SENTINEL, clsModule, clsName, "startCreateVolumeRollback", [sdUUID, imgUUID, volUUID]) ) # Create volume rollback vars.task.pushRecovery( task.Recovery("Halfbaked volume rollback", clsModule, clsName, "halfbakedVolumeRollback", [sdUUID, volUUID, volPath]) ) # Specific volume creation (block, file, etc...) try: metaId = cls._create(dom, imgUUID, volUUID, size, volFormat, preallocate, volParent, srcImgUUID, srcVolUUID, volPath, initialSize=initialSize) except (se.VolumeAlreadyExists, se.CannotCreateLogicalVolume, se.VolumeCreationError, se.InvalidParameterException) as e: cls.log.error("Failed to create volume %s: %s", volPath, e) vars.task.popRecovery() raise # When the volume format is raw what the guest sees is the apparent # size of the file/device therefore if the requested size doesn't # match the apparent size (eg: physical extent granularity in LVM) # we need to update the size value so that the metadata reflects # the correct state. if volFormat == RAW_FORMAT: apparentSize = int(dom.getVSize(imgUUID, volUUID) / BLOCK_SIZE) if apparentSize < size: cls.log.error("The volume %s apparent size %s is smaller " "than the requested size %s", volUUID, apparentSize, size) raise se.VolumeCreationError() if apparentSize > size: cls.log.info("The requested size for volume %s doesn't " "match the granularity on domain %s, " "updating the volume size from %s to %s", volUUID, sdUUID, size, apparentSize) size = apparentSize vars.task.pushRecovery( task.Recovery("Create volume metadata rollback", clsModule, clsName, "createVolumeMetadataRollback", map(str, metaId)) ) cls.newMetadata(metaId, sdUUID, imgUUID, srcVolUUID, size, type2name(volFormat), type2name(preallocate), volType, diskType, desc, LEGAL_VOL) if dom.hasVolumeLeases(): cls.newVolumeLease(metaId, sdUUID, volUUID) except se.StorageException: cls.log.error("Unexpected error", exc_info=True) raise except Exception as e: cls.log.error("Unexpected error", exc_info=True) raise se.VolumeCreationError("Volume creation %s failed: %s" % (volUUID, e)) # Remove the rollback for the halfbaked volume vars.task.replaceRecoveries( task.Recovery("Create volume rollback", clsModule, clsName, "createVolumeRollback", [repoPath, sdUUID, imgUUID, volUUID, imgPath]) ) return volUUID
def create(cls, repoPath, sdUUID, imgUUID, size, volFormat, preallocate, diskType, volUUID, desc, srcImgUUID, srcVolUUID, initialSize=None): """ Create a new volume with given size or snapshot 'size' - in sectors 'volFormat' - volume format COW / RAW 'preallocate' - Preallocate / Sparse 'diskType' - enum (API.Image.DiskTypes) 'srcImgUUID' - source image UUID 'srcVolUUID' - source volume UUID 'initialSize' - initial volume size in sectors, in case of thin provisioning """ dom = sdCache.produce(sdUUID) dom.validateCreateVolumeParams(volFormat, srcVolUUID, preallocate=preallocate) imgPath = image.Image(repoPath).create(sdUUID, imgUUID) volPath = os.path.join(imgPath, volUUID) volParent = None volType = type2name(LEAF_VOL) # Get the specific class name and class module to be used in the # Recovery tasks. clsModule, clsName = cls._getModuleAndClass() try: if srcVolUUID != BLANK_UUID: # When the srcImgUUID isn't specified we assume it's the same # as the imgUUID if srcImgUUID == BLANK_UUID: srcImgUUID = imgUUID volParent = cls(repoPath, sdUUID, srcImgUUID, srcVolUUID) if not volParent.isLegal(): raise se.createIllegalVolumeSnapshotError( volParent.volUUID) if imgUUID != srcImgUUID: volParent.share(imgPath) volParent = cls(repoPath, sdUUID, imgUUID, srcVolUUID) # Override the size with the size of the parent size = volParent.getSize() except se.StorageException: cls.log.error("Unexpected error", exc_info=True) raise except Exception as e: cls.log.error("Unexpected error", exc_info=True) raise se.VolumeCannotGetParent( "Couldn't get parent %s for volume %s: %s" % (srcVolUUID, volUUID, e)) try: cls.log.info("Creating volume %s", volUUID) # Rollback sentinel to mark the start of the task vars.task.pushRecovery( task.Recovery(task.ROLLBACK_SENTINEL, clsModule, clsName, "startCreateVolumeRollback", [sdUUID, imgUUID, volUUID])) # Create volume rollback vars.task.pushRecovery( task.Recovery("Halfbaked volume rollback", clsModule, clsName, "halfbakedVolumeRollback", [sdUUID, volUUID, volPath])) # Specific volume creation (block, file, etc...) try: metaId = cls._create(dom, imgUUID, volUUID, size, volFormat, preallocate, volParent, srcImgUUID, srcVolUUID, volPath, initialSize=initialSize) except (se.VolumeAlreadyExists, se.CannotCreateLogicalVolume, se.VolumeCreationError, se.InvalidParameterException) as e: cls.log.error("Failed to create volume %s: %s", volPath, e) vars.task.popRecovery() raise # When the volume format is raw what the guest sees is the apparent # size of the file/device therefore if the requested size doesn't # match the apparent size (eg: physical extent granularity in LVM) # we need to update the size value so that the metadata reflects # the correct state. if volFormat == RAW_FORMAT: apparentSize = int(dom.getVSize(imgUUID, volUUID) / BLOCK_SIZE) if apparentSize < size: cls.log.error( "The volume %s apparent size %s is smaller " "than the requested size %s", volUUID, apparentSize, size) raise se.VolumeCreationError() if apparentSize > size: cls.log.info( "The requested size for volume %s doesn't " "match the granularity on domain %s, " "updating the volume size from %s to %s", volUUID, sdUUID, size, apparentSize) size = apparentSize vars.task.pushRecovery( task.Recovery("Create volume metadata rollback", clsModule, clsName, "createVolumeMetadataRollback", map(str, metaId))) cls.newMetadata(metaId, sdUUID, imgUUID, srcVolUUID, size, type2name(volFormat), type2name(preallocate), volType, diskType, desc, LEGAL_VOL) if dom.hasVolumeLeases(): cls.newVolumeLease(metaId, sdUUID, volUUID) except se.StorageException: cls.log.error("Unexpected error", exc_info=True) raise except Exception as e: cls.log.error("Unexpected error", exc_info=True) raise se.VolumeCreationError("Volume creation %s failed: %s" % (volUUID, e)) # Remove the rollback for the halfbaked volume vars.task.replaceRecoveries( task.Recovery("Create volume rollback", clsModule, clsName, "createVolumeRollback", [repoPath, sdUUID, imgUUID, volUUID, imgPath])) return volUUID