Пример #1
0
    def delete_snapshot(self, snapshot):
        snapshotname = huawei_utils.encode_name(snapshot['id'])
        volume_name = huawei_utils.encode_name(snapshot['volume_id'])

        LOG.info(_LI(
            'stop_snapshot: snapshot name: %(snapshot)s, '
            'volume name: %(volume)s.'),
            {'snapshot': snapshotname,
             'volume': volume_name},)

        snapshot_id = snapshot.get('provider_location', None)
        if snapshot_id is None:
            snapshot_id = self.restclient.get_snapshotid_by_name(snapshotname)

        if snapshot_id is not None:
            if self.restclient.check_snapshot_exist(snapshot_id):
                self.restclient.stop_snapshot(snapshot_id)
                self.restclient.delete_snapshot(snapshot_id)
            else:
                LOG.warning(_LW("Can't find snapshot on the array."))
        else:
            LOG.warning(_LW("Can't find snapshot on the array."))
            return False

        return True
Пример #2
0
    def update_migrated_volume(self,
                               ctxt,
                               volume,
                               new_volume,
                               original_volume_status=None):
        original_name = huawei_utils.encode_name(volume['id'])
        current_name = huawei_utils.encode_name(new_volume['id'])

        lun_id = self.restclient.get_volume_by_name(current_name)
        try:
            self.restclient.rename_lun(lun_id, original_name)
        except exception.VolumeBackendAPIException:
            LOG.error(_LE('Unable to rename lun %s on array.'), current_name)
            return {'_name_id': new_volume['_name_id'] or new_volume['id']}

        LOG.debug(
            "Rename lun from %(current_name)s to %(original_name)s "
            "successfully.", {
                'current_name': current_name,
                'original_name': original_name
            })

        model_update = {'_name_id': None}

        return model_update
Пример #3
0
    def delete_snapshot(self, snapshot):
        snapshotname = huawei_utils.encode_name(snapshot['id'])
        volume_name = huawei_utils.encode_name(snapshot['volume_id'])

        LOG.info(
            _LI('stop_snapshot: snapshot name: %(snapshot)s, '
                'volume name: %(volume)s.'),
            {
                'snapshot': snapshotname,
                'volume': volume_name
            },
        )

        snapshot_id = snapshot.get('provider_location')
        if snapshot_id is None:
            snapshot_id = self.restclient.get_snapshotid_by_name(snapshotname)

        if snapshot_id is not None:
            if self.restclient.check_snapshot_exist(snapshot_id):
                self.restclient.stop_snapshot(snapshot_id)
                self.restclient.delete_snapshot(snapshot_id)
            else:
                LOG.warning(_LW("Can't find snapshot on the array."))
        else:
            LOG.warning(_LW("Can't find snapshot on the array."))
            return False

        return True
Пример #4
0
    def create_snapshot(self, snapshot):
        snapshot_name = huawei_utils.encode_name(snapshot['id'])
        snapshot_description = snapshot['id']
        volume_name = huawei_utils.encode_name(snapshot['volume_id'])

        LOG.info(_LI(
            'create_snapshot:snapshot name: %(snapshot)s, '
            'volume name: %(volume)s.'),
            {'snapshot': snapshot_name,
             'volume': volume_name})

        lun_id = self.get_volume_by_name(volume_name)
        if lun_id is None:
            msg = (_("Can't find lun info on the array, "
                     "lun name is: %(name)s.") % {'name': volume_name})
            LOG.error(msg)
            raise exception.VolumeBackendAPIException(data=msg)

        url = self.url + "/snapshot"
        data = json.dumps({"TYPE": "27",
                           "NAME": snapshot_name,
                           "PARENTTYPE": "11",
                           "DESCRIPTION": snapshot_description,
                           "PARENTID": lun_id})
        result = self.call(url, data)

        msg = 'Create snapshot error.'
        self._assert_rest_result(result, msg)
        self._assert_data_in_result(result, msg)

        return result['data']
Пример #5
0
    def update_consistencygroup(self, context, group,
                                add_volumes, remove_volumes):
        LOG.info(_LI("Update Consistency Group: %(group)s. "
                     "This adds or removes volumes from a CG."),
                 {'group': group['id']})

        metrogroup_id = self.check_consistencygroup_need_to_stop(group)
        if not metrogroup_id:
            msg = _("The CG does not exist on array.")
            LOG.error(msg)
            raise exception.VolumeBackendAPIException(data=msg)

        # Deal with add volumes to CG
        for volume in add_volumes:
            metadata = huawei_utils.get_lun_metadata(volume)
            if not metadata.get('hypermetro'):
                err_msg = _("Volume %s is not in hypermetro pair.") % volume.id
                LOG.error(err_msg)
                raise exception.VolumeBackendAPIException(data=err_msg)

            lun_name = huawei_utils.encode_name(volume.id)
            hypermetro = self.client.get_hypermetro_by_lun_name(lun_name)
            if not hypermetro:
                err_msg = _("Volume %s is not in hypermetro pair.") % volume.id
                LOG.error(err_msg)
                raise exception.VolumeBackendAPIException(data=err_msg)

            metro_id = hypermetro['ID']
            if not self._check_metro_in_cg(metro_id, metrogroup_id):
                self.check_metro_need_to_stop(metro_id)
                self.client.add_metro_to_metrogroup(metrogroup_id,
                                                    metro_id)
                self._ensure_hypermetro_added_to_cg(
                    metro_id, metrogroup_id)

        # Deal with remove volumes from CG
        for volume in remove_volumes:
            metadata = huawei_utils.get_lun_metadata(volume)
            if not metadata.get('hypermetro'):
                continue

            lun_name = huawei_utils.encode_name(volume.id)
            hypermetro = self.client.get_hypermetro_by_lun_name(lun_name)
            if not hypermetro:
                continue

            metro_id = hypermetro['ID']
            if self._check_metro_in_cg(metro_id, metrogroup_id):
                self.check_metro_need_to_stop(metro_id)
                self.client.remove_metro_from_metrogroup(metrogroup_id,
                                                         metro_id)
                self._ensure_hypermetro_removed_from_cg(
                    metro_id, metrogroup_id)
                self.client.sync_hypermetro(metro_id)

        new_group_info = self.client.get_metrogroup_by_id(metrogroup_id)
        is_empty = new_group_info["ISEMPTY"]
        if is_empty == 'false':
            self.client.sync_metrogroup(metrogroup_id)
Пример #6
0
    def create_volume_from_snapshot(self, volume, snapshot):
        """Create a volume from a snapshot.

        We use LUNcopy to copy a new volume from snapshot.
        The time needed increases as volume size does.
        """
        snapshotname = huawei_utils.encode_name(snapshot['id'])

        snapshot_id = snapshot.get('provider_location', None)
        if snapshot_id is None:
            snapshot_id = self.restclient.get_snapshotid_by_name(snapshotname)
            if snapshot_id is None:
                err_msg = (_(
                    'create_volume_from_snapshot: Snapshot %(name)s '
                    'does not exist.')
                    % {'name': snapshotname})
                LOG.error(err_msg)
                raise exception.VolumeBackendAPIException(data=err_msg)

        lun_info = self.create_volume(volume)

        tgt_lun_id = lun_info['ID']
        luncopy_name = huawei_utils.encode_name(volume['id'])

        LOG.info(_LI(
            'create_volume_from_snapshot: src_lun_id: %(src_lun_id)s, '
            'tgt_lun_id: %(tgt_lun_id)s, copy_name: %(copy_name)s.'),
            {'src_lun_id': snapshot_id,
             'tgt_lun_id': tgt_lun_id,
             'copy_name': luncopy_name})

        event_type = 'LUNReadyWaitInterval'

        wait_interval = huawei_utils.get_wait_interval(self.xml_file_path,
                                                       event_type)

        def _volume_ready():
            result = self.restclient.get_lun_info(tgt_lun_id)

            if (result['HEALTHSTATUS'] == constants.STATUS_HEALTH
               and result['RUNNINGSTATUS'] == constants.STATUS_VOLUME_READY):
                return True
            return False

        huawei_utils.wait_for_condition(self.xml_file_path,
                                        _volume_ready,
                                        wait_interval,
                                        wait_interval * 10)

        self._copy_volume(volume, luncopy_name,
                          snapshot_id, tgt_lun_id)

        return {'ID': lun_info['ID'],
                'lun_info': lun_info}
Пример #7
0
    def create_volume_from_snapshot(self, volume, snapshot):
        """Create a volume from a snapshot.

        We use LUNcopy to copy a new volume from snapshot.
        The time needed increases as volume size does.
        """
        snapshotname = huawei_utils.encode_name(snapshot["id"])

        snapshot_id = snapshot.get("provider_location", None)
        if snapshot_id is None:
            snapshot_id = self.restclient.get_snapshotid_by_name(snapshotname)
            if snapshot_id is None:
                err_msg = _("create_volume_from_snapshot: Snapshot %(name)s " "does not exist.") % {
                    "name": snapshotname
                }
                LOG.error(err_msg)
                raise exception.VolumeBackendAPIException(data=err_msg)

        lun_info = self.create_volume(volume)

        tgt_lun_id = lun_info["ID"]
        luncopy_name = huawei_utils.encode_name(volume["id"])

        LOG.info(
            _LI(
                "create_volume_from_snapshot: src_lun_id: %(src_lun_id)s, "
                "tgt_lun_id: %(tgt_lun_id)s, copy_name: %(copy_name)s."
            ),
            {"src_lun_id": snapshot_id, "tgt_lun_id": tgt_lun_id, "copy_name": luncopy_name},
        )

        event_type = "LUNReadyWaitInterval"

        wait_interval = huawei_utils.get_wait_interval(self.xml_file_path, event_type)

        def _volume_ready():
            result = self.restclient.get_lun_info(tgt_lun_id)

            if (
                result["HEALTHSTATUS"] == constants.STATUS_HEALTH
                and result["RUNNINGSTATUS"] == constants.STATUS_VOLUME_READY
            ):
                return True
            return False

        huawei_utils.wait_for_condition(self.xml_file_path, _volume_ready, wait_interval, wait_interval * 10)

        self._copy_volume(volume, luncopy_name, snapshot_id, tgt_lun_id)

        return {"ID": lun_info["ID"], "lun_info": lun_info}
Пример #8
0
    def delete_volume(self, volume):
        """Delete a volume.

        Three steps:
        Firstly, remove associate from lungroup.
        Secondly, remove associate from QoS policy.
        Thirdly, remove the lun.
        """
        name = huawei_utils.encode_name(volume['id'])
        lun_id = volume.get('provider_location')
        LOG.info(
            _LI('Delete volume: %(name)s, array lun id: %(lun_id)s.'),
            {
                'name': name,
                'lun_id': lun_id
            },
        )
        if lun_id:
            if self.restclient.check_lun_exist(lun_id):
                qos_id = self.restclient.get_qosid_by_lunid(lun_id)
                if qos_id:
                    self.remove_qos_lun(lun_id, qos_id)

                self.restclient.delete_lun(lun_id)
        else:
            LOG.warning(_LW("Can't find lun %s on the array."), lun_id)
            return False

        return True
Пример #9
0
    def delete_consistencygroup(self, context, group, volumes):
        LOG.info(_LI("Delete Consistency Group: %(group)s."),
                 {'group': group['id']})
        metrogroup_id = self.check_consistencygroup_need_to_stop(group)
        if not metrogroup_id:
            return

        # Remove pair from metrogroup.
        for volume in volumes:
            metadata = huawei_utils.get_lun_metadata(volume)
            if not metadata.get('hypermetro'):
                continue

            lun_name = huawei_utils.encode_name(volume.id)
            hypermetro = self.client.get_hypermetro_by_lun_name(lun_name)
            if not hypermetro:
                continue

            metro_id = hypermetro['ID']
            if self._check_metro_in_cg(metro_id, metrogroup_id):
                self.client.remove_metro_from_metrogroup(
                    metrogroup_id, metro_id)

        # Delete metrogroup.
        self.client.delete_metrogroup(metrogroup_id)
Пример #10
0
    def update_migrated_volume(self, ctxt, volume, new_volume,
                               original_volume_status):
        new_name = huawei_utils.encode_name(volume.id)
        org_metadata = huawei_utils.get_volume_private_data(volume)
        new_metadata = huawei_utils.get_volume_private_data(new_volume)

        try:
            if org_metadata.get('huawei_sn') == new_metadata.get('huawei_sn'):
                self.local_cli.rename_lun(org_metadata['huawei_lun_id'],
                                          new_name[:-4] + '-org')
            self.local_cli.rename_lun(new_metadata['huawei_lun_id'],
                                      new_name,
                                      description=volume.name)
        except Exception:
            LOG.exception('Unable to rename lun %(id)s to %(name)s.', {
                'id': new_metadata['huawei_lun_id'],
                'name': new_name
            })
            name_id = new_volume.name_id
        else:
            LOG.info("Successfully rename lun %(id)s to %(name)s.", {
                'id': new_metadata['huawei_lun_id'],
                'name': new_name
            })
            name_id = None

        return {
            '_name_id': name_id,
            'provider_location': huawei_utils.to_string(**new_metadata),
        }
Пример #11
0
    def extend_volume(self, volume, new_size):
        """Extend a volume."""
        volume_size = huawei_utils.get_volume_size(volume)
        new_volume_size = int(new_size) * units.Gi / 512
        volume_name = huawei_utils.encode_name(volume['id'])

        LOG.info(
            _LI('Extend volume: %(volumename)s, oldsize:'
                ' %(oldsize)s  newsize: %(newsize)s.'),
            {
                'volumename': volume_name,
                'oldsize': volume_size,
                'newsize': new_volume_size
            },
        )

        lun_id = self.restclient.get_volume_by_name(volume_name)

        if lun_id is None:
            msg = (
                _("Can't find lun info on the array, lun name is: %(name)s.") %
                {
                    'name': volume_name
                })
            LOG.error(msg)
            raise exception.VolumeBackendAPIException(data=msg)

        luninfo = self.restclient.extend_volume(lun_id, new_volume_size)

        return {'provider_location': luninfo['ID'], 'lun_info': luninfo}
Пример #12
0
    def create_volume(self, volume):
        """Create a volume."""
        pool_info = self.restclient.find_pool_info()
        volume_name = huawei_utils.encode_name(volume['id'])
        volume_description = volume['name']
        volume_size = huawei_utils.get_volume_size(volume)

        LOG.info(_LI(
            'Create volume: %(volume)s, size: %(size)s.'),
            {'volume': volume_name,
             'size': volume_size})

        params = huawei_utils.get_lun_conf_params(self.xml_file_path)
        params['pool_id'] = pool_info['ID']
        params['volume_size'] = volume_size
        params['volume_description'] = volume_description

        # Prepare LUN parameters.
        lun_param = huawei_utils.init_lun_parameters(volume_name, params)

        # Create LUN on the array.
        lun_info = self.restclient.create_volume(lun_param)
        lun_id = lun_info['ID']

        return {'provider_location': lun_info['ID'],
                'ID': lun_id,
                'lun_info': lun_info}
Пример #13
0
 def _get_group_info_by_name(self, group_id):
     group_name = huawei_utils.encode_name(group_id)
     group_info = self.local_cgop.get_replicg_by_name(group_name)
     if not group_info:
         group_name = huawei_utils.old_encode_name(group_id)
         group_info = self.local_cgop.get_replicg_by_name(group_name)
     return group_info
Пример #14
0
 def create(self, group, replica_model):
     group_id = group.get('id')
     LOG.info("Create Consistency Group: %(group)s.",
              {'group': group_id})
     group_name = huawei_utils.encode_name(group_id)
     self.local_cgop.create(group_name, group_id, replica_model,
                            self.conf.replica_sync_speed)
Пример #15
0
    def extend_volume(self, volume, new_size):
        """Extend a volume."""
        volume_size = huawei_utils.get_volume_size(volume)
        new_volume_size = int(new_size) * units.Gi / 512
        volume_name = huawei_utils.encode_name(volume['id'])

        LOG.info(_LI(
            'Extend volume: %(volumename)s, oldsize:'
            ' %(oldsize)s  newsize: %(newsize)s.'),
            {'volumename': volume_name,
             'oldsize': volume_size,
             'newsize': new_volume_size},)

        lun_id = self.restclient.get_volume_by_name(volume_name)

        if lun_id is None:
            msg = (_(
                "Can't find lun info on the array, lun name is: %(name)s.")
                % {'name': volume_name})
            LOG.error(msg)
            raise exception.VolumeBackendAPIException(data=msg)

        luninfo = self.restclient.extend_volume(lun_id, new_volume_size)

        return {'provider_location': luninfo['ID'],
                'lun_info': luninfo}
Пример #16
0
    def create_volume(self, volume):
        """Create a volume."""
        pool_name = volume_utils.extract_host(volume['host'],
                                              level='pool')
        pools = self.restclient.find_all_pools()
        pool_info = self.restclient.find_pool_info(pool_name, pools)
        if not pool_info:
            msg = (_('Error in getting pool information for the pool: %s.')
                   % pool_name)
            LOG.error(msg)
            raise exception.VolumeBackendAPIException(data=msg)
        volume_name = huawei_utils.encode_name(volume['id'])
        volume_description = volume['name']
        volume_size = huawei_utils.get_volume_size(volume)

        LOG.info(_LI(
            'Create volume: %(volume)s, size: %(size)s.'),
            {'volume': volume_name,
             'size': volume_size})

        params = huawei_utils.get_lun_conf_params(self.xml_file_path)
        params['pool_id'] = pool_info['ID']
        params['volume_size'] = volume_size
        params['volume_description'] = volume_description

        # Prepare LUN parameters.
        lun_param = huawei_utils.init_lun_parameters(volume_name, params)

        # Create LUN on the array.
        lun_info = self.restclient.create_volume(lun_param)
        lun_id = lun_info['ID']

        return {'provider_location': lun_info['ID'],
                'ID': lun_id,
                'lun_info': lun_info}
Пример #17
0
    def _migrate_volume(self, volume, host, new_type=None):
        if not self._check_migration_valid(host, volume):
            return (False, None)

        type_id = volume['volume_type_id']

        volume_type = None
        if type_id:
            volume_type = volume_types.get_volume_type(None, type_id)

        pool_name = host['capabilities']['pool_name']
        pools = self.restclient.find_all_pools()
        pool_info = self.restclient.find_pool_info(pool_name, pools)
        src_volume_name = huawei_utils.encode_name(volume['id'])
        dst_volume_name = six.text_type(hash(src_volume_name))
        src_id = volume.get('provider_location', None)

        src_lun_params = self.restclient.get_lun_info(src_id)

        opts = None
        qos = None
        if new_type:
            # If new type exists, use new type.
            opts = huawei_utils._get_extra_spec_value(
                new_type['extra_specs'])
            opts = smartx.SmartX().get_smartx_specs_opts(opts)
            if 'LUNType' not in opts:
                opts['LUNType'] = huawei_utils.find_luntype_in_xml(
                    self.xml_file_path)

            qos = huawei_utils.get_qos_by_volume_type(new_type)
        elif volume_type:
            qos = huawei_utils.get_qos_by_volume_type(volume_type)

        if not opts:
            opts = huawei_utils.get_volume_params(volume)
            opts = smartx.SmartX().get_smartx_specs_opts(opts)

        lun_info = self._create_lun_with_extra_feature(pool_info,
                                                       dst_volume_name,
                                                       src_lun_params,
                                                       opts)
        lun_id = lun_info['ID']

        if qos:
            LOG.info(_LI('QoS: %s.'), qos)
            SmartQos = smartx.SmartQos(self.restclient)
            SmartQos.create_qos(qos, lun_id)
        if opts:
            smartpartition = smartx.SmartPartition(self.restclient)
            smartpartition.add(opts, lun_id)
            smartcache = smartx.SmartCache(self.restclient)
            smartcache.add(opts, lun_id)

        dst_id = lun_info['ID']
        self._wait_volume_ready(dst_id)
        moved = self._migrate_lun(src_id, dst_id)

        return moved, {}
Пример #18
0
    def initialize_connection_iscsi(self, volume, connector):
        """Map a volume to a host and return target iSCSI information."""
        LOG.info(_LI('Enter initialize_connection_iscsi.'))
        initiator_name = connector['initiator']
        volume_name = huawei_utils.encode_name(volume['id'])

        LOG.info(_LI(
            'initiator name: %(initiator_name)s, '
            'volume name: %(volume)s.'),
            {'initiator_name': initiator_name,
             'volume': volume_name})

        (iscsi_iqn,
         target_ip,
         portgroup_id) = self.restclient.get_iscsi_params(self.xml_file_path,
                                                          connector)
        LOG.info(_LI('initialize_connection_iscsi, iscsi_iqn: %(iscsi_iqn)s, '
                     'target_ip: %(target_ip)s, '
                     'TargetPortGroup: %(portgroup_id)s.'),
                 {'iscsi_iqn': iscsi_iqn,
                  'target_ip': target_ip,
                  'portgroup_id': portgroup_id},)

        # Create hostgroup if not exist.
        host_name = connector['host']
        host_name_before_hash = None
        if host_name and (len(host_name) > constants.MAX_HOSTNAME_LENTH):
            host_name_before_hash = host_name
            host_name = str(hash(host_name))
        host_id = self.restclient.add_host_with_check(host_name,
                                                      host_name_before_hash)

        # Add initiator to the host.
        self.restclient.ensure_initiator_added(initiator_name, host_id)
        hostgroup_id = self.restclient.add_host_into_hostgroup(host_id)

        # Mapping lungroup and hostgroup to view.
        lun_id = self.restclient.mapping_hostgroup_and_lungroup(volume_name,
                                                                hostgroup_id,
                                                                host_id,
                                                                portgroup_id)

        hostlun_id = self.restclient.find_host_lun_id(host_id, lun_id)

        LOG.info(_LI("initialize_connection_iscsi, host lun id is: %s."),
                 hostlun_id)

        # Return iSCSI properties.
        properties = {}
        properties['target_discovered'] = False
        properties['target_portal'] = ('%s:%s' % (target_ip, '3260'))
        properties['target_iqn'] = iscsi_iqn
        properties['target_lun'] = int(hostlun_id)
        properties['volume_id'] = volume['id']

        LOG.info(_LI("initialize_connection_iscsi success. Return data: %s."),
                 properties)
        return {'driver_volume_type': 'iscsi', 'data': properties}
Пример #19
0
    def terminate_connection_fc(self, volume, connector):
        """Delete map between a volume and a host."""
        wwns = connector['wwpns']
        volume_name = huawei_utils.encode_name(volume['id'])
        lun_id = volume.get('provider_location', None)
        host_name = connector['host']
        left_lunnum = -1

        LOG.info(
            _LI('terminate_connection_fc: volume name: %(volume)s, '
                'wwpns: %(wwns)s, '
                'lun_id: %(lunid)s.'),
            {
                'volume': volume_name,
                'wwns': wwns,
                'lunid': lun_id
            },
        )
        if lun_id:
            if self.restclient.check_lun_exist(lun_id):
                # Get lungroup id by lun id.
                lungroup_id = self.restclient.get_lungroupid_by_lunid(lun_id)
                if not lungroup_id:
                    LOG.info(_LI("Can't find lun in lungroup."))
                else:
                    self.restclient.remove_lun_from_lungroup(
                        lungroup_id, lun_id)
            else:
                LOG.warning(_LW("Can't find lun on the array."))
        tgt_port_wwns = []
        for wwn in wwns:
            tgtwwpns = self.restclient.get_fc_target_wwpns(wwn)
            if tgtwwpns:
                tgt_port_wwns.append(tgtwwpns)

        init_targ_map = {}
        for initiator in wwns:
            init_targ_map[initiator] = tgt_port_wwns
        host_id = self.restclient.find_host(host_name)
        if host_id:
            mapping_view_name = constants.MAPPING_VIEW_PREFIX + host_id
            view_id = self.restclient.find_mapping_view(mapping_view_name)
            if view_id:
                lungroup_id = self.restclient.find_lungroup_from_map(view_id)
        if lungroup_id:
            left_lunnum = self.restclient.get_lunnum_from_lungroup(lungroup_id)
        if int(left_lunnum) > 0:
            info = {'driver_volume_type': 'fibre_channel', 'data': {}}
        else:
            info = {
                'driver_volume_type': 'fibre_channel',
                'data': {
                    'target_wwn': tgt_port_wwns,
                    'initiator_target_map': init_targ_map
                },
            }

        return info
Пример #20
0
    def create_volume(self, volume):
        """Create a volume."""
        opts = huawei_utils.get_volume_params(volume)
        smartx_opts = smartx.SmartX().get_smartx_specs_opts(opts)
        params = huawei_utils.get_lun_params(self.xml_file_path,
                                             smartx_opts)
        pool_name = volume_utils.extract_host(volume['host'],
                                              level='pool')
        pools = self.restclient.find_all_pools()
        pool_info = self.restclient.find_pool_info(pool_name, pools)
        if not pool_info:
            # The following code is to keep compatibility with old version of
            # Huawei driver.
            pool_names = huawei_utils.get_pools(self.xml_file_path)
            for pool_name in pool_names.split(";"):
                pool_info = self.restclient.find_pool_info(pool_name,
                                                           pools)
                if pool_info:
                    break

        volume_name = huawei_utils.encode_name(volume['id'])
        volume_description = volume['name']
        volume_size = huawei_utils.get_volume_size(volume)

        LOG.info(_LI(
            'Create volume: %(volume)s, size: %(size)s.'),
            {'volume': volume_name,
             'size': volume_size})

        params['pool_id'] = pool_info['ID']
        params['volume_size'] = volume_size
        params['volume_description'] = volume_description

        # Prepare LUN parameters.
        lun_param = huawei_utils.init_lun_parameters(volume_name, params)

        # Create LUN on the array.
        lun_info = self.restclient.create_volume(lun_param)
        lun_id = lun_info['ID']

        try:
            qos = huawei_utils.get_volume_qos(volume)
            if qos:
                smart_qos = smartx.SmartQos(self.restclient)
                smart_qos.create_qos(qos, lun_id)
            smartpartition = smartx.SmartPartition(self.restclient)
            smartpartition.add(opts, lun_id)

            smartcache = smartx.SmartCache(self.restclient)
            smartcache.add(opts, lun_id)
        except Exception as err:
            self._delete_lun_with_check(lun_id)
            raise exception.InvalidInput(
                reason=_('Create volume error. Because %s.') % err)

        return {'provider_location': lun_info['ID'],
                'ID': lun_id,
                'lun_info': lun_info}
Пример #21
0
    def _get_metro_group_id(self, id):
        group_name = huawei_utils.encode_name(id)
        metrogroup_id = self.client.get_metrogroup_by_name(group_name)

        if not metrogroup_id:
            group_name = huawei_utils.old_encode_name(id)
            metrogroup_id = self.client.get_metrogroup_by_name(group_name)

        return metrogroup_id
Пример #22
0
    def _get_metro_group_id(self, id):
        group_name = huawei_utils.encode_name(id)
        metrogroup_id = self.client.get_metrogroup_by_name(group_name)

        if not metrogroup_id:
            group_name = huawei_utils.old_encode_name(id)
            metrogroup_id = self.client.get_metrogroup_by_name(group_name)

        return metrogroup_id
Пример #23
0
    def initialize_connection_fc(self, volume, connector):
        wwns = connector['wwpns']
        volume_name = huawei_utils.encode_name(volume['id'])

        LOG.info(_LI(
            'initialize_connection_fc, initiator: %(wwpns)s,'
            ' volume name: %(volume)s.'),
            {'wwpns': wwns,
             'volume': volume_name},)

        host_name_before_hash = None
        host_name = connector['host']
        if host_name and (len(host_name) > constants.MAX_HOSTNAME_LENGTH):
            host_name_before_hash = host_name
            host_name = six.text_type(hash(host_name))

        # Create hostgroup if not exist.
        host_id = self.restclient.add_host_with_check(host_name,
                                                      host_name_before_hash)

        # Add host into hostgroup.
        hostgroup_id = self.restclient.add_host_into_hostgroup(host_id)

        free_wwns = self.restclient.get_connected_free_wwns()
        LOG.info(_LI("initialize_connection_fc, the array has free wwns: %s."),
                 free_wwns)
        for wwn in wwns:
            if wwn in free_wwns:
                self.restclient.add_fc_port_to_host(host_id, wwn)

        lun_id = self.restclient.mapping_hostgroup_and_lungroup(volume_name,
                                                                hostgroup_id,
                                                                host_id)
        host_lun_id = self.restclient.find_host_lun_id(host_id, lun_id)

        tgt_port_wwns = []
        for wwn in wwns:
            tgtwwpns = self.restclient.get_fc_target_wwpns(wwn)
            if tgtwwpns:
                tgt_port_wwns.append(tgtwwpns)

        init_targ_map = {}
        for initiator in wwns:
            init_targ_map[initiator] = tgt_port_wwns

        # Return FC properties.
        info = {'driver_volume_type': 'fibre_channel',
                'data': {'target_lun': int(host_lun_id),
                         'target_discovered': True,
                         'target_wwn': tgt_port_wwns,
                         'volume_id': volume['id'],
                         'initiator_target_map': init_targ_map}, }

        LOG.info(_LI("initialize_connection_fc, return data is: %s."),
                 info)

        return info
Пример #24
0
    def create_volume(self, volume):
        """Create a volume."""
        opts = huawei_utils.get_volume_params(volume)
        smartx_opts = smartx.SmartX().get_smartx_specs_opts(opts)
        params = huawei_utils.get_lun_params(self.xml_file_path, smartx_opts)
        pool_name = volume_utils.extract_host(volume['host'], level='pool')
        pools = self.restclient.find_all_pools()
        pool_info = self.restclient.find_pool_info(pool_name, pools)
        if not pool_info:
            # The following code is to keep compatibility with old version of
            # Huawei driver.
            pool_names = huawei_utils.get_pools(self.xml_file_path)
            for pool_name in pool_names.split(";"):
                pool_info = self.restclient.find_pool_info(pool_name, pools)
                if pool_info:
                    break

        volume_name = huawei_utils.encode_name(volume['id'])
        volume_description = volume['name']
        volume_size = huawei_utils.get_volume_size(volume)

        LOG.info(_LI('Create volume: %(volume)s, size: %(size)s.'), {
            'volume': volume_name,
            'size': volume_size
        })

        params['pool_id'] = pool_info['ID']
        params['volume_size'] = volume_size
        params['volume_description'] = volume_description

        # Prepare LUN parameters.
        lun_param = huawei_utils.init_lun_parameters(volume_name, params)

        # Create LUN on the array.
        lun_info = self.restclient.create_volume(lun_param)
        lun_id = lun_info['ID']

        try:
            qos = huawei_utils.get_volume_qos(volume)
            if qos:
                smart_qos = smartx.SmartQos(self.restclient)
                smart_qos.create_qos(qos, lun_id)
            smartpartition = smartx.SmartPartition(self.restclient)
            smartpartition.add(opts, lun_id)

            smartcache = smartx.SmartCache(self.restclient)
            smartcache.add(opts, lun_id)
        except Exception as err:
            self._delete_lun_with_check(lun_id)
            raise exception.InvalidInput(
                reason=_('Create volume error. Because %s.') % err)

        return {
            'provider_location': lun_info['ID'],
            'ID': lun_id,
            'lun_info': lun_info
        }
Пример #25
0
    def update_migrated_volume(self, ctxt, volume, new_volume, original_volume_status=None):
        original_name = huawei_utils.encode_name(volume["id"])
        current_name = huawei_utils.encode_name(new_volume["id"])

        lun_id = self.restclient.get_volume_by_name(current_name)
        try:
            self.restclient.rename_lun(lun_id, original_name)
        except exception.VolumeBackendAPIException:
            LOG.error(_LE("Unable to rename lun %s on array."), current_name)
            return {"_name_id": new_volume["_name_id"] or new_volume["id"]}

        LOG.debug(
            "Rename lun from %(current_name)s to %(original_name)s " "successfully.",
            {"current_name": current_name, "original_name": original_name},
        )

        model_update = {"_name_id": None}

        return model_update
Пример #26
0
    def create_volume(self, volume):
        """Create a volume."""
        opts = huawei_utils.get_volume_params(volume)
        smartx_opts = smartx.SmartX().get_smartx_specs_opts(opts)
        params = huawei_utils.get_lun_params(self.xml_file_path,
                                             smartx_opts)
        pool_name = volume_utils.extract_host(volume['host'],
                                              level='pool')
        pools = self.restclient.find_all_pools()
        pool_info = self.restclient.find_pool_info(pool_name, pools)
        if not pool_info:
            msg = (_('Error in getting pool information for the pool: %s.')
                   % pool_name)
            LOG.error(msg)
            raise exception.VolumeBackendAPIException(data=msg)
        volume_name = huawei_utils.encode_name(volume['id'])
        volume_description = volume['name']
        volume_size = huawei_utils.get_volume_size(volume)

        LOG.info(_LI(
            'Create volume: %(volume)s, size: %(size)s.'),
            {'volume': volume_name,
             'size': volume_size})

        params['pool_id'] = pool_info['ID']
        params['volume_size'] = volume_size
        params['volume_description'] = volume_description

        # Prepare LUN parameters.
        lun_param = huawei_utils.init_lun_parameters(volume_name, params)

        # Create LUN on the array.
        lun_info = self.restclient.create_volume(lun_param)
        lun_id = lun_info['ID']

        try:
            qos = huawei_utils.get_volume_qos(volume)
            if qos:
                smart_qos = smartx.SmartQos(self.restclient)
                smart_qos.create_qos(qos, lun_id)
            smartpartition = smartx.SmartPartition(self.restclient)
            smartpartition.add(opts, lun_id)

            smartcache = smartx.SmartCache(self.restclient)
            smartcache.add(opts, lun_id)
        except Exception as err:
            if lun_id:
                self._delete_lun_with_check(lun_id)
            raise exception.InvalidInput(
                reason=_('Create volume error. Because %s.') % err)

        return {'provider_location': lun_info['ID'],
                'ID': lun_id,
                'lun_info': lun_info}
Пример #27
0
    def update_migrated_volume(self, ctxt, volume, new_volume,
                               original_volume_status):
        original_name = huawei_utils.encode_name(volume['id'])
        current_name = huawei_utils.encode_name(new_volume['id'])

        lun_id = self.restclient.get_volume_by_name(current_name)
        try:
            self.restclient.rename_lun(lun_id, original_name)
        except exception.VolumeBackendAPIException:
            LOG.error(_LE('Unable to rename lun %s on array.'), current_name)
            return {'_name_id': new_volume['_name_id'] or new_volume['id']}

        LOG.debug("Rename lun from %(current_name)s to %(original_name)s "
                  "successfully.",
                  {'current_name': current_name,
                   'original_name': original_name})

        model_update = {'_name_id': None}

        return model_update
Пример #28
0
    def create_consistencygroup(self, group):
        LOG.info("Create Consistency Group: %(group)s.", {'group': group.id})
        group_name = huawei_utils.encode_name(group.id)
        domain_name = self.configuration.metro_domain_name
        domain_id = self.client.get_hyper_domain_id(domain_name)
        if not domain_name or not domain_id:
            msg = _("The domain_name config in cinder.conf is wrong.")
            LOG.error(msg)
            raise exception.VolumeBackendAPIException(data=msg)

        self.client.create_metrogroup(group_name, group.id, domain_id)
Пример #29
0
    def create_consistencygroup(self, group):
        LOG.info(_LI("Create Consistency Group: %(group)s."),
                 {'group': group.id})
        group_name = huawei_utils.encode_name(group.id)
        domain_name = self.configuration.metro_domain_name
        domain_id = self.client.get_hyper_domain_id(domain_name)
        if not domain_name or not domain_id:
            msg = _("The domain_name config in cinder.conf is wrong.")
            LOG.error(msg)
            raise exception.VolumeBackendAPIException(data=msg)

        self.client.create_metrogroup(group_name, group.id, domain_id)
Пример #30
0
    def terminate_connection_fc(self, volume, connector):
        """Delete map between a volume and a host."""
        wwns = connector['wwpns']
        volume_name = huawei_utils.encode_name(volume['id'])
        lun_id = volume.get('provider_location', None)
        host_name = connector['host']
        left_lunnum = -1

        LOG.info(_LI('terminate_connection_fc: volume name: %(volume)s, '
                     'wwpns: %(wwns)s, '
                     'lun_id: %(lunid)s.'),
                 {'volume': volume_name,
                  'wwns': wwns,
                  'lunid': lun_id},)
        if lun_id:
            if self.restclient.check_lun_exist(lun_id):
                # Get lungroup id by lun id.
                lungroup_id = self.restclient.get_lungroupid_by_lunid(lun_id)
                if not lungroup_id:
                    LOG.info(_LI("Can't find lun in lungroup."))
                else:
                    self.restclient.remove_lun_from_lungroup(lungroup_id,
                                                             lun_id)
            else:
                LOG.warning(_LW("Can't find lun on the array."))
        tgt_port_wwns = []
        for wwn in wwns:
            tgtwwpns = self.restclient.get_fc_target_wwpns(wwn)
            if tgtwwpns:
                tgt_port_wwns.append(tgtwwpns)

        init_targ_map = {}
        for initiator in wwns:
            init_targ_map[initiator] = tgt_port_wwns
        host_id = self.restclient.find_host(host_name)
        if host_id:
            mapping_view_name = constants.MAPPING_VIEW_PREFIX + host_id
            view_id = self.restclient.find_mapping_view(mapping_view_name)
            if view_id:
                lungroup_id = self.restclient.find_lungroup_from_map(view_id)
        if lungroup_id:
            left_lunnum = self.restclient.get_lunnum_from_lungroup(lungroup_id)
        if int(left_lunnum) > 0:
            info = {'driver_volume_type': 'fibre_channel',
                    'data': {}}
        else:
            info = {'driver_volume_type': 'fibre_channel',
                    'data': {'target_wwn': tgt_port_wwns,
                             'initiator_target_map': init_targ_map}, }

        return info
Пример #31
0
    def delete_hypermetro(self, hypermetro_id, volume):
        hypermetro = self.local_cli.get_hypermetro_by_id(hypermetro_id)
        if hypermetro:
            if (hypermetro['RUNNINGSTATUS'] in (constants.METRO_RUNNING_NORMAL,
                                                constants.METRO_RUNNING_SYNC)):
                self.local_cli.stop_hypermetro(hypermetro_id)

            self.local_cli.delete_hypermetro(hypermetro_id)
            self.remote_cli.delete_lun(hypermetro['REMOTEOBJID'])
        else:
            name = huawei_utils.encode_name(volume.id)
            remote_lun_info = self.remote_cli.get_lun_info_by_name(name)
            if remote_lun_info:
                self.remote_cli.delete_lun(remote_lun_info['ID'])
Пример #32
0
    def delete_hypermetro(self, volume):
        """Delete hypermetro."""
        lun_name = huawei_utils.encode_name(volume.id)
        hypermetro = self.client.get_hypermetro_by_lun_name(lun_name)
        if not hypermetro:
            return

        metro_id = hypermetro['ID']
        remote_lun_id = hypermetro['REMOTEOBJID']

        # Delete hypermetro and remote lun.
        self.check_metro_need_to_stop(metro_id, hypermetro)
        self.client.delete_hypermetro(metro_id)
        self.rmt_client.delete_lun(remote_lun_id)
Пример #33
0
    def check_consistencygroup_need_to_stop(self, group):
        group_name = huawei_utils.encode_name(group.id)
        metrogroup_id = self.client.get_metrogroup_by_name(group_name)

        if metrogroup_id:
            metrogroup_info = self.client.get_metrogroup_by_id(metrogroup_id)
            health_status = metrogroup_info['HEALTHSTATUS']
            running_status = metrogroup_info['RUNNINGSTATUS']

            if (health_status == constants.HEALTH_NORMAL
                and (running_status == constants.RUNNING_NORMAL
                     or running_status == constants.RUNNING_SYNC)):
                self.client.stop_metrogroup(metrogroup_id)

        return metrogroup_id
Пример #34
0
    def delete_snapshot(self, snapshot):
        snapshotname = huawei_utils.encode_name(snapshot["id"])
        volume_name = huawei_utils.encode_name(snapshot["volume_id"])

        LOG.info(
            _LI("stop_snapshot: snapshot name: %(snapshot)s, " "volume name: %(volume)s."),
            {"snapshot": snapshotname, "volume": volume_name},
        )

        snapshot_id = snapshot.get("provider_location", None)
        if snapshot_id is None:
            snapshot_id = self.restclient.get_snapshotid_by_name(snapshotname)

        if snapshot_id is not None:
            if self.restclient.check_snapshot_exist(snapshot_id):
                self.restclient.stop_snapshot(snapshot_id)
                self.restclient.delete_snapshot(snapshot_id)
            else:
                LOG.warning(_LW("Can't find snapshot on the array."))
        else:
            LOG.warning(_LW("Can't find snapshot on the array."))
            return False

        return True
Пример #35
0
    def create_group(self, group_id, replica_model):
        LOG.info("Create replication group %s.", group_id)
        group_name = huawei_utils.encode_name(group_id)
        params = {'NAME': group_name,
                  'DESCRIPTION': group_id,
                  'RECOVERYPOLICY': '1',
                  'REPLICATIONMODEL': replica_model,
                  'SPEED': constants.REPLICA_SPEED}

        if replica_model == constants.REPLICA_ASYNC_MODEL:
            params['SYNCHRONIZETYPE'] = '2'
            params['TIMINGVAL'] = constants.REPLICA_CG_PERIOD

        group = self.group_op.create(params)
        return group['ID']
Пример #36
0
    def check_consistencygroup_need_to_stop(self, group):
        group_name = huawei_utils.encode_name(group.id)
        metrogroup_id = self.client.get_metrogroup_by_name(group_name)

        if metrogroup_id:
            metrogroup_info = self.client.get_metrogroup_by_id(metrogroup_id)
            health_status = metrogroup_info['HEALTHSTATUS']
            running_status = metrogroup_info['RUNNINGSTATUS']

            if (health_status == constants.HEALTH_NORMAL
                and (running_status == constants.RUNNING_NORMAL
                     or running_status == constants.RUNNING_SYNC)):
                self.client.stop_metrogroup(metrogroup_id)

        return metrogroup_id
Пример #37
0
    def create_consistencygroup(self, group_id):
        LOG.info("Create hypermetro consistency group %s.", group_id)

        domain_name = self.configs['metro_domain']
        domain_id = self.local_cli.get_hypermetro_domain_id(domain_name)
        if not domain_id:
            msg = _("Hypermetro domain %s doesn't exist.") % domain_name
            LOG.error(msg)
            raise exception.VolumeBackendAPIException(data=msg)

        params = {"NAME": huawei_utils.encode_name(group_id),
                  "DESCRIPTION": group_id,
                  "RECOVERYPOLICY": "1",
                  "SPEED": self.configs['sync_speed'],
                  "DOMAINID": domain_id}
        self.local_cli.create_metrogroup(params)
Пример #38
0
    def delete_hypermetro(self, volume):
        lun_name = huawei_utils.encode_name(volume.id)
        hypermetro = self.local_cli.get_hypermetro_by_lun_name(lun_name)

        if hypermetro:
            huawei_utils.remove_lun_from_lungroup(self.remote_cli,
                                                  hypermetro['REMOTEOBJID'])
            if (hypermetro['RUNNINGSTATUS'] in (constants.METRO_RUNNING_NORMAL,
                                                constants.METRO_RUNNING_SYNC)):
                self.local_cli.stop_hypermetro(hypermetro['ID'])

            self.local_cli.delete_hypermetro(hypermetro['ID'])
            self.remote_cli.delete_lun(hypermetro['REMOTEOBJID'])
        else:
            remote_lun_info = self.remote_cli.get_lun_info_by_name(lun_name)
            if remote_lun_info:
                self.remote_cli.delete_lun(remote_lun_info['ID'])
Пример #39
0
    def extend_volume(self, volume, new_size):
        """Extend a volume."""
        volume_size = huawei_utils.get_volume_size(volume)
        new_volume_size = int(new_size) * units.Gi / 512
        volume_name = huawei_utils.encode_name(volume['id'])

        LOG.info(_LI(
            'Extend volume: %(volumename)s, oldsize:'
            ' %(oldsize)s  newsize: %(newsize)s.'),
            {'volumename': volume_name,
             'oldsize': volume_size,
             'newsize': new_volume_size},)

        lun_id = self.restclient.get_lunid(volume, volume_name)
        luninfo = self.restclient.extend_volume(lun_id, new_volume_size)

        return {'provider_location': luninfo['ID'],
                'lun_info': luninfo}
Пример #40
0
    def create_volume(self, volume):
        """Create a volume."""
        opts = huawei_utils.get_volume_params(volume)
        smartx_opts = smartx.SmartX().get_smartx_specs_opts(opts)
        params = huawei_utils.get_lun_params(self.xml_file_path, smartx_opts)
        pool_name = volume_utils.extract_host(volume["host"], level="pool")
        pools = self.restclient.find_all_pools()
        pool_info = self.restclient.find_pool_info(pool_name, pools)
        if not pool_info:
            msg = _("Error in getting pool information for the pool: %s.") % pool_name
            LOG.error(msg)
            raise exception.VolumeBackendAPIException(data=msg)
        volume_name = huawei_utils.encode_name(volume["id"])
        volume_description = volume["name"]
        volume_size = huawei_utils.get_volume_size(volume)

        LOG.info(_LI("Create volume: %(volume)s, size: %(size)s."), {"volume": volume_name, "size": volume_size})

        params["pool_id"] = pool_info["ID"]
        params["volume_size"] = volume_size
        params["volume_description"] = volume_description

        # Prepare LUN parameters.
        lun_param = huawei_utils.init_lun_parameters(volume_name, params)

        # Create LUN on the array.
        lun_info = self.restclient.create_volume(lun_param)
        lun_id = lun_info["ID"]

        try:
            qos = huawei_utils.get_volume_qos(volume)
            if qos:
                smart_qos = smartx.SmartQos(self.restclient)
                smart_qos.create_qos(qos, lun_id)
            smartpartition = smartx.SmartPartition(self.restclient)
            smartpartition.add(opts, lun_id)

            smartcache = smartx.SmartCache(self.restclient)
            smartcache.add(opts, lun_id)
        except Exception as err:
            self._delete_lun_with_check(lun_id)
            raise exception.InvalidInput(reason=_("Create volume error. Because %s.") % err)

        return {"provider_location": lun_info["ID"], "ID": lun_id, "lun_info": lun_info}
Пример #41
0
    def delete_volume(self, volume):
        """Delete a volume.

        Three steps:
        Firstly, remove associate from lungroup.
        Secondly, remove associate from QoS policy.
        Thirdly, remove the lun.
        """
        name = huawei_utils.encode_name(volume['id'])
        lun_id = volume.get('provider_location', None)
        LOG.info(_LI('Delete volume: %(name)s, array lun id: %(lun_id)s.'),
                 {'name': name, 'lun_id': lun_id},)
        if lun_id:
            if self.restclient.check_lun_exist(lun_id):
                self.restclient.delete_lun(lun_id)
        else:
            LOG.warning(_LW("Can't find %s on the array."), lun_id)
            return False

        return True
Пример #42
0
    def extend_volume(self, volume, new_size):
        """Extend a volume."""
        volume_size = huawei_utils.get_volume_size(volume)
        new_volume_size = int(new_size) * units.Gi / 512
        volume_name = huawei_utils.encode_name(volume['id'])

        LOG.info(
            _LI('Extend volume: %(volumename)s, oldsize:'
                ' %(oldsize)s  newsize: %(newsize)s.'),
            {
                'volumename': volume_name,
                'oldsize': volume_size,
                'newsize': new_volume_size
            },
        )

        lun_id = self.restclient.get_lunid(volume, volume_name)
        luninfo = self.restclient.extend_volume(lun_id, new_volume_size)

        return {'provider_location': luninfo['ID'], 'lun_info': luninfo}
Пример #43
0
    def _pre_fail_check(self, vol, running_status_set, data_status_set=None):
        # check the replica_pair status
        vol_name = huawei_utils.encode_name(vol.id)
        vol_id = self.local_client.get_lun_id_by_name(vol_name)
        pair_info = self.local_client.get_pair_info_by_lun_id(vol_id)
        if pair_info:
            running_status = self.local_op.is_running_status(
                running_status_set, pair_info)
            data_status = self.local_op.is_data_status(
                data_status_set, pair_info) if data_status_set else True

            if not (running_status and data_status):
                msg = _('Replication pair %(id)s is not at the status '
                        'failover/failback available, RUNNINGSTATUS: '
                        '%(run)s, SECRESDATASTATUS: %(sec)s.') % {
                            'id': pair_info['ID'],
                            'run': pair_info['RUNNINGSTATUS'],
                            'sec': pair_info['SECRESDATASTATUS']
                        }
                LOG.error(msg)
                raise exception.InvalidReplicationTarget(reason=msg)
Пример #44
0
    def extend_volume(self, volume, new_size):
        """Extend a volume."""
        volume_size = huawei_utils.get_volume_size(volume)
        new_volume_size = int(new_size) * units.Gi / 512
        volume_name = huawei_utils.encode_name(volume["id"])

        LOG.info(
            _LI("Extend volume: %(volumename)s, oldsize:" " %(oldsize)s  newsize: %(newsize)s."),
            {"volumename": volume_name, "oldsize": volume_size, "newsize": new_volume_size},
        )

        lun_id = self.restclient.get_volume_by_name(volume_name)

        if lun_id is None:
            msg = _("Can't find lun info on the array, lun name is: %(name)s.") % {"name": volume_name}
            LOG.error(msg)
            raise exception.VolumeBackendAPIException(data=msg)

        luninfo = self.restclient.extend_volume(lun_id, new_volume_size)

        return {"provider_location": luninfo["ID"], "lun_info": luninfo}
Пример #45
0
    def delete_volume(self, volume):
        """Delete a volume.

        Three steps:
        Firstly, remove associate from lungroup.
        Secondly, remove associate from QoS policy.
        Thirdly, remove the lun.
        """
        name = huawei_utils.encode_name(volume["id"])
        lun_id = volume.get("provider_location", None)
        LOG.info(_LI("Delete volume: %(name)s, array lun id: %(lun_id)s."), {"name": name, "lun_id": lun_id})
        if lun_id:
            if self.restclient.check_lun_exist(lun_id):
                qos_id = self.restclient.get_qosid_by_lunid(lun_id)
                if qos_id:
                    self.remove_qos_lun(lun_id, qos_id)

                self.restclient.delete_lun(lun_id)
        else:
            LOG.warning(_LW("Can't find lun %s on the array."), lun_id)
            return False

        return True
Пример #46
0
    def create_volume(self, volume):
        """Create a volume."""
        pool_name = volume_utils.extract_host(volume['host'], level='pool')
        pools = self.restclient.find_all_pools()
        pool_info = self.restclient.find_pool_info(pool_name, pools)
        if not pool_info:
            msg = (_('Error in getting pool information for the pool: %s.') %
                   pool_name)
            LOG.error(msg)
            raise exception.VolumeBackendAPIException(data=msg)
        volume_name = huawei_utils.encode_name(volume['id'])
        volume_description = volume['name']
        volume_size = huawei_utils.get_volume_size(volume)

        LOG.info(_LI('Create volume: %(volume)s, size: %(size)s.'), {
            'volume': volume_name,
            'size': volume_size
        })

        params = huawei_utils.get_lun_conf_params(self.xml_file_path)
        params['pool_id'] = pool_info['ID']
        params['volume_size'] = volume_size
        params['volume_description'] = volume_description

        # Prepare LUN parameters.
        lun_param = huawei_utils.init_lun_parameters(volume_name, params)

        # Create LUN on the array.
        lun_info = self.restclient.create_volume(lun_param)
        lun_id = lun_info['ID']

        return {
            'provider_location': lun_info['ID'],
            'ID': lun_id,
            'lun_info': lun_info
        }
Пример #47
0
 def create_consistencygroup(self, group):
     LOG.info(_LI("Create Consistency Group: %(group)s."),
              {'group': group['id']})
     group_name = huawei_utils.encode_name(group['id'])
     domain_id = self._valid_rmt_metro_domain()
     self.client.create_metrogroup(group_name, group['id'], domain_id)
Пример #48
0
    def terminate_connection(self, volume, connector, **kwargs):
        """Delete map between a volume and a host."""
        initiator_name = connector['initiator']
        volume_name = huawei_utils.encode_name(volume['id'])
        lun_id = volume.get('provider_location')
        host_name = connector['host']
        lungroup_id = None

        LOG.info(
            _LI('terminate_connection: volume name: %(volume)s, '
                'initiator name: %(ini)s, '
                'lun_id: %(lunid)s.'),
            {
                'volume': volume_name,
                'ini': initiator_name,
                'lunid': lun_id
            },
        )

        iscsi_conf = huawei_utils.get_iscsi_conf(self.xml_file_path)
        portgroup = None
        portgroup_id = None
        view_id = None
        left_lunnum = -1
        for ini in iscsi_conf['Initiator']:
            if ini['Name'] == initiator_name:
                for key in ini:
                    if key == 'TargetPortGroup':
                        portgroup = ini['TargetPortGroup']
                        break

        if portgroup:
            portgroup_id = self.restclient.find_tgt_port_group(portgroup)
        if host_name and (len(host_name) > constants.MAX_HOSTNAME_LENGTH):
            host_name = six.text_type(hash(host_name))
        host_id = self.restclient.find_host(host_name)
        if host_id:
            mapping_view_name = constants.MAPPING_VIEW_PREFIX + host_id
            view_id = self.restclient.find_mapping_view(mapping_view_name)
            if view_id:
                lungroup_id = self.restclient.find_lungroup_from_map(view_id)

        # Remove lun from lungroup.
        if lun_id and self.restclient.check_lun_exist(lun_id):
            if lungroup_id:
                lungroup_ids = self.restclient.get_lungroupids_by_lunid(lun_id)
                if lungroup_id in lungroup_ids:
                    self.restclient.remove_lun_from_lungroup(
                        lungroup_id, lun_id)
                else:
                    LOG.warning(
                        _LW("Lun is not in lungroup. "
                            "Lun id: %(lun_id)s. "
                            "lungroup id: %(lungroup_id)s."), {
                                "lun_id": lun_id,
                                "lungroup_id": lungroup_id
                            })
        else:
            LOG.warning(_LW("Can't find lun on the array."))

        # Remove portgroup from mapping view if no lun left in lungroup.
        if lungroup_id:
            left_lunnum = self.restclient.get_lunnum_from_lungroup(lungroup_id)

        if portgroup_id and view_id and (int(left_lunnum) <= 0):
            if self.restclient.is_portgroup_associated_to_view(
                    view_id, portgroup_id):
                self.restclient.delete_portgroup_mapping_view(
                    view_id, portgroup_id)
        if view_id and (int(left_lunnum) <= 0):
            self.restclient.remove_chap(initiator_name)

            if self.restclient.lungroup_associated(view_id, lungroup_id):
                self.restclient.delete_lungroup_mapping_view(
                    view_id, lungroup_id)
            self.restclient.delete_lungroup(lungroup_id)
            if self.restclient.is_initiator_associated_to_host(initiator_name):
                self.restclient.remove_iscsi_from_host(initiator_name)
            hostgroup_name = constants.HOSTGROUP_PREFIX + host_id
            hostgroup_id = self.restclient.find_hostgroup(hostgroup_name)
            if hostgroup_id:
                if self.restclient.hostgroup_associated(view_id, hostgroup_id):
                    self.restclient.delete_hostgoup_mapping_view(
                        view_id, hostgroup_id)
                self.restclient.remove_host_from_hostgroup(
                    hostgroup_id, host_id)
                self.restclient.delete_hostgroup(hostgroup_id)
            self.restclient.remove_host(host_id)
            self.restclient.delete_mapping_view(view_id)
Пример #49
0
    def initialize_connection(self, volume, connector):
        """Map a volume to a host and return target iSCSI information."""
        LOG.info(_LI('Enter initialize_connection.'))
        initiator_name = connector['initiator']
        volume_name = huawei_utils.encode_name(volume['id'])

        LOG.info(
            _LI('initiator name: %(initiator_name)s, '
                'volume name: %(volume)s.'), {
                    'initiator_name': initiator_name,
                    'volume': volume_name
                })

        (iscsi_iqns, target_ips,
         portgroup_id) = self.restclient.get_iscsi_params(
             self.xml_file_path, connector)
        LOG.info(
            _LI('initialize_connection, iscsi_iqn: %(iscsi_iqn)s, '
                'target_ip: %(target_ip)s, '
                'portgroup_id: %(portgroup_id)s.'),
            {
                'iscsi_iqn': iscsi_iqns,
                'target_ip': target_ips,
                'portgroup_id': portgroup_id
            },
        )

        # Create hostgroup if not exist.
        host_name = connector['host']
        host_name_before_hash = None
        if host_name and (len(host_name) > constants.MAX_HOSTNAME_LENGTH):
            host_name_before_hash = host_name
            host_name = six.text_type(hash(host_name))
        host_id = self.restclient.add_host_with_check(host_name,
                                                      host_name_before_hash)

        # Add initiator to the host.
        self.restclient.ensure_initiator_added(self.xml_file_path,
                                               initiator_name, host_id)
        hostgroup_id = self.restclient.add_host_into_hostgroup(host_id)

        lun_id = self.restclient.get_lunid(volume, volume_name)

        # Mapping lungroup and hostgroup to view.
        self.restclient.do_mapping(lun_id, hostgroup_id, host_id, portgroup_id)

        hostlun_id = self.restclient.find_host_lun_id(host_id, lun_id)

        LOG.info(_LI("initialize_connection, host lun id is: %s."), hostlun_id)

        iscsi_conf = huawei_utils.get_iscsi_conf(self.xml_file_path)
        chapinfo = self.restclient.find_chap_info(iscsi_conf, initiator_name)
        # Return iSCSI properties.
        properties = {}
        properties['target_discovered'] = False
        properties['volume_id'] = volume['id']
        multipath = connector.get('multipath', False)
        hostlun_id = int(hostlun_id)
        if not multipath:
            properties['target_portal'] = ('%s:3260' % target_ips[0])
            properties['target_iqn'] = iscsi_iqns[0]
            properties['target_lun'] = hostlun_id
        else:
            properties['target_iqns'] = [iqn for iqn in iscsi_iqns]
            properties['target_portals'] = [
                '%s:3260' % ip for ip in target_ips
            ]
            properties['target_luns'] = [hostlun_id] * len(target_ips)

        # If use CHAP, return CHAP info.
        if chapinfo:
            chap_username, chap_password = chapinfo.split(';')
            properties['auth_method'] = 'CHAP'
            properties['auth_username'] = chap_username
            properties['auth_password'] = chap_password

        LOG.info(_LI("initialize_connection success. Return data: %s."),
                 properties)
        return {'driver_volume_type': 'iscsi', 'data': properties}
Пример #50
0
    def connect_volume_fc(self, volume, connector):
        """Create map between a volume and a host for FC."""
        wwns = connector['wwpns']
        volume_name = huawei_utils.encode_name(volume.id)

        LOG.info(_LI(
            'initialize_connection_fc, initiator: %(wwpns)s,'
            ' volume name: %(volume)s.'),
            {'wwpns': wwns,
             'volume': volume_name})

        metadata = huawei_utils.get_volume_metadata(volume)
        lun_id = metadata['remote_lun_id']

        if lun_id is None:
            lun_id = self.rmt_client.get_lun_id_by_name(volume_name)
        if lun_id is None:
            msg = _("Can't get volume id. Volume name: %s.") % volume_name
            LOG.error(msg)
            raise exception.VolumeBackendAPIException(data=msg)

        original_host_name = connector['host']
        host_name = huawei_utils.encode_host_name(original_host_name)
        host_id = self.client.add_host_with_check(host_name,
                                                  original_host_name)

        # Create hostgroup if not exist.
        host_id = self.rmt_client.add_host_with_check(
            host_name, original_host_name)

        online_wwns_in_host = (
            self.rmt_client.get_host_online_fc_initiators(host_id))
        online_free_wwns = self.rmt_client.get_online_free_wwns()
        for wwn in wwns:
            if (wwn not in online_wwns_in_host
                    and wwn not in online_free_wwns):
                wwns_in_host = (
                    self.rmt_client.get_host_fc_initiators(host_id))
                iqns_in_host = (
                    self.rmt_client.get_host_iscsi_initiators(host_id))
                if not (wwns_in_host or iqns_in_host):
                    self.rmt_client.remove_host(host_id)

                msg = _('Can not add FC port to host.')
                LOG.error(msg)
                raise exception.VolumeBackendAPIException(data=msg)

        for wwn in wwns:
            if wwn in online_free_wwns:
                self.rmt_client.add_fc_port_to_host(host_id, wwn)

        (tgt_port_wwns, init_targ_map) = (
            self.rmt_client.get_init_targ_map(wwns))

        # Add host into hostgroup.
        hostgroup_id = self.rmt_client.add_host_to_hostgroup(host_id)
        map_info = self.rmt_client.do_mapping(lun_id,
                                              hostgroup_id,
                                              host_id)
        if not map_info:
            msg = _('Map info is None due to array version '
                    'not supporting hypermetro.')
            LOG.error(msg)
            raise exception.VolumeBackendAPIException(data=msg)

        host_lun_id = self.rmt_client.get_host_lun_id(host_id, lun_id)

        # Return FC properties.
        fc_info = {'driver_volume_type': 'fibre_channel',
                   'data': {'target_lun': int(host_lun_id),
                            'target_discovered': True,
                            'target_wwn': tgt_port_wwns,
                            'volume_id': volume.id,
                            'initiator_target_map': init_targ_map,
                            'map_info': map_info},
                   }

        LOG.info(_LI('Remote return FC info is: %s.'), fc_info)

        return fc_info
Пример #51
0
    def initialize_connection_iscsi(self, volume, connector):
        """Map a volume to a host and return target iSCSI information."""
        LOG.info(_LI('Enter initialize_connection_iscsi.'))
        initiator_name = connector['initiator']
        volume_name = huawei_utils.encode_name(volume['id'])

        LOG.info(_LI(
            'initiator name: %(initiator_name)s, '
            'volume name: %(volume)s.'),
            {'initiator_name': initiator_name,
             'volume': volume_name})

        (iscsi_iqns,
         target_ips,
         portgroup_id) = self.restclient.get_iscsi_params(self.xml_file_path,
                                                          connector)
        LOG.info(_LI('initialize_connection_iscsi, iscsi_iqn: %(iscsi_iqn)s, '
                     'target_ip: %(target_ip)s, '
                     'portgroup_id: %(portgroup_id)s.'),
                 {'iscsi_iqn': iscsi_iqns,
                  'target_ip': target_ips,
                  'portgroup_id': portgroup_id},)

        # Create hostgroup if not exist.
        host_name = connector['host']
        host_name_before_hash = None
        if host_name and (len(host_name) > constants.MAX_HOSTNAME_LENGTH):
            host_name_before_hash = host_name
            host_name = six.text_type(hash(host_name))
        host_id = self.restclient.add_host_with_check(host_name,
                                                      host_name_before_hash)

        # Add initiator to the host.
        self.restclient.ensure_initiator_added(self.xml_file_path,
                                               initiator_name,
                                               host_id)
        hostgroup_id = self.restclient.add_host_into_hostgroup(host_id)

        # Mapping lungroup and hostgroup to view.
        lun_id = self.restclient.mapping_hostgroup_and_lungroup(volume_name,
                                                                hostgroup_id,
                                                                host_id,
                                                                portgroup_id)

        hostlun_id = self.restclient.find_host_lun_id(host_id, lun_id)

        LOG.info(_LI("initialize_connection_iscsi, host lun id is: %s."),
                 hostlun_id)

        iscsi_conf = huawei_utils.get_iscsi_conf(self.xml_file_path)
        chapinfo = self.restclient.find_chap_info(iscsi_conf,
                                                  initiator_name)
        # Return iSCSI properties.
        properties = {}
        properties['target_discovered'] = False
        properties['volume_id'] = volume['id']
        multipath = connector.get('multipath', False)
        hostlun_id = int(hostlun_id)
        if not multipath:
            properties['target_portal'] = ('%s:3260' % target_ips[0])
            properties['target_iqn'] = iscsi_iqns[0]
            properties['target_lun'] = hostlun_id
        else:
            properties['target_iqns'] = [iqn for iqn in iscsi_iqns]
            properties['target_portals'] = [
                '%s:3260' % ip for ip in target_ips]
            properties['target_luns'] = [hostlun_id] * len(target_ips)

        # If use CHAP, return CHAP info.
        if chapinfo:
            chap_username, chap_password = chapinfo.split(';')
            properties['auth_method'] = 'CHAP'
            properties['auth_username'] = chap_username
            properties['auth_password'] = chap_password

        LOG.info(_LI("initialize_connection_iscsi success. Return data: %s."),
                 properties)
        return {'driver_volume_type': 'iscsi', 'data': properties}
Пример #52
0
    def terminate_connection(self, volume, connector, **kwargs):
        """Delete map between a volume and a host."""
        wwns = connector['wwpns']
        volume_name = huawei_utils.encode_name(volume['id'])
        lun_id = volume.get('provider_location')
        host_name = connector['host']
        left_lunnum = -1
        lungroup_id = None
        view_id = None
        LOG.info(
            _LI('terminate_connection: volume name: %(volume)s, '
                'wwpns: %(wwns)s, '
                'lun_id: %(lunid)s.'),
            {
                'volume': volume_name,
                'wwns': wwns,
                'lunid': lun_id
            },
        )

        if host_name and len(host_name) > constants.MAX_HOSTNAME_LENGTH:
            host_name = six.text_type(hash(host_name))
        host_id = self.restclient.find_host(host_name)
        if host_id:
            mapping_view_name = constants.MAPPING_VIEW_PREFIX + host_id
            view_id = self.restclient.find_mapping_view(mapping_view_name)
            if view_id:
                lungroup_id = self.restclient.find_lungroup_from_map(view_id)

        if lun_id and self.restclient.check_lun_exist(lun_id):
            if lungroup_id:
                lungroup_ids = self.restclient.get_lungroupids_by_lunid(lun_id)
                if lungroup_id in lungroup_ids:
                    self.restclient.remove_lun_from_lungroup(
                        lungroup_id, lun_id)
                else:
                    LOG.warning(
                        _LW("Lun is not in lungroup. "
                            "Lun id: %(lun_id)s. "
                            "Lungroup id: %(lungroup_id)s."), {
                                "lun_id": lun_id,
                                "lungroup_id": lungroup_id
                            })
        else:
            LOG.warning(_LW("Can't find lun on the array."))
        if lungroup_id:
            left_lunnum = self.restclient.get_lunnum_from_lungroup(lungroup_id)
        if int(left_lunnum) > 0:
            info = {'driver_volume_type': 'fibre_channel', 'data': {}}
        else:
            if not self.fcsan_lookup_service:
                self.fcsan_lookup_service = fczm_utils.create_lookup_service()

            if self.fcsan_lookup_service:
                zone_helper = fc_zone_helper.FCZoneHelper(
                    self.fcsan_lookup_service, self.restclient)

                (tgt_port_wwns,
                 init_targ_map) = (zone_helper.build_ini_targ_map(wwns))
            else:
                (tgt_port_wwns,
                 init_targ_map) = (self.restclient.get_init_targ_map(wwns))

            for wwn in wwns:
                if self.restclient.is_fc_initiator_associated_to_host(wwn):
                    self.restclient.remove_fc_from_host(wwn)
            if lungroup_id:
                if view_id and self.restclient.lungroup_associated(
                        view_id, lungroup_id):
                    self.restclient.delete_lungroup_mapping_view(
                        view_id, lungroup_id)
                self.restclient.delete_lungroup(lungroup_id)

            if host_id:
                hostgroup_name = constants.HOSTGROUP_PREFIX + host_id
                hostgroup_id = self.restclient.find_hostgroup(hostgroup_name)
                if hostgroup_id:
                    if view_id and self.restclient.hostgroup_associated(
                            view_id, hostgroup_id):
                        self.restclient.delete_hostgoup_mapping_view(
                            view_id, hostgroup_id)
                    self.restclient.remove_host_from_hostgroup(
                        hostgroup_id, host_id)
                    self.restclient.delete_hostgroup(hostgroup_id)

                if not self.restclient.check_fc_initiators_exist_in_host(
                        host_id):
                    self.restclient.remove_host(host_id)

            if view_id:
                self.restclient.delete_mapping_view(view_id)

            info = {
                'driver_volume_type': 'fibre_channel',
                'data': {
                    'target_wwn': tgt_port_wwns,
                    'initiator_target_map': init_targ_map
                }
            }
        LOG.info(_LI("terminate_connection, return data is: %s."), info)

        return info
Пример #53
0
    def terminate_connection_iscsi(self, volume, connector):
        """Delete map between a volume and a host."""
        initiator_name = connector['initiator']
        volume_name = huawei_utils.encode_name(volume['id'])
        lun_id = volume.get('provider_location', None)
        host_name = connector['host']

        LOG.info(_LI(
            'terminate_connection_iscsi: volume name: %(volume)s, '
            'initiator name: %(ini)s, '
            'lun_id: %(lunid)s.'),
            {'volume': volume_name,
             'ini': initiator_name,
             'lunid': lun_id},)

        iscsi_conf = huawei_utils.get_iscsi_conf(self.xml_file_path)
        portgroup = None
        portgroup_id = None
        left_lunnum = -1
        for ini in iscsi_conf['Initiator']:
            if ini['Name'] == initiator_name:
                for key in ini:
                    if key == 'TargetPortGroup':
                        portgroup = ini['TargetPortGroup']
                        break
        # Remove lun from lungroup.
        if lun_id:
            if self.restclient.check_lun_exist(lun_id):
                # Get lungroup id by lun id.
                lungroup_id = self.restclient.get_lungroupid_by_lunid(lun_id)
                if lungroup_id:
                    self.restclient.remove_lun_from_lungroup(lungroup_id,
                                                             lun_id)
            else:
                LOG.warning(_LW("Can't find lun on the array."))
        # Remove portgroup from mapping view if no lun left in lungroup.
        if portgroup:
            portgroup_id = self.restclient.find_tgt_port_group(portgroup)
        host_id = self.restclient.find_host(host_name)
        if host_id:
            mapping_view_name = constants.MAPPING_VIEW_PREFIX + host_id
            view_id = self.restclient.find_mapping_view(mapping_view_name)
            if view_id:
                lungroup_id = self.restclient.find_lungroup_from_map(view_id)
        if lungroup_id:
            left_lunnum = self.restclient.get_lunnum_from_lungroup(lungroup_id)

        if portgroup_id and view_id and (int(left_lunnum) <= 0):
            if self.restclient.is_portgroup_associated_to_view(view_id,
                                                               portgroup_id):
                self.restclient.delete_portgroup_mapping_view(view_id,
                                                              portgroup_id)
        if view_id and (int(left_lunnum) <= 0):
            self.restclient.remove_chap(initiator_name)

            if self.restclient.lungroup_associated(view_id, lungroup_id):
                self.restclient.delete_lungroup_mapping_view(view_id,
                                                             lungroup_id)
            self.restclient.delete_lungroup(lungroup_id)
            if self.restclient.is_initiator_associated_to_host(initiator_name):
                self.restclient.remove_iscsi_from_host(initiator_name)
            hostgroup_name = constants.HOSTGROUP_PREFIX + host_id
            hostgroup_id = self.restclient.find_hostgroup(hostgroup_name)
            if hostgroup_id:
                if self.restclient.hostgroup_associated(view_id, hostgroup_id):
                    self.restclient.delete_hostgoup_mapping_view(view_id,
                                                                 hostgroup_id)
                self.restclient.remove_host_from_hostgroup(hostgroup_id,
                                                           host_id)
                self.restclient.delete_hostgroup(hostgroup_id)
            self.restclient.remove_host(host_id)
            self.restclient.delete_mapping_view(view_id)
Пример #54
0
    def initialize_connection(self, volume, connector):
        wwns = connector['wwpns']
        volume_name = huawei_utils.encode_name(volume['id'])
        LOG.info(_LI(
            'initialize_connection, initiator: %(wwpns)s,'
            ' volume name: %(volume)s.'),
            {'wwpns': wwns,
             'volume': volume_name},)

        host_name_before_hash = None
        host_name = connector['host']
        if host_name and (len(host_name) > constants.MAX_HOSTNAME_LENGTH):
            host_name_before_hash = host_name
            host_name = six.text_type(hash(host_name))

        if not self.fcsan_lookup_service:
            self.fcsan_lookup_service = fczm_utils.create_lookup_service()

        if self.fcsan_lookup_service:
            # Use FC switch.
            host_id = self.restclient.add_host_with_check(
                host_name, host_name_before_hash)
            zone_helper = fc_zone_helper.FCZoneHelper(
                self.fcsan_lookup_service, self.restclient)
            (tgt_port_wwns, init_targ_map) = (
                zone_helper.build_ini_targ_map(wwns))
            for ini in init_targ_map:
                self.restclient.ensure_fc_initiator_added(ini, host_id)
        else:
            # Not use FC switch.
            host_id = self.restclient.add_host_with_check(
                host_name, host_name_before_hash)
            online_wwns_in_host = (
                self.restclient.get_host_online_fc_initiators(host_id))
            online_free_wwns = self.restclient.get_online_free_wwns()
            for wwn in wwns:
                if (wwn not in online_wwns_in_host
                        and wwn not in online_free_wwns):
                    wwns_in_host = (
                        self.restclient.get_host_fc_initiators(host_id))
                    iqns_in_host = (
                        self.restclient.get_host_iscsi_initiators(host_id))
                    if not wwns_in_host and not iqns_in_host:
                        self.restclient.remove_host(host_id)

                    msg = (_('Can not add FC initiator to host.'))
                    LOG.error(msg)
                    raise exception.VolumeBackendAPIException(data=msg)

            for wwn in wwns:
                if wwn in online_free_wwns:
                    self.restclient.add_fc_port_to_host(host_id, wwn)

            (tgt_port_wwns, init_targ_map) = (
                self.restclient.get_init_targ_map(wwns))

        # Add host into hostgroup.
        hostgroup_id = self.restclient.add_host_into_hostgroup(host_id)
        lun_id = self.restclient.mapping_hostgroup_and_lungroup(volume_name,
                                                                hostgroup_id,
                                                                host_id)
        host_lun_id = self.restclient.find_host_lun_id(host_id, lun_id)

        # Return FC properties.
        info = {'driver_volume_type': 'fibre_channel',
                'data': {'target_lun': int(host_lun_id),
                         'target_discovered': True,
                         'target_wwn': tgt_port_wwns,
                         'volume_id': volume['id'],
                         'initiator_target_map': init_targ_map}, }

        LOG.info(_LI("initialize_connection, return data is: %s."),
                 info)

        return info
Пример #55
0
    def terminate_connection(self, volume, connector, **kwargs):
        """Delete map between a volume and a host."""
        wwns = connector['wwpns']
        volume_name = huawei_utils.encode_name(volume['id'])
        lun_id = volume.get('provider_location', None)
        host_name = connector['host']
        left_lunnum = -1
        lungroup_id = None
        view_id = None
        LOG.info(_LI('terminate_connection: volume name: %(volume)s, '
                     'wwpns: %(wwns)s, '
                     'lun_id: %(lunid)s.'),
                 {'volume': volume_name,
                  'wwns': wwns,
                  'lunid': lun_id},)

        if host_name and len(host_name) > constants.MAX_HOSTNAME_LENGTH:
            host_name = six.text_type(hash(host_name))
        host_id = self.restclient.find_host(host_name)
        if host_id:
            mapping_view_name = constants.MAPPING_VIEW_PREFIX + host_id
            view_id = self.restclient.find_mapping_view(mapping_view_name)
            if view_id:
                lungroup_id = self.restclient.find_lungroup_from_map(view_id)

        if lun_id and self.restclient.check_lun_exist(lun_id):
            if lungroup_id:
                lungroup_ids = self.restclient.get_lungroupids_by_lunid(lun_id)
                if lungroup_id in lungroup_ids:
                    self.restclient.remove_lun_from_lungroup(lungroup_id,
                                                             lun_id)
                else:
                    LOG.warning(_LW("Lun is not in lungroup. "
                                    "Lun id: %(lun_id)s. "
                                    "Lungroup id: %(lungroup_id)s."),
                                {"lun_id": lun_id,
                                 "lungroup_id": lungroup_id})
        else:
            LOG.warning(_LW("Can't find lun on the array."))
        if lungroup_id:
            left_lunnum = self.restclient.get_lunnum_from_lungroup(lungroup_id)
        if int(left_lunnum) > 0:
            info = {'driver_volume_type': 'fibre_channel',
                    'data': {}}
        else:
            if not self.fcsan_lookup_service:
                self.fcsan_lookup_service = fczm_utils.create_lookup_service()

            if self.fcsan_lookup_service:
                zone_helper = fc_zone_helper.FCZoneHelper(
                    self.fcsan_lookup_service, self.restclient)

                (tgt_port_wwns, init_targ_map) = (
                    zone_helper.build_ini_targ_map(wwns))
            else:
                (tgt_port_wwns, init_targ_map) = (
                    self.restclient.get_init_targ_map(wwns))

            for wwn in wwns:
                if self.restclient.is_fc_initiator_associated_to_host(wwn):
                    self.restclient.remove_fc_from_host(wwn)
            if lungroup_id:
                if view_id and self.restclient.lungroup_associated(
                        view_id, lungroup_id):
                    self.restclient.delete_lungroup_mapping_view(view_id,
                                                                 lungroup_id)
                self.restclient.delete_lungroup(lungroup_id)

            if host_id:
                hostgroup_name = constants.HOSTGROUP_PREFIX + host_id
                hostgroup_id = self.restclient.find_hostgroup(hostgroup_name)
                if hostgroup_id:
                    if view_id and self.restclient.hostgroup_associated(
                            view_id, hostgroup_id):
                        self.restclient.delete_hostgoup_mapping_view(
                            view_id, hostgroup_id)
                    self.restclient.remove_host_from_hostgroup(
                        hostgroup_id, host_id)
                    self.restclient.delete_hostgroup(hostgroup_id)

                if not self.restclient.check_fc_initiators_exist_in_host(
                        host_id):
                    self.restclient.remove_host(host_id)

            if view_id:
                self.restclient.delete_mapping_view(view_id)

            info = {'driver_volume_type': 'fibre_channel',
                    'data': {'target_wwn': tgt_port_wwns,
                             'initiator_target_map': init_targ_map}}
        LOG.info(_LI("terminate_connection, return data is: %s."),
                 info)

        return info
Пример #56
0
    def disconnect_volume_fc(self, volume, connector):
        """Delete map between a volume and a host for FC."""
        wwns = connector['wwpns']
        volume_name = huawei_utils.encode_name(volume.id)
        metadata = huawei_utils.get_volume_metadata(volume)
        lun_id = metadata['remote_lun_id']
        host_name = connector['host']
        left_lunnum = -1
        lungroup_id = None
        view_id = None

        LOG.info(_LI('terminate_connection_fc: volume name: %(volume)s, '
                     'wwpns: %(wwns)s, '
                     'lun_id: %(lunid)s.'),
                 {'volume': volume_name,
                  'wwns': wwns,
                  'lunid': lun_id},)

        host_name = huawei_utils.encode_host_name(host_name)
        hostid = self.rmt_client.get_host_id_by_name(host_name)
        if hostid:
            mapping_view_name = constants.MAPPING_VIEW_PREFIX + hostid
            view_id = self.rmt_client.find_mapping_view(
                mapping_view_name)
            if view_id:
                lungroup_id = self.rmt_client.find_lungroup_from_map(
                    view_id)

        if lun_id and self.rmt_client.check_lun_exist(lun_id):
            if lungroup_id:
                lungroup_ids = self.rmt_client.get_lungroupids_by_lunid(
                    lun_id)
                if lungroup_id in lungroup_ids:
                    self.rmt_client.remove_lun_from_lungroup(
                        lungroup_id, lun_id)
                else:
                    LOG.warning(_LW("Lun is not in lungroup. "
                                    "Lun id: %(lun_id)s, "
                                    "lungroup id: %(lungroup_id)s"),
                                {"lun_id": lun_id,
                                 "lungroup_id": lungroup_id})

        (tgt_port_wwns, init_targ_map) = (
            self.rmt_client.get_init_targ_map(wwns))

        hostid = self.rmt_client.get_host_id_by_name(host_name)
        if hostid:
            mapping_view_name = constants.MAPPING_VIEW_PREFIX + hostid
            view_id = self.rmt_client.find_mapping_view(
                mapping_view_name)
            if view_id:
                lungroup_id = self.rmt_client.find_lungroup_from_map(
                    view_id)
        if lungroup_id:
            left_lunnum = self.rmt_client.get_lunnum_from_lungroup(
                lungroup_id)

        if int(left_lunnum) > 0:
            info = {'driver_volume_type': 'fibre_channel',
                    'data': {}}
        else:
            info = {'driver_volume_type': 'fibre_channel',
                    'data': {'target_wwn': tgt_port_wwns,
                             'initiator_target_map': init_targ_map}, }

        return info