Beispiel #1
0
    def rebaseVolumeRollback(cls, taskObj, sdUUID, srcImg,
                             srcVol, dstFormat, srcParent, unsafe):
        """
        Rebase volume rollback
        """
        cls.log.info('rebase volume rollback (sdUUID=%s srcImg=%s srcVol=%s '
                     'dstFormat=%s srcParent=%s)', sdUUID, srcImg, srcVol,
                     dstFormat, srcParent)

        imageResourcesNamespace = sd.getNamespace(
            sdUUID,
            resourceFactories.IMAGE_NAMESPACE)

        with rmanager.acquireResource(imageResourcesNamespace,
                                      srcImg, rm.LockType.exclusive):
            vol = sdCache.produce(sdUUID).produceVolume(srcImg, srcVol)
            vol.prepare(rw=True, chainrw=True, setrw=True)

            volumePath = vol.getVolumePath()
            backingVolPath = getBackingVolumePath(srcImg, srcParent)

            try:
                qemuimg.rebase(volumePath, backingVolPath,
                               fmt2str(vol.getFormat()),
                               fmt2str(int(dstFormat)),
                               misc.parseBool(unsafe), vars.task.aborting)
                vol.setParent(srcParent)
                vol.recheckIfLeaf()
            except qemuimg.QImgError:
                cls.log.exception('cannot rollback rebase for volume %s on '
                                  '%s', volumePath, backingVolPath)
                raise se.MergeVolumeRollbackError(srcVol)
            finally:
                vol.teardown(sdUUID, srcVol)
Beispiel #2
0
    def rebaseVolumeRollback(cls, taskObj, sdUUID, srcImg, srcVol, dstFormat,
                             srcParent, unsafe):
        """
        Rebase volume rollback
        """
        cls.log.info(
            'rebase volume rollback (sdUUID=%s srcImg=%s srcVol=%s '
            'dstFormat=%s srcParent=%s)', sdUUID, srcImg, srcVol, dstFormat,
            srcParent)

        imageResourcesNamespace = sd.getNamespace(sc.IMAGE_NAMESPACE, sdUUID)

        with rm.acquireResource(imageResourcesNamespace, srcImg, rm.EXCLUSIVE):
            vol = sdCache.produce(sdUUID).produceVolume(srcImg, srcVol)
            vol.prepare(rw=True, chainrw=True, setrw=True)

            volumePath = vol.getVolumePath()
            backingVolPath = getBackingVolumePath(srcImg, srcParent)

            try:
                qemuimg.rebase(volumePath, backingVolPath,
                               sc.fmt2str(vol.getFormat()),
                               sc.fmt2str(int(dstFormat)),
                               misc.parseBool(unsafe), vars.task.aborting)
                vol.setParent(srcParent)
                vol.recheckIfLeaf()
            except qemuimg.QImgError:
                cls.log.exception(
                    'cannot rollback rebase for volume %s on '
                    '%s', volumePath, backingVolPath)
                raise se.MergeVolumeRollbackError(srcVol)
            finally:
                vol.teardown(sdUUID, srcVol)
Beispiel #3
0
    def rebaseVolumeRollback(cls, taskObj, sdUUID, srcImg, srcVol, dstFormat, srcParent, unsafe):
        """
        Rebase volume rollback
        """
        cls.log.info("sdUUID=%s srcImg=%s srcVol=%s dstFormat=%s srcParent=%s",
                     sdUUID, srcImg, srcVol, dstFormat, srcParent)

        imageResourcesNamespace = sd.getNamespace(sdUUID, resourceFactories.IMAGE_NAMESPACE)
        with rmanager.acquireResource(imageResourcesNamespace, srcImg, rm.LockType.exclusive):
            try:
                vol = sdCache.produce(sdUUID).produceVolume(imgUUID=srcImg, volUUID=srcVol)
                vol.prepare(rw=True, chainrw=True, setrw=True)
            except Exception:
                cls.log.error("sdUUID=%s srcImg=%s srcVol=%s dstFormat=%s srcParent=%s",
                               sdUUID, srcImg, srcVol, dstFormat, srcParent, exc_info=True)
                raise

            try:
                (rc, out, err) = qemuRebase(vol.getVolumePath(), vol.getFormat(),
                                            os.path.join('..', srcImg, srcParent),
                                            int(dstFormat), misc.parseBool(unsafe),
                                            vars.task.aborting, False)
                if rc:
                    raise se.MergeVolumeRollbackError(srcVol)

                vol.setParent(srcParent)
                vol.recheckIfLeaf()
            except Exception:
                cls.log.error("sdUUID=%s srcImg=%s srcVol=%s dstFormat=%s srcParent=%s",
                               sdUUID, srcImg, srcVol, dstFormat, srcParent, exc_info=True)
                raise
            finally:
                vol.teardown(sdUUID, srcVol)
Beispiel #4
0
    def _registerResourceNamespaces(self):
        """
        Register resources namespaces and create
        factories for it.
        """
        sd.StorageDomain._registerResourceNamespaces(self)

        rmanager = rm.ResourceManager.getInstance()
        # Register lvm activation resource namespace for the underlying VG
        lvmActivationFactory = resourceFactories.LvmActivationFactory(self.sdUUID)
        lvmActivationNamespace = sd.getNamespace(self.sdUUID, LVM_ACTIVATION_NAMESPACE)
        try:
            rmanager.registerNamespace(lvmActivationNamespace, lvmActivationFactory)
        except Exception:
            self.log.warn("Resource namespace %s already registered", lvmActivationNamespace)
Beispiel #5
0
    def _registerResourceNamespaces(self):
        """
        Register resources namespaces and create
        factories for it.
        """
        sd.StorageDomain._registerResourceNamespaces(self)

        rmanager = rm.ResourceManager.getInstance()
        # Register lvm activation resource namespace for the underlying VG
        lvmActivationFactory = resourceFactories.LvmActivationFactory(
            self.sdUUID)
        lvmActivationNamespace = sd.getNamespace(self.sdUUID,
                                                 LVM_ACTIVATION_NAMESPACE)
        try:
            rmanager.registerNamespace(lvmActivationNamespace,
                                       lvmActivationFactory)
        except KeyError:
            self.log.info("Resource namespace %s already registered",
                          lvmActivationNamespace)
Beispiel #6
0
    def teardown(cls, sdUUID, volUUID, justme=False):
        """
        Deactivate volume and release resources.
        Volume deactivation occurs as part of resource releasing.
        If justme is false, the entire COW chain should be torn down.
        """
        cls.log.info("Tearing down volume %s/%s justme %s" % (sdUUID, volUUID, justme))
        lvmActivationNamespace = sd.getNamespace(sdUUID, LVM_ACTIVATION_NAMESPACE)
        rmanager.releaseResource(lvmActivationNamespace, volUUID)
        if not justme:
            try:
                pvolUUID = _getVolumeTag(sdUUID, volUUID, TAG_PREFIX_PARENT)
            except Exception, e:
                # If storage not accessible or lvm error occurred
                # we will failure to get the parent volume.
                # We can live with it and still succeed in volume's teardown.
                pvolUUID = volume.BLANK_UUID
                cls.log.warn("Failure to get parent of volume %s/%s (%s)" % (sdUUID, volUUID, e))

            if pvolUUID != volume.BLANK_UUID:
                cls.teardown(sdUUID=sdUUID, volUUID=pvolUUID, justme=False)
Beispiel #7
0
    def teardown(cls, sdUUID, volUUID, justme=False):
        """
        Deactivate volume and release resources.
        Volume deactivation occurs as part of resource releasing.
        If justme is false, the entire COW chain should be torn down.
        """
        cls.log.info("Tearing down volume %s/%s justme %s" %
                     (sdUUID, volUUID, justme))
        lvmActivationNamespace = sd.getNamespace(sdUUID,
                                                 LVM_ACTIVATION_NAMESPACE)
        rmanager.releaseResource(lvmActivationNamespace, volUUID)
        if not justme:
            try:
                pvolUUID = _getVolumeTag(sdUUID, volUUID, TAG_PREFIX_PARENT)
            except Exception as e:
                # If storage not accessible or lvm error occurred
                # we will failure to get the parent volume.
                # We can live with it and still succeed in volume's teardown.
                pvolUUID = volume.BLANK_UUID
                cls.log.warn("Failure to get parent of volume %s/%s (%s)" %
                             (sdUUID, volUUID, e))

            if pvolUUID != volume.BLANK_UUID:
                cls.teardown(sdUUID=sdUUID, volUUID=pvolUUID, justme=False)
Beispiel #8
0
 def __init__(self, repoPath, sdUUID, imgUUID, volUUID):
     manifest = self.manifestClass(repoPath, sdUUID, imgUUID, volUUID)
     volume.Volume.__init__(self, manifest)
     self.lvmActivationNamespace = sd.getNamespace(self.sdUUID,
                                                   LVM_ACTIVATION_NAMESPACE)
Beispiel #9
0
 def ns(self):
     return sd.getNamespace(sc.VOLUME_LEASE_NAMESPACE, self._sd_id)
Beispiel #10
0
 def __init__(self, sdUUID):
     rm.SimpleResourceFactory.__init__(self)
     self.sdUUID = sdUUID
     self.volumeResourcesNamespace = sd.getNamespace(sc.VOLUME_NAMESPACE,
                                                     self.sdUUID)
Beispiel #11
0
 def __init__(self, repoPath, sdUUID, imgUUID, volUUID):
     md = self.metadataClass(repoPath, sdUUID, imgUUID, volUUID)
     volume.Volume.__init__(self, md)
     self.lvmActivationNamespace = sd.getNamespace(
         self.sdUUID, LVM_ACTIVATION_NAMESPACE)
Beispiel #12
0
 def __init__(self, repoPath, sdUUID, imgUUID, volUUID):
     self.metaoff = None
     volume.Volume.__init__(self, repoPath, sdUUID, imgUUID, volUUID)
     self.lvmActivationNamespace = sd.getNamespace(self.sdUUID, LVM_ACTIVATION_NAMESPACE)
Beispiel #13
0
    def _createTargetImage(self, destDom, srcSdUUID, imgUUID):
        # Before actual data copying we need perform several operation
        # such as: create all volumes, create fake template if needed, ...
        try:
            # Find all volumes of source image
            srcChain = self.getChain(srcSdUUID, imgUUID)
        except se.StorageException:
            self.log.error("Unexpected error", exc_info=True)
            raise
        except Exception as e:
            self.log.error("Unexpected error", exc_info=True)
            raise se.SourceImageActionError(imgUUID, srcSdUUID, str(e))

        fakeTemplate = False
        pimg = volume.BLANK_UUID    # standalone chain
        # check if the chain is build above a template, or it is a standalone
        pvol = srcChain[0].getParentVolume()
        if pvol:
            # find out parent volume parameters
            volParams = pvol.getVolumeParams()
            pimg = volParams['imgUUID']      # pimg == template image
            if destDom.isBackup():
                # FIXME: This workaround help as copy VM to the backup domain
                #        without its template. We will create fake template
                #        for future VM creation and mark it as FAKE volume.
                #        This situation is relevant for backup domain only.
                fakeTemplate = True

        @contextmanager
        def justLogIt(img):
            self.log.debug("You don't really need lock parent of image %s",
                           img)
            yield

        dstImageResourcesNamespace = sd.getNamespace(
            destDom.sdUUID, resourceFactories.IMAGE_NAMESPACE)
        # In destination domain we need to lock image's template if exists
        with rmanager.acquireResource(dstImageResourcesNamespace, pimg,
                                      rm.LockType.shared) \
                if pimg != volume.BLANK_UUID else justLogIt(imgUUID):
            if fakeTemplate:
                self.createFakeTemplate(destDom.sdUUID, volParams)

            dstChain = []
            for srcVol in srcChain:
                # Create the dst volume
                try:
                    # find out src volume parameters
                    volParams = srcVol.getVolumeParams(bs=1)

                    # To avoid prezeroing preallocated volumes on NFS domains
                    # we create the target as a sparse volume (since it will be
                    # soon filled with the data coming from the copy) and then
                    # we change its metadata back to the original value.
                    if (volParams['prealloc'] == volume.PREALLOCATED_VOL
                            and destDom.supportsSparseness):
                        tmpVolPreallocation = volume.SPARSE_VOL
                    else:
                        tmpVolPreallocation = volParams['prealloc']

                    destDom.createVolume(imgUUID=imgUUID,
                                         size=volParams['size'],
                                         volFormat=volParams['volFormat'],
                                         preallocate=tmpVolPreallocation,
                                         diskType=volParams['disktype'],
                                         volUUID=srcVol.volUUID,
                                         desc=volParams['descr'],
                                         srcImgUUID=pimg,
                                         srcVolUUID=volParams['parent'])

                    dstVol = destDom.produceVolume(imgUUID=imgUUID,
                                                   volUUID=srcVol.volUUID)

                    # Extend volume (for LV only) size to the actual size
                    dstVol.extend((volParams['apparentsize'] + 511) / 512)

                    # Change destination volume metadata back to the original
                    # type.
                    if tmpVolPreallocation != volParams['prealloc']:
                        dstVol.setType(volParams['prealloc'])

                    dstChain.append(dstVol)
                except se.StorageException:
                    self.log.error("Unexpected error", exc_info=True)
                    raise
                except Exception as e:
                    self.log.error("Unexpected error", exc_info=True)
                    raise se.DestImageActionError(imgUUID, destDom.sdUUID,
                                                  str(e))

                # only base may have a different parent image
                pimg = imgUUID

        return {'srcChain': srcChain, 'dstChain': dstChain}
Beispiel #14
0
 def __init__(self, repoPath, sdUUID, imgUUID, volUUID):
     volume.VolumeManifest.__init__(self, repoPath, sdUUID, imgUUID,
                                    volUUID)
     self.metaoff = None
     self.lvmActivationNamespace = sd.getNamespace(
         self.sdUUID, LVM_ACTIVATION_NAMESPACE)
Beispiel #15
0
 def __init__(self, sdUUID):
     rm.SimpleResourceFactory.__init__(self)
     self.sdUUID = sdUUID
     self.volumeResourcesNamespace = sd.getNamespace(
         self.sdUUID, VOLUME_NAMESPACE)
Beispiel #16
0
 def __init__(self, repoPath, sdUUID, imgUUID, volUUID):
     volume.VolumeManifest.__init__(self, repoPath, sdUUID, imgUUID,
                                    volUUID)
     self.lvmActivationNamespace = sd.getNamespace(
         sc.LVM_ACTIVATION_NAMESPACE, self.sdUUID)
Beispiel #17
0
 def ns(self):
     return sd.getNamespace(sc.VOLUME_LEASE_NAMESPACE, self._sd_id)