Esempio n. 1
0
    def _cascade_volume_delete(self, o_vname, o_snaps):
        """Delete or hides volume(if it is busy)

        Go over snapshots and deletes them if possible
        Calls for recursive volume deletion if volume do not have children
        """
        vsnaps = []
        deletable = True

        for snap in o_snaps:
            if jcom.is_snapshot(snap['name']):
                vsnaps += [(snap['name'],
                            jcom.full_name_volume(snap['clones']))]

        active_vsnaps = [vs for vs in vsnaps if jcom.is_hidden(vs[1]) is False]

        # If volume have clones or hidden snapshots it should be hidden
        if len(active_vsnaps) < len(o_snaps):
            deletable = False

        for vsnap in active_vsnaps:
            psnap = []
            try:
                psnap = self.ra.get_snapshots(vsnap[1])
            except jexc.JDSSException as jerr:
                msg = (_('Failure in acquiring snapshot for %s.') % vsnap[1])
                raise exception.VolumeBackendAPIException(msg) from jerr

            try:
                psnap = self._clean_garbage_snapshots(vsnap[1], psnap)
            except exception.VolumeBackendAPIException as err:
                msg = (_('Failure in cleaning garbage snapshots %s'
                         ' for volume %s, %s') % psnap, vsnap[1], err)
                raise exception.VolumeBackendAPIException(msg) from err
            if len(psnap) > 0:
                deletable = False
                self._hide_object(vsnap[1])
            else:
                try:
                    self.ra.delete_snapshot(o_vname,
                                            vsnap[0],
                                            recursively_children=True,
                                            recursively_dependents=True,
                                            force_umount=True)
                except jexc.JDSSException as jerr:
                    LOG.warning(
                        'Failure during deletion of physical '
                        'snapshot %s, err: %s', vsnap[0], jerr)
                    msg = (_('Failure during deletion of virtual snapshot '
                             '%s') % vsnap[1])
                    raise exception.VolumeBackendAPIException(msg)

        if deletable:
            self._gc_delete(o_vname)
        else:
            self._hide_object(o_vname)
Esempio n. 2
0
    def _delete_back_recursively(self, opvname, opsname):
        """Deletes snapshot by removing its oldest removable parent

        Checks if source volume for this snapshot is hidden:
        If it is hidden and have no other descenents, it calls itself on its
            source snapshot if such exists, or deletes it
        If it is not hidden, trigers delete for snapshot

        :param opvname: origin physical volume name
        :param opsname: origin physical snapshot name
        """

        if jcom.is_hidden(opvname):
            # Resource is hidden
            snaps = []
            try:
                snaps = self.ra.get_snapshots(opvname)
            except jexc.JDSSResourceNotFoundException:
                LOG.debug(
                    'Unable to get physical snapshots related to'
                    ' physical volume %s, volume do not exist', opvname)
                return
            except jexc.JDSSException as jerr:
                raise exception.VolumeBackendAPIException(jerr)

            snaps = self._clean_garbage_snapshots(opvname, snaps)

            if len(snaps) > 1:
                # opvname has active snapshots and cant be deleted
                # that is why we delete branch related to opsname
                try:
                    self.ra.delete_snapshot(opvname,
                                            opsname,
                                            recursively_children=True,
                                            recursively_dependents=True,
                                            force_umount=True)
                except jexc.JDSSException as jerr:
                    raise exception.VolumeBackendAPIException(jerr)
            else:
                vol = None
                try:
                    vol = self.ra.get_lun(opvname)

                except jexc.JDSSResourceNotFoundException:
                    LOG.debug(
                        'volume %s does not exist, it was already '
                        'deleted.', opvname)
                    return
                except jexc.JDSSException as jerr:
                    raise exception.VolumeBackendAPIException(jerr)

                if vol['is_clone']:
                    self._delete_back_recursively(
                        jcom.origin_volume(vol['origin']),
                        jcom.origin_snapshot(vol['origin']))
                else:
                    try:
                        self.ra.delete_lun(opvname,
                                           recursively_children=True,
                                           recursively_dependents=True,
                                           force_umount=True)
                    except jexc.JDSSResourceNotFoundException:
                        LOG.debug(
                            'volume %s does not exist, it was already '
                            'deleted.', opvname)
                        return
                    except jexc.JDSSException as jerr:
                        raise exception.VolumeBackendAPIException(jerr)
        else:
            # Resource is active
            try:
                self.ra.delete_snapshot(opvname,
                                        opsname,
                                        recursively_children=True,
                                        recursively_dependents=True,
                                        force_umount=True)
            except jexc.JDSSException as jerr:
                raise exception.VolumeBackendAPIException(jerr) from jerr