Exemplo n.º 1
0
def unmap_volume_from_host(client, volume, host, mapping):
    # Volume is mapped directly to host, so delete the mapping
    if mapping.get('mapRef') == host['hostRef']:
        LOG.debug(
            "Volume %(vol)s is mapped directly to host %(host)s; "
            "removing mapping.", {
                'vol': volume['id'],
                'host': host['label']
            })
        client.delete_volume_mapping(mapping['lunMappingRef'])
        return

    try:
        host_group = client.get_host_group(mapping['mapRef'])
    except exception.NotFound:
        # Volumes is mapped but to a different initiator
        raise eseries_exc.VolumeNotMapped(volume_id=volume['id'],
                                          host=host['label'])
    # If volume is mapped to a foreign host group raise error
    if host_group['label'] != utils.MULTI_ATTACH_HOST_GROUP_NAME:
        raise eseries_exc.UnsupportedHostGroup(volume_id=volume['id'],
                                               group=host_group['label'])
    # If target host is not in the multiattach host group
    if host['clusterRef'] != host_group['clusterRef']:
        raise eseries_exc.VolumeNotMapped(volume_id=volume['id'],
                                          host=host['label'])

    # Volume is mapped to multiattach host group
    # Remove mapping if volume should no longer be attached after this
    # operation.
    if volume['status'] == 'detaching':
        LOG.debug(
            "Volume %s is mapped directly to multiattach host group but "
            "is not currently attached; removing mapping.", volume['id'])
        client.delete_volume_mapping(mapping['lunMappingRef'])
Exemplo n.º 2
0
    def terminate_connection(self, volume, connector, **kwargs):
        """Disallow connection from connector."""
        eseries_vol = self._get_volume(volume['name_id'])
        initiator = connector['initiator']
        host = self._get_host_with_port(initiator)
        mappings = eseries_vol.get('listOfMappings', [])

        # There can only be one or zero mappings on a volume in E-Series
        mapping = mappings[0] if mappings else None

        if not mapping:
            raise eseries_exc.VolumeNotMapped(volume_id=volume['id'],
                                              host=host['label'])
        host_mapper.unmap_volume_from_host(self._client, volume, host, mapping)
Exemplo n.º 3
0
    def terminate_connection_fc(self, volume, connector, **kwargs):
        """Disallow connection from connector.

        Return empty data if other volumes are in the same zone.
        The FibreChannel ZoneManager doesn't remove zones
        if there isn't an initiator_target_map in the
        return of terminate_connection.

        :returns: data - the target_wwns and initiator_target_map if the
                         zone is to be removed, otherwise the same map with
                         an empty dict for the 'data' key
        """

        eseries_vol = self._get_volume(volume['name_id'])
        initiators = [
            fczm_utils.get_formatted_wwn(wwpn) for wwpn in connector['wwpns']
        ]
        host = self._get_host_with_matching_port(initiators)
        mappings = eseries_vol.get('listOfMappings', [])

        # There can only be one or zero mappings on a volume in E-Series
        mapping = mappings[0] if mappings else None

        if not mapping:
            raise eseries_exc.VolumeNotMapped(volume_id=volume['id'],
                                              host=host['label'])
        host_mapper.unmap_volume_from_host(self._client, volume, host, mapping)

        info = {'driver_volume_type': 'fibre_channel', 'data': {}}

        if len(self._client.get_volume_mappings_for_host(
                host['hostRef'])) == 0:
            # No more exports for this host, so tear down zone.
            LOG.info(
                _LI("Need to remove FC Zone, building initiator "
                    "target map."))

            initiator_info = self._build_initiator_target_map_fc(connector)
            target_wwpns, initiator_target_map, num_paths = initiator_info

            info['data'] = {
                'target_wwn': target_wwpns,
                'initiator_target_map': initiator_target_map
            }

        return info