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'])
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)
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