Beispiel #1
0
 def revert_to_snapshot(self, volume, snapshot):
     """Rollback the specified snapshot."""
     pvol = utils.get_ldev(volume)
     svol = utils.get_ldev(snapshot)
     if (pvol is not None and svol is not None
             and self.has_snap_pair(pvol, svol)):
         self.restore_ldev(pvol, svol)
     else:
         raise NotImplementedError()
Beispiel #2
0
    def terminate_connection(self, volume, connector):
        """Terminate connection between the server and the volume."""
        ldev = utils.get_ldev(volume)
        if ldev is None:
            utils.output_log(MSG.INVALID_LDEV_FOR_UNMAPPING,
                             volume_id=volume['id'])
            return
        # If a fake connector is generated by nova when the host
        # is down, then the connector will not have a host property,
        # In this case construct the lock without the host property
        # so that all the fake connectors to an SVC are serialized
        if 'host' not in connector:
            port_hostgroup_map = self.get_port_hostgroup_map(ldev)
            if not port_hostgroup_map:
                utils.output_log(MSG.NO_LUN, ldev=ldev)
                return
            self.set_terminate_target(connector, port_hostgroup_map)

        # A synchronization to prevent conflicts between host group creation
        # and deletion.
        @coordination.synchronized(
            'hbsd-host-%(storage_id)s-%(host)s' % {
                'storage_id': self.conf.hitachi_storage_id,
                'host': connector.get('host'),
            }
        )
        def inner(self, volume, connector):
            deleted_targets = self.detach_ldev(volume, ldev, connector)
            if self.storage_info['protocol'] == 'FC':
                target_wwn = [
                    self.storage_info['wwns'][target]
                    for target in deleted_targets]
                return {'driver_volume_type': self.driver_info['volume_type'],
                        'data': {'target_wwn': target_wwn}}
        return inner(self, volume, connector)
Beispiel #3
0
 def discard_zero_page(self, volume):
     """Return the volume's no-data pages to the storage pool."""
     if self.conf.hitachi_discard_zero_page:
         ldev = utils.get_ldev(volume)
         try:
             self.client.discard_zero_page(ldev)
         except utils.HBSDError:
             utils.output_log(MSG.DISCARD_ZERO_PAGE_FAILED, ldev=ldev)
Beispiel #4
0
    def create_group_from_src(self,
                              context,
                              group,
                              volumes,
                              snapshots=None,
                              source_vols=None):
        volumes_model_update = []
        new_ldevs = []
        events = []

        def _create_group_volume_from_src(context, volume, src, from_snapshot):
            volume_model_update = {'id': volume.id}
            try:
                ldev = utils.get_ldev(src)
                if ldev is None:
                    msg = utils.output_log(
                        MSG.INVALID_LDEV_FOR_VOLUME_COPY,
                        type='snapshot' if from_snapshot else 'volume',
                        id=src.id)
                    self.raise_error(msg)
                volume_model_update.update(
                    self.create_volume_from_snapshot(volume, src) if
                    from_snapshot else self.create_cloned_volume(volume, src))
            except Exception as exc:
                volume_model_update['msg'] = utils.get_exception_msg(exc)
            raise loopingcall.LoopingCallDone(volume_model_update)

        try:
            from_snapshot = True if snapshots else False
            for volume, src in zip(volumes,
                                   snapshots if snapshots else source_vols):
                loop = loopingcall.FixedIntervalLoopingCall(
                    _create_group_volume_from_src, context, volume, src,
                    from_snapshot)
                event = loop.start(interval=0)
                events.append(event)
            is_success = True
            for e in events:
                volume_model_update = e.wait()
                if 'msg' in volume_model_update:
                    is_success = False
                    msg = volume_model_update['msg']
                else:
                    volumes_model_update.append(volume_model_update)
                ldev = utils.get_ldev(volume_model_update)
                if ldev is not None:
                    new_ldevs.append(ldev)
            if not is_success:
                self.raise_error(msg)
        except Exception:
            with excutils.save_and_reraise_exception():
                for new_ldev in new_ldevs:
                    try:
                        self.delete_ldev(new_ldev)
                    except exception.VolumeDriverException:
                        utils.output_log(MSG.DELETE_LDEV_FAILED, ldev=new_ldev)
        return None, volumes_model_update
Beispiel #5
0
 def update_group(self, group, add_volumes=None):
     if add_volumes and volume_utils.is_group_a_cg_snapshot_type(group):
         for volume in add_volumes:
             ldev = utils.get_ldev(volume)
             if ldev is None:
                 msg = utils.output_log(MSG.LDEV_NOT_EXIST_FOR_ADD_GROUP,
                                        volume_id=volume.id,
                                        group='consistency group',
                                        group_id=group.id)
                 self.raise_error(msg)
     return None, None, None
Beispiel #6
0
 def delete_snapshot(self, snapshot):
     """Delete the specified snapshot."""
     ldev = utils.get_ldev(snapshot)
     if ldev is None:
         utils.output_log(MSG.INVALID_LDEV_FOR_DELETION,
                          method='delete_snapshot',
                          id=snapshot['id'])
         return
     try:
         self.delete_ldev(ldev)
     except utils.HBSDBusy:
         raise exception.SnapshotIsBusy(snapshot_name=snapshot['name'])
Beispiel #7
0
 def delete_volume(self, volume):
     """Delete the specified volume."""
     ldev = utils.get_ldev(volume)
     if ldev is None:
         utils.output_log(MSG.INVALID_LDEV_FOR_DELETION,
                          method='delete_volume',
                          id=volume['id'])
         return
     try:
         self.delete_ldev(ldev)
     except utils.HBSDBusy:
         raise exception.VolumeIsBusy(volume_name=volume['name'])
Beispiel #8
0
 def extend_volume(self, volume, new_size):
     """Extend the specified volume to the specified size."""
     ldev = utils.get_ldev(volume)
     if ldev is None:
         msg = utils.output_log(MSG.INVALID_LDEV_FOR_EXTENSION,
                                volume_id=volume['id'])
         raise utils.HBSDError(msg)
     if self.check_pair_svol(ldev):
         msg = utils.output_log(MSG.INVALID_VOLUME_TYPE_FOR_EXTEND,
                                volume_id=volume['id'])
         raise utils.HBSDError(msg)
     self.delete_pair(ldev)
     self.extend_ldev(ldev, volume['size'], new_size)
Beispiel #9
0
 def create_snapshot(self, snapshot):
     """Create a snapshot from a volume and return its properties."""
     src_vref = snapshot.volume
     ldev = utils.get_ldev(src_vref)
     if ldev is None:
         msg = utils.output_log(MSG.INVALID_LDEV_FOR_VOLUME_COPY,
                                type='volume',
                                id=src_vref['id'])
         raise utils.HBSDError(msg)
     size = snapshot['volume_size']
     new_ldev = self._copy_on_storage(ldev, size, True)
     return {
         'provider_location': str(new_ldev),
     }
Beispiel #10
0
 def _create_cgsnapshot_volume(snapshot):
     pair = {'snapshot': snapshot}
     try:
         pair['pvol'] = utils.get_ldev(snapshot.volume)
         if pair['pvol'] is None:
             msg = utils.output_log(MSG.INVALID_LDEV_FOR_VOLUME_COPY,
                                    type='volume',
                                    id=snapshot.volume_id)
             self.raise_error(msg)
         size = snapshot.volume_size
         pair['svol'] = self.create_ldev(size)
     except Exception as exc:
         pair['msg'] = utils.get_exception_msg(exc)
     raise loopingcall.LoopingCallDone(pair)
Beispiel #11
0
 def delete_snapshot(self, snapshot):
     """Delete the specified snapshot."""
     ldev = utils.get_ldev(snapshot)
     if ldev is None:
         utils.output_log(MSG.INVALID_LDEV_FOR_DELETION,
                          method='delete_snapshot',
                          id=snapshot['id'])
         return
     try:
         self.delete_ldev(ldev)
     except exception.VolumeDriverException as ex:
         if ex.msg == utils.BUSY_MESSAGE:
             raise exception.SnapshotIsBusy(snapshot_name=snapshot['name'])
         else:
             raise ex
Beispiel #12
0
 def delete_volume(self, volume):
     """Delete the specified volume."""
     ldev = utils.get_ldev(volume)
     if ldev is None:
         utils.output_log(MSG.INVALID_LDEV_FOR_DELETION,
                          method='delete_volume',
                          id=volume['id'])
         return
     try:
         self.delete_ldev(ldev)
     except exception.VolumeDriverException as ex:
         if ex.msg == utils.BUSY_MESSAGE:
             raise exception.VolumeIsBusy(volume_name=volume['name'])
         else:
             raise ex
Beispiel #13
0
 def _create_group_volume_from_src(context, volume, src, from_snapshot):
     volume_model_update = {'id': volume.id}
     try:
         ldev = utils.get_ldev(src)
         if ldev is None:
             msg = utils.output_log(
                 MSG.INVALID_LDEV_FOR_VOLUME_COPY,
                 type='snapshot' if from_snapshot else 'volume',
                 id=src.id)
             self.raise_error(msg)
         volume_model_update.update(
             self.create_volume_from_snapshot(volume, src) if
             from_snapshot else self.create_cloned_volume(volume, src))
     except Exception as exc:
         volume_model_update['msg'] = utils.get_exception_msg(exc)
     raise loopingcall.LoopingCallDone(volume_model_update)
Beispiel #14
0
 def unmanage(self, volume):
     """Prepare the volume for removing it from Cinder management."""
     ldev = utils.get_ldev(volume)
     if ldev is None:
         utils.output_log(MSG.INVALID_LDEV_FOR_DELETION, method='unmanage',
                          id=volume['id'])
         return
     if self.check_pair_svol(ldev):
         utils.output_log(
             MSG.INVALID_LDEV_TYPE_FOR_UNMANAGE, volume_id=volume['id'],
             volume_type=utils.NORMAL_LDEV_TYPE)
         raise exception.VolumeIsBusy(volume_name=volume['name'])
     try:
         self.delete_pair(ldev)
     except utils.HBSDBusy:
         raise exception.VolumeIsBusy(volume_name=volume['name'])
Beispiel #15
0
    def create_volume_from_src(self, volume, src, src_type):
        """Create a volume from a volume or snapshot and return its properties.

        """
        ldev = utils.get_ldev(src)
        if ldev is None:
            msg = utils.output_log(
                MSG.INVALID_LDEV_FOR_VOLUME_COPY, type=src_type, id=src['id'])
            raise utils.HBSDError(msg)

        size = volume['size']
        new_ldev = self._copy_on_storage(ldev, size)
        self.modify_ldev_name(new_ldev, volume['id'].replace("-", ""))

        return {
            'provider_location': str(new_ldev),
        }
Beispiel #16
0
 def _delete_group_obj(group, obj, is_snapshot):
     obj_update = {'id': obj.id}
     try:
         if is_snapshot:
             self.delete_snapshot(obj)
         else:
             self.delete_volume(obj)
         obj_update['status'] = 'deleted'
     except (utils.HBSDError, exception.VolumeIsBusy,
             exception.SnapshotIsBusy) as exc:
         obj_update['status'] = 'available' if isinstance(
             exc, (exception.VolumeIsBusy,
                   exception.SnapshotIsBusy)) else 'error'
         utils.output_log(
             MSG.GROUP_OBJECT_DELETE_FAILED,
             obj='snapshot' if is_snapshot else 'volume',
             group='group snapshot' if is_snapshot else 'group',
             group_id=group.id, obj_id=obj.id, ldev=utils.get_ldev(obj),
             reason=exc.msg)
     raise loopingcall.LoopingCallDone(obj_update)
Beispiel #17
0
    def initialize_connection(self, volume, connector):
        """Initialize connection between the server and the volume."""
        targets = {
            'info': {},
            'list': [],
            'lun': {},
            'iqns': {},
            'target_map': {},
        }
        ldev = utils.get_ldev(volume)
        if ldev is None:
            msg = utils.output_log(MSG.INVALID_LDEV_FOR_CONNECTION,
                                   volume_id=volume['id'])
            raise utils.HBSDError(msg)

        target_lun = self.attach_ldev(volume, ldev, connector, targets)

        return {
            'driver_volume_type': self.driver_info['volume_type'],
            'data': self.get_properties(targets, target_lun, connector),
        }
Beispiel #18
0
    def _create_cgsnapshot(self, context, cgsnapshot, snapshots):
        pairs = []
        events = []
        snapshots_model_update = []

        def _create_cgsnapshot_volume(snapshot):
            pair = {'snapshot': snapshot}
            try:
                pair['pvol'] = utils.get_ldev(snapshot.volume)
                if pair['pvol'] is None:
                    msg = utils.output_log(MSG.INVALID_LDEV_FOR_VOLUME_COPY,
                                           type='volume',
                                           id=snapshot.volume_id)
                    self.raise_error(msg)
                size = snapshot.volume_size
                pair['svol'] = self.create_ldev(size)
            except Exception as exc:
                pair['msg'] = utils.get_exception_msg(exc)
            raise loopingcall.LoopingCallDone(pair)

        try:
            for snapshot in snapshots:
                ldev = utils.get_ldev(snapshot.volume)
                if ldev is None:
                    msg = utils.output_log(MSG.INVALID_LDEV_FOR_VOLUME_COPY,
                                           type='volume',
                                           id=snapshot.volume_id)
                    self.raise_error(msg)
            for snapshot in snapshots:
                loop = loopingcall.FixedIntervalLoopingCall(
                    _create_cgsnapshot_volume, snapshot)
                event = loop.start(interval=0)
                events.append(event)
            is_success = True
            for e in events:
                pair = e.wait()
                if 'msg' in pair:
                    is_success = False
                    msg = pair['msg']
                pairs.append(pair)
            if not is_success:
                self.raise_error(msg)
            self._create_ctg_snap_pair(pairs)
        except Exception:
            for pair in pairs:
                if 'svol' in pair and pair['svol'] is not None:
                    try:
                        self.delete_ldev(pair['svol'])
                    except exception.VolumeDriverException:
                        utils.output_log(MSG.DELETE_LDEV_FAILED,
                                         ldev=pair['svol'])
            model_update = {'status': fields.GroupSnapshotStatus.ERROR}
            for snapshot in snapshots:
                snapshot_model_update = {
                    'id': snapshot.id,
                    'status': fields.SnapshotStatus.ERROR
                }
                snapshots_model_update.append(snapshot_model_update)
            return model_update, snapshots_model_update
        for pair in pairs:
            snapshot_model_update = {
                'id': pair['snapshot'].id,
                'status': fields.SnapshotStatus.AVAILABLE,
                'provider_location': str(pair['svol'])
            }
            snapshots_model_update.append(snapshot_model_update)
        return None, snapshots_model_update