Exemple #1
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']})
        model_update = {}
        model_update['status'] = group['status']
        metrogroup_id = self.check_consistencygroup_need_to_stop(group)
        if metrogroup_id:
            # Deal with add volumes to CG
            for volume in add_volumes:
                metadata = huawei_utils.get_volume_metadata(volume)
                metro_id = metadata['hypermetro_id']
                if metro_id and self.client.check_hypermetro_exist(metro_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)
                else:
                    err_msg = _("Hypermetro pair doesn't exist on array.")
                    LOG.error(err_msg)
                    raise exception.VolumeBackendAPIException(data=err_msg)

            # Deal with remove volumes from CG
            for volume in remove_volumes:
                metadata = huawei_utils.get_volume_metadata(volume)
                metro_id = metadata['hypermetro_id']
                if metro_id and self.client.check_hypermetro_exist(metro_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.client.sync_hypermetro(metro_id)
                else:
                    err_msg = _("Hypermetro pair doesn't exist on array.")
                    LOG.error(err_msg)
                    raise exception.VolumeBackendAPIException(data=err_msg)

            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)

        # if CG not exist on array
        else:
            msg = _("The CG does not exist on array.")
            LOG.error(msg)
            raise exception.VolumeBackendAPIException(data=msg)
    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']})
        model_update = {}
        model_update['status'] = group['status']
        metrogroup_id = self.check_consistencygroup_need_to_stop(group)
        if metrogroup_id:
            # Deal with add volumes to CG
            for volume in add_volumes:
                metadata = huawei_utils.get_volume_metadata(volume)
                metro_id = metadata['hypermetro_id']
                if metro_id and self.client.check_hypermetro_exist(metro_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)
                else:
                    err_msg = _("Hypermetro pair doesn't exist on array.")
                    LOG.error(err_msg)
                    raise exception.VolumeBackendAPIException(data=err_msg)

            # Deal with remove volumes from CG
            for volume in remove_volumes:
                metadata = huawei_utils.get_volume_metadata(volume)
                metro_id = metadata['hypermetro_id']
                if metro_id and self.client.check_hypermetro_exist(metro_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.client.sync_hypermetro(metro_id)
                else:
                    err_msg = _("Hypermetro pair doesn't exist on array.")
                    LOG.error(err_msg)
                    raise exception.VolumeBackendAPIException(data=err_msg)

            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)

        # if CG not exist on array
        else:
            msg = _("The CG does not exist on array.")
            LOG.error(msg)
            raise exception.VolumeBackendAPIException(data=msg)
    def failover_replica(self, volume):
        """Just make the secondary available."""
        LOG.debug('Failover replication, volume: %s.', volume['id'])

        info = get_replication_driver_data(volume)
        pair_id = info.get('pair_id')
        if not pair_id:
            msg = _('No pair id in volume replication_driver_data.')
            LOG.error(msg)
            raise exception.VolumeBackendAPIException(data=msg)

        rmt_lun_id = info.get('rmt_lun_id')
        if not rmt_lun_id:
            msg = _('No remote LUN id in volume replication_driver_data.')
            LOG.error(msg)
            raise exception.VolumeBackendAPIException(data=msg)

        # Remote array must be available. So we can get the real pool info.
        lun_info = self.rmt_client.get_lun_info(rmt_lun_id)
        lun_wwn = lun_info.get('WWN')
        lun_pool = lun_info.get('PARENTNAME')
        new_backend = re.sub(r'(?<=#).*$', lun_pool, self.rmt_backend)

        self.rmt_driver.failover(pair_id)

        metadata = huawei_utils.get_volume_metadata(volume)
        metadata.update({'lun_wwn': lun_wwn})

        new_driver_data = {'pair_id': pair_id,
                           'rmt_lun_id': volume['provider_location']}
        new_driver_data = to_string(new_driver_data)
        return {'host': new_backend,
                'provider_location': rmt_lun_id,
                'replication_driver_data': new_driver_data,
                'metadata': metadata}
    def delete_hypermetro(self, volume):
        """Delete hypermetro."""
        metadata = huawei_utils.get_volume_metadata(volume)
        metro_id = metadata['hypermetro_id']
        remote_lun_id = metadata['remote_lun_id']

        if metro_id:
            exst_flag = self.client.check_hypermetro_exist(metro_id)
            if exst_flag:
                metro_info = self.client.get_hypermetro_by_id(metro_id)
                metro_status = int(metro_info['data']['RUNNINGSTATUS'])

                LOG.debug("Hypermetro status is: %s.", metro_status)
                if constants.HYPERMETRO_RUNNSTATUS_STOP != metro_status:
                    self.client.stop_hypermetro(metro_id)

                # Delete hypermetro
                self.client.delete_hypermetro(metro_id)

        # Delete remote lun.
        if remote_lun_id:
            metro_devices = self.configuration.hypermetro_devices
            device_info = huawei_utils.get_remote_device_info(metro_devices)
            self.rmt_client = rest_client.RestClient(self.configuration)
            self.rmt_client.login_with_ip(device_info)

            try:
                if self.rmt_client.check_lun_exist(remote_lun_id):
                    self.rmt_client.delete_lun(remote_lun_id)
            except Exception as err:
                msg = _("Delete remote lun err. %s.") % err
                LOG.exception(msg)
                raise exception.VolumeBackendAPIException(data=msg)
            finally:
                self.rmt_client.logout()
Exemple #5
0
    def delete_hypermetro(self, volume):
        """Delete hypermetro."""
        metadata = huawei_utils.get_volume_metadata(volume)
        metro_id = metadata["hypermetro_id"]
        remote_lun_id = metadata["remote_lun_id"]

        if metro_id:
            exst_flag = self.client.check_hypermetro_exist(metro_id)
            if exst_flag:
                metro_info = self.client.get_hypermetro_by_id(metro_id)
                metro_status = int(metro_info["data"]["RUNNINGSTATUS"])

                LOG.debug("Hypermetro status is: %s.", metro_status)
                if constants.HYPERMETRO_RUNNSTATUS_STOP != metro_status:
                    self.client.stop_hypermetro(metro_id)

                # Delete hypermetro
                self.client.delete_hypermetro(metro_id)

        # Delete remote lun.
        if remote_lun_id:
            metro_devices = self.configuration.hypermetro_devices
            device_info = huawei_utils.get_remote_device_info(metro_devices)
            self.rmt_client = rest_client.RestClient(self.configuration)
            self.rmt_client.login_with_ip(device_info)

            try:
                if self.rmt_client.check_lun_exist(remote_lun_id):
                    self.rmt_client.delete_lun(remote_lun_id)
            except Exception as err:
                msg = _("Delete remote lun err. %s.") % err
                LOG.exception(msg)
                raise exception.VolumeBackendAPIException(data=msg)
            finally:
                self.rmt_client.logout()
Exemple #6
0
    def failback(self, volumes):
        """Failover volumes back to primary backend.

        The main steps:
        1. Switch the role of replication pairs.
        2. Copy the second LUN data back to primary LUN.
        3. Split replication pairs.
        4. Switch the role of replication pairs.
        5. Enable replications.
        """
        volumes_update = []
        for v in volumes:
            v_update = {}
            v_update['volume_id'] = v['id']
            drv_data = get_replication_driver_data(v)
            pair_id = drv_data.get('pair_id')
            if not pair_id:
                LOG.warning(_LW("No pair id in volume %s."), v['id'])
                v_update['updates'] = {'replication_status': 'error'}
                volumes_update.append(v_update)
                continue

            rmt_lun_id = drv_data.get('rmt_lun_id')
            if not rmt_lun_id:
                LOG.warning(_LW("No remote lun id in volume %s."), v['id'])
                v_update['updates'] = {'replication_status': 'error'}
                volumes_update.append(v_update)
                continue

            # Switch replication pair role, and start synchronize.
            self.local_driver.enable(pair_id)

            # Wait for synchronize complete.
            self.local_driver.wait_replica_ready(pair_id)

            # Split replication pair again
            self.rmt_driver.failover(pair_id)

            # Switch replication pair role, and start synchronize.
            self.rmt_driver.enable(pair_id)

            lun_info = self.rmt_client.get_lun_info(rmt_lun_id)
            lun_wwn = lun_info.get('WWN')
            metadata = huawei_utils.get_volume_metadata(v)
            metadata.update({'lun_wwn': lun_wwn})
            new_drv_data = {'pair_id': pair_id,
                            'rmt_lun_id': v['provider_location']}
            new_drv_data = to_string(new_drv_data)
            v_update['updates'] = {'provider_location': rmt_lun_id,
                                   'replication_status': 'available',
                                   'replication_driver_data': new_drv_data,
                                   'metadata': metadata}
            volumes_update.append(v_update)

        return volumes_update
    def delete_hypermetro(self, volume):
        """Delete hypermetro."""
        metadata = huawei_utils.get_volume_metadata(volume)
        metro_id = metadata['hypermetro_id']
        remote_lun_id = metadata['remote_lun_id']

        # Delete hypermetro.
        if metro_id and self.client.check_hypermetro_exist(metro_id):
            self.check_metro_need_to_stop(metro_id)
            self.client.delete_hypermetro(metro_id)

        # Delete remote lun.
        if remote_lun_id and self.rmt_client.check_lun_exist(remote_lun_id):
            self.rmt_client.delete_lun(remote_lun_id)
Exemple #8
0
    def delete_hypermetro(self, volume):
        """Delete hypermetro."""
        metadata = huawei_utils.get_volume_metadata(volume)
        metro_id = metadata['hypermetro_id']
        remote_lun_id = metadata['remote_lun_id']

        # Delete hypermetro.
        if metro_id and self.client.check_hypermetro_exist(metro_id):
            self.check_metro_need_to_stop(metro_id)
            self.client.delete_hypermetro(metro_id)

        # Delete remote lun.
        if remote_lun_id and self.rmt_client.check_lun_exist(remote_lun_id):
            self.rmt_client.delete_lun(remote_lun_id)
Exemple #9
0
    def check_metro_need_to_stop(self, volume):
        metadata = huawei_utils.get_volume_metadata(volume)
        metro_id = metadata['hypermetro_id']
        metro_existed = self.client.check_hypermetro_exist(metro_id)

        if metro_existed:
            metro_info = self.client.get_hypermetro_by_id(metro_id)
            metro_health_status = metro_info['HEALTHSTATUS']
            metro_running_status = metro_info['RUNNINGSTATUS']

            if (metro_health_status == constants.HEALTH_NORMAL and
                (metro_running_status == constants.RUNNING_NORMAL or
                    metro_running_status == constants.RUNNING_SYNC)):
                self.client.stop_hypermetro(metro_id)

        return metro_id
Exemple #10
0
    def check_metro_need_to_stop(self, volume):
        metadata = huawei_utils.get_volume_metadata(volume)
        metro_id = metadata['hypermetro_id']
        metro_existed = self.client.check_hypermetro_exist(metro_id)

        if metro_existed:
            metro_info = self.client.get_hypermetro_by_id(metro_id)
            metro_health_status = metro_info['HEALTHSTATUS']
            metro_running_status = metro_info['RUNNINGSTATUS']

            if (metro_health_status == constants.HEALTH_NORMAL and
                (metro_running_status == constants.RUNNING_NORMAL or
                    metro_running_status == constants.RUNNING_SYNC)):
                self.client.stop_hypermetro(metro_id)

        return metro_id
    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 metrogroup_id:
            # Remove pair from metrogroup.
            for volume in volumes:
                metadata = huawei_utils.get_volume_metadata(volume)
                metro_id = metadata['hypermetro_id']
                if metro_id and self.client.check_hypermetro_exist(metro_id):
                    if self._check_metro_in_cg(metro_id, metrogroup_id):
                        self.client.remove_metro_from_metrogroup(metrogroup_id,
                                                                 metro_id)
                else:
                    err = (_("Hypermetro pair %(id)s doesn't exist on array.")
                           % {'id': metro_id})
                    LOG.warning(err)

            # Delete metrogroup.
            self.client.delete_metrogroup(metrogroup_id)
    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 metrogroup_id:
            # Remove pair from metrogroup.
            for volume in volumes:
                metadata = huawei_utils.get_volume_metadata(volume)
                metro_id = metadata['hypermetro_id']
                if metro_id and self.client.check_hypermetro_exist(metro_id):
                    if self._check_metro_in_cg(metro_id, metrogroup_id):
                        self.client.remove_metro_from_metrogroup(metrogroup_id,
                                                                 metro_id)
                else:
                    err = (_("Hypermetro pair %(id)s doesn't exist on array.")
                           % {'id': metro_id})
                    LOG.warning(err)

            # Delete metrogroup.
            self.client.delete_metrogroup(metrogroup_id)
Exemple #13
0
    def failover(self, volumes):
        """Failover volumes back to secondary array.

        Split the replication pairs and make the secondary LUNs R&W.
        """
        volumes_update = []
        for v in volumes:
            v_update = {}
            v_update['volume_id'] = v['id']
            drv_data = get_replication_driver_data(v)
            pair_id = drv_data.get('pair_id')
            if not pair_id:
                LOG.warning(_LW("No pair id in volume %s."), v['id'])
                v_update['updates'] = {'replication_status': 'error'}
                volumes_update.append(v_update)
                continue

            rmt_lun_id = drv_data.get('rmt_lun_id')
            if not rmt_lun_id:
                LOG.warning(_LW("No remote lun id in volume %s."), v['id'])
                v_update['updates'] = {'replication_status': 'error'}
                volumes_update.append(v_update)
                continue

            self.rmt_driver.failover(pair_id)

            lun_info = self.rmt_client.get_lun_info(rmt_lun_id)
            lun_wwn = lun_info.get('WWN')
            metadata = huawei_utils.get_volume_metadata(v)
            metadata.update({'lun_wwn': lun_wwn})
            new_drv_data = {'pair_id': pair_id,
                            'rmt_lun_id': v['provider_location']}
            new_drv_data = to_string(new_drv_data)
            v_update['updates'] = {'provider_location': rmt_lun_id,
                                   'replication_status': 'failed-over',
                                   'replication_driver_data': new_drv_data,
                                   'metadata': metadata}
            volumes_update.append(v_update)

        return volumes_update
Exemple #14
0
    def delete_hypermetro(self, volume):
        """Delete hypermetro."""
        metadata = huawei_utils.get_volume_metadata(volume)
        metro_id = metadata['hypermetro_id']
        remote_lun_id = metadata['remote_lun_id']

        if metro_id:
            exst_flag = self.client.check_hypermetro_exist(metro_id)
            if exst_flag:
                metro_info = self.client.get_hypermetro_by_id(metro_id)
                metro_status = int(metro_info['data']['RUNNINGSTATUS'])

                LOG.debug("Hypermetro status is: %s.", metro_status)
                if constants.HYPERMETRO_RUNNSTATUS_STOP != metro_status:
                    self.client.stop_hypermetro(metro_id)

                # Delete hypermetro
                self.client.delete_hypermetro(metro_id)

        # Delete remote lun.
        if remote_lun_id and self.rmt_client.check_lun_exist(remote_lun_id):
            self.rmt_client.delete_lun(remote_lun_id)
Exemple #15
0
    def delete_hypermetro(self, volume):
        """Delete hypermetro."""
        metadata = huawei_utils.get_volume_metadata(volume)
        metro_id = metadata['hypermetro_id']
        remote_lun_id = metadata['remote_lun_id']

        if metro_id:
            exst_flag = self.client.check_hypermetro_exist(metro_id)
            if exst_flag:
                metro_info = self.client.get_hypermetro_by_id(metro_id)
                metro_status = int(metro_info['data']['RUNNINGSTATUS'])

                LOG.debug("Hypermetro status is: %s.", metro_status)
                if constants.HYPERMETRO_RUNNSTATUS_STOP != metro_status:
                    self.client.stop_hypermetro(metro_id)

                # Delete hypermetro
                self.client.delete_hypermetro(metro_id)

        # Delete remote lun.
        if remote_lun_id and self.rmt_client.check_lun_exist(remote_lun_id):
            self.rmt_client.delete_lun(remote_lun_id)
    def connect_volume_fc(self, volume, connector):
        """Create map between a volume and a host for FC."""
        self.xml_file_path = self.configuration.cinder_huawei_conf_file
        metro_devices = self.configuration.hypermetro_devices
        device_info = huawei_utils.get_remote_device_info(metro_devices)
        self.rmt_client = rest_client.RestClient(self.configuration)
        self.rmt_client.login_with_ip(device_info)

        try:
            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_volume_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)

            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.rmt_client.add_host_with_check(
                host_name, host_name_before_hash)

            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 and not 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_into_hostgroup(host_id)
            map_info = self.rmt_client.do_mapping(lun_id,
                                                  hostgroup_id,
                                                  host_id)
            host_lun_id = self.rmt_client.find_host_lun_id(host_id, lun_id)
        except exception.VolumeBackendAPIException:
            raise
        except Exception as err:
            msg = _("Connect volume fc: connect volume error. %s.") % err
            LOG.exception(msg)
            raise exception.VolumeBackendAPIException(data=msg)

        # 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
Exemple #17
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
Exemple #18
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
Exemple #19
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
Exemple #20
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)
        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
    def disconnect_volume_fc(self, volume, connector):
        """Delete map between a volume and a host for FC."""
        # Login remote storage device.
        self.xml_file_path = self.configuration.cinder_huawei_conf_file
        metro_devices = self.configuration.hypermetro_devices
        device_info = huawei_utils.get_remote_device_info(metro_devices)
        self.rmt_client = rest_client.RestClient(self.configuration)
        self.rmt_client.login_with_ip(device_info)

        try:
            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},)

            if host_name and (len(host_name) > constants.MAX_HOSTNAME_LENGTH):
                host_name = six.text_type(hash(host_name))

            hostid = self.rmt_client.find_host(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.find_host(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)

        except Exception as err:
            msg = _("Remote detatch volume error. %s.") % err
            LOG.exception(msg)
            raise exception.VolumeBackendAPIException(data=msg)
        finally:
            self.rmt_client.logout()

        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
Exemple #22
0
    def disconnect_volume_fc(self, volume, connector):
        """Delete map between a volume and a host for FC."""
        # Login remote storage device.
        self.xml_file_path = self.configuration.cinder_huawei_conf_file
        metro_devices = self.configuration.hypermetro_devices
        device_info = huawei_utils.get_remote_device_info(metro_devices)
        self.rmt_client = rest_client.RestClient(self.configuration)
        self.rmt_client.login_with_ip(device_info)

        try:
            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},
            )

            if host_name and (len(host_name) > constants.MAX_HOSTNAME_LENGTH):
                host_name = six.text_type(hash(host_name))

            hostid = self.rmt_client.find_host(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.find_host(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)

        except Exception as err:
            msg = _("Remote detatch volume error. %s.") % err
            LOG.exception(msg)
            raise exception.VolumeBackendAPIException(data=msg)
        finally:
            self.rmt_client.logout()

        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
Exemple #23
0
    def connect_volume_fc(self, volume, connector):
        """Create map between a volume and a host for FC."""
        self.xml_file_path = self.configuration.cinder_huawei_conf_file
        metro_devices = self.configuration.hypermetro_devices
        device_info = huawei_utils.get_remote_device_info(metro_devices)
        self.rmt_client = rest_client.RestClient(self.configuration)
        self.rmt_client.login_with_ip(device_info)

        try:
            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_volume_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)

            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.rmt_client.add_host_with_check(host_name, host_name_before_hash)

            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 and not 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_into_hostgroup(host_id)
            map_info = self.rmt_client.do_mapping(lun_id, hostgroup_id, host_id)
            host_lun_id = self.rmt_client.find_host_lun_id(host_id, lun_id)
        except exception.VolumeBackendAPIException:
            raise
        except Exception as err:
            msg = _("Connect volume fc: connect volume error. %s.") % err
            LOG.exception(msg)
            raise exception.VolumeBackendAPIException(data=msg)

        # 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