Exemplo n.º 1
0
 def initialize_connection(self, volume, connector):
     """Attach K2 volume to host."""
     # Check wwpns in host connector.
     if not connector.get('wwpns'):
         msg = _("No wwpns found in host connector.")
         LOG.error(msg)
         raise common.KaminarioCinderDriverException(reason=msg)
     # To support replication failback
     temp_client = None
     if (hasattr(volume, 'replication_status') and
             volume.replication_status == K2_REP_FAILED_OVER):
         temp_client = self.client
         self.client = self.target
     # Get target wwpns.
     target_wwpns = self.get_target_info(volume)
     # Map volume.
     lun = self.k2_initialize_connection(volume, connector)
     # Create initiator-target mapping.
     target_wwpns, init_target_map = self._build_initiator_target_map(
         connector, target_wwpns)
     # To support replication failback
     if temp_client:
         self.client = temp_client
     # Return target volume information.
     conn_info = {'driver_volume_type': 'fibre_channel',
                  'data': {"target_discovered": True,
                           "target_lun": lun,
                           "target_wwn": target_wwpns,
                           "initiator_target_map": init_target_map}}
     fczm_utils.add_fc_zone(conn_info)
     return conn_info
Exemplo n.º 2
0
 def initialize_connection(self, volume, connector):
     """Attach K2 volume to host."""
     # Check wwpns in host connector.
     if not connector.get('wwpns'):
         msg = _("No wwpns found in host connector.")
         LOG.error(msg)
         raise common.KaminarioCinderDriverException(reason=msg)
     # To support replication failback
     temp_client = None
     if (hasattr(volume, 'replication_status') and
             volume.replication_status == K2_REP_FAILED_OVER):
         temp_client = self.client
         self.client = self.target
     # Get target wwpns.
     target_wwpns = self.get_target_info(volume)
     # Map volume.
     lun = self.k2_initialize_connection(volume, connector)
     # Create initiator-target mapping.
     target_wwpns, init_target_map = self._build_initiator_target_map(
         connector, target_wwpns)
     # To support replication failback
     if temp_client:
         self.client = temp_client
     # Return target volume information.
     conn_info = {'driver_volume_type': 'fibre_channel',
                  'data': {"target_discovered": True,
                           "target_lun": lun,
                           "target_wwn": target_wwpns,
                           "initiator_target_map": init_target_map}}
     fczm_utils.add_fc_zone(conn_info)
     return conn_info
Exemplo n.º 3
0
    def initialize_connection(self, volume, connector):
        LOG.debug(
            'enter: initialize_connection: volume '
            '%(vol)s with connector %(conn)s', {
                'vol': volume.id,
                'conn': connector
            })
        volume_name = self._convert_name(volume.name)
        ret = self._cmd.create_lun_map(volume_name, self.protocol,
                                       connector['wwpns'])
        if ret['key'] == 0:
            if 'lun' in ret['arr']:
                lun_id = int(ret['arr']['lun'])
            else:
                msg = (_('_create_fc_lun: Lun id did not find '
                         'when volume %s create lun map.') % volume['id'])
                raise exception.VolumeBackendAPIException(data=msg)

            target_wwpns = self._get_connected_wwpns()
            if len(target_wwpns) == 0:
                if self._check_multi_attached(volume, connector) < 1:
                    self._cmd.delete_lun_map(volume_name, self.protocol,
                                             connector['wwpns'])
                msg = (_('_create_fc_lun: Did not find '
                         'available fc wwpns when volume %s '
                         'create lun map.') % volume['id'])
                raise exception.VolumeBackendAPIException(data=msg)

            initiator_target = {}
            for initiator_wwpn in connector['wwpns']:
                initiator_target[str(initiator_wwpn)] = target_wwpns
            properties = {
                'driver_volume_type': 'fibre_channel',
                'data': {
                    'target_wwn': target_wwpns,
                    'target_discovered': False,
                    'target_lun': lun_id,
                    'volume_id': volume['id']
                }
            }
            properties['data']['initiator_target_map'] = initiator_target
        elif ret['key'] == 303:
            raise exception.VolumeNotFound(volume_id=volume_name)
        else:
            msg = (_('failed to map the volume %(vol)s to '
                     'connector %(conn)s.') % {
                         'vol': volume['id'],
                         'conn': connector
                     })
            raise exception.VolumeBackendAPIException(data=msg)

        zone_utils.add_fc_zone(properties)
        LOG.debug(
            'leave: initialize_connection: volume '
            '%(vol)s with connector %(conn)s', {
                'vol': volume.id,
                'conn': connector
            })
        return properties
Exemplo n.º 4
0
 def initialize_connection_with_empty_map(self, volume, connector):
     conn_info = {
         'driver_volume_type': 'fibre_channel',
         'data': {
             'initiator_target_map': {},
         }}
     fczm_utils.add_fc_zone(conn_info)
     return conn_info
Exemplo n.º 5
0
 def initialize_connection(self, volume, connector):
     conn_info = {
         'driver_volume_type': 'fibre_channel',
         'data': {
             'initiator_target_map': {'fake_wwn': ['fake_wwn2']},
         }}
     fczm_utils.add_fc_zone(conn_info)
     return conn_info
Exemplo n.º 6
0
 def no_zone_initialize_connection(self, volume, connector):
     """This shouldn't call the ZM."""
     conn_info = {
         'driver_volume_type': 'bogus',
         'data': {
             'initiator_target_map': {'fake_wwn': ['fake_wwn2']},
         }}
     fczm_utils.add_fc_zone(conn_info)
     return conn_info
Exemplo n.º 7
0
    def initialize_connection(self, volume, connector):
        """Perform work so that an FC connection can be made.

        To be able to create a FC connection from a given host to a
        volume, we must:
        1. Translate the given WWNN to a host name
        2. Create new host on the storage system if it does not yet exist
        3. Map the volume to the host if it is not already done
        4. Return the connection information for relevant nodes (in the
           proper I/O group)

        """

        LOG.debug(
            'enter: initialize_connection: volume %(vol)s with '
            'connector %(conn)s.', {'vol': volume, 'conn': connector})

        vdisk_name = volume['name']
        vdisk_id = volume['id']
        vdisk_params = self._get_vdisk_params(volume['volume_type_id'])

        # TODO(edwin): might fix it after vdisk copy function is
        # ready in FlashSystem thin-provision layer. As this validation
        # is to check the vdisk which is in copying, at present in firmware
        # level vdisk doesn't allow to map host which it is copy. New
        # vdisk clone and snapshot function will cover it. After that the
        # _wait_vdisk_copy_completed need some modification.
        self._wait_vdisk_copy_completed(vdisk_name)

        self._driver_assert(
            self._is_vdisk_defined(vdisk_name),
            (_('initialize_connection: vdisk %s is not defined.')
             % vdisk_name))

        lun_id = self._map_vdisk_to_host(vdisk_name, connector)

        properties = {}
        try:
            properties = self._get_vdisk_map_properties(
                connector, lun_id, vdisk_name, vdisk_id, vdisk_params)
        except exception.VolumeBackendAPIException:
            with excutils.save_and_reraise_exception():
                self.terminate_connection(volume, connector)
                LOG.error('initialize_connection: Failed to collect '
                          'return properties for volume %(vol)s and '
                          'connector %(conn)s.',
                          {'vol': volume, 'conn': connector})

        LOG.debug(
            'leave: initialize_connection:\n volume: %(vol)s\n connector '
            '%(conn)s\n properties: %(prop)s.',
            {'vol': volume,
             'conn': connector,
             'prop': properties})

        fczm_utils.add_fc_zone(properties)
        return properties
Exemplo n.º 8
0
    def initialize_connection(self, volume, connector):
        """Initializes the connection and returns connection info.

        Assign any created volume to a compute node/host so that it can be
        used from that host.

        The  driver returns a driver_volume_type of 'fibre_channel'.
        The target_wwn can be a single entry or a list of wwns that
        correspond to the list of remote wwn(s) that will export the volume.
        The initiator_target_map is a map that represents the remote wwn(s)
        and a list of wwns which are visible to the remote wwn(s).
        Example return values:
        FC:

        .. code-block:: json

            {
                'driver_volume_type': 'fibre_channel'
                'data': {
                    'target_discovered': True,
                    'target_lun': 1,
                    'target_wwn': ['1234567890123', '0987654321321'],
                    'initiator_target_map': {
                        '1122334455667788': ['1234567890123',
                                             '0987654321321']
                    }
                }
            }

        iSCSI:

        .. code-block:: json

            {
                'driver_volume_type': 'iscsi'
                'data': {
                    'target_discovered': True,
                    'target_iqns': ['iqn.2010-10.org.openstack:volume-00001',
                                    'iqn.2010-10.org.openstack:volume-00002'],
                    'target_portals': ['127.0.0.1:3260', '127.0.1.1:3260'],
                    'target_luns': [1, 1],
                }
            }

        """
        LOG.debug(
            "Entering initialize_connection"
            " - connector: %(connector)s.", {'connector': connector})
        conn_info = self.adapter.initialize_connection(volume, connector)
        LOG.debug(
            "Exit initialize_connection"
            " - Returning connection info: %(conn_info)s.",
            {'conn_info': conn_info})
        zm_utils.add_fc_zone(conn_info)
        return conn_info
Exemplo n.º 9
0
    def initialize_connection(self, volume, connector):
        """Initializes the connection and returns connection info.

        Assign any created volume to a compute node/host so that it can be
        used from that host.

        The  driver returns a driver_volume_type of 'fibre_channel'.
        The target_wwn can be a single entry or a list of wwns that
        correspond to the list of remote wwn(s) that will export the volume.
        The initiator_target_map is a map that represents the remote wwn(s)
        and a list of wwns which are visible to the remote wwn(s).
        Example return values:
        FC:

        .. code-block:: json

            {
                'driver_volume_type': 'fibre_channel'
                'data': {
                    'target_discovered': True,
                    'target_lun': 1,
                    'target_wwn': ['1234567890123', '0987654321321'],
                    'initiator_target_map': {
                        '1122334455667788': ['1234567890123',
                                             '0987654321321']
                    }
                }
            }

        iSCSI:

        .. code-block:: json

            {
                'driver_volume_type': 'iscsi'
                'data': {
                    'target_discovered': True,
                    'target_iqns': ['iqn.2010-10.org.openstack:volume-00001',
                                    'iqn.2010-10.org.openstack:volume-00002'],
                    'target_portals': ['127.0.0.1:3260', '127.0.1.1:3260'],
                    'target_luns': [1, 1],
                }
            }

        """
        LOG.debug("Entering initialize_connection"
                  " - connector: %(connector)s.",
                  {'connector': connector})
        conn_info = self.adapter.initialize_connection(volume,
                                                       connector)
        LOG.debug("Exit initialize_connection"
                  " - Returning connection info: %(conn_info)s.",
                  {'conn_info': conn_info})
        zm_utils.add_fc_zone(conn_info)
        return conn_info
Exemplo n.º 10
0
 def initialize_connection(self, volume, connector):
     """Initialize connection between the server and the volume."""
     conn_info = super(HBSDRESTFC, self).initialize_connection(
         volume, connector)
     if self.conf.hitachi_zoning_request:
         init_targ_map = utils.build_initiator_target_map(
             connector, conn_info['data']['target_wwn'],
             self._lookup_service)
         if init_targ_map:
             conn_info['data']['initiator_target_map'] = init_targ_map
         fczm_utils.add_fc_zone(conn_info)
     return conn_info
Exemplo n.º 11
0
    def initialize_connection_snapshot(self, snapshot, connector, **kwargs):
        LOG.info('Initialize FC connection for snapshot %(id)s, '
                 'connector info %(conn)s.',
                 {'id': snapshot.id, 'conn': connector})
        mapping_info = huawei_flow.initialize_fc_connection(
            snapshot, constants.SNAPSHOT_TYPE, connector, self.fc_san,
            self.local_cli, self.configuration)

        mapping_info.pop('aval_host_lun_ids', None)
        conn = {'driver_volume_type': 'fibre_channel',
                'data': mapping_info}
        LOG.info('Initialize FC connection successfully: %s.', conn)
        zm_utils.add_fc_zone(conn)
        return conn
Exemplo n.º 12
0
    def initialize_connection(self, volume, connector):
        LOG.info(
            'Initialize FC connection for volume %(id)s, '
            'connector info %(conn)s.', {
                'id': volume.id,
                'conn': connector
            })

        metadata = huawei_utils.get_volume_private_data(volume)
        if metadata.get('hypermetro'):
            if (not connector.get('multipath')
                    and self.configuration.enforce_multipath_for_hypermetro):
                msg = _("Mapping hypermetro volume must use multipath.")
                LOG.error(msg)
                raise exception.VolumeBackendAPIException(data=msg)
            elif (not connector.get('multipath')
                  and not self.configuration.enforce_multipath_for_hypermetro):
                LOG.warning("Mapping hypermetro volume not use multipath,"
                            " so just mapping the local lun.")
            if not self.hypermetro_rmt_cli:
                msg = _("Mapping hypermetro volume requires remote.")
                LOG.error(msg)
                raise exception.VolumeBackendAPIException(data=msg)

        local_mapping = huawei_flow.initialize_fc_connection(
            volume, constants.LUN_TYPE, connector, self.fc_san, self.local_cli,
            self.configuration)
        if metadata.get('hypermetro') and connector.get('multipath'):
            hypermetro = huawei_utils.get_hypermetro(self.local_cli, volume)
            if not hypermetro:
                msg = _("Mapping hypermetro remote volume error.")
                LOG.error(msg)
                raise exception.VolumeBackendAPIException(data=msg)

            remote_mapping = huawei_flow.initialize_remote_fc_connection(
                hypermetro['ID'], connector, self.fc_san,
                self.hypermetro_rmt_cli, self.configuration)
            same_host_lun_id = self._change_same_host_lun_id(
                local_mapping, remote_mapping)
            mapping_info = self._merge_fc_mapping(local_mapping,
                                                  remote_mapping,
                                                  same_host_lun_id)
        else:
            mapping_info = local_mapping

        mapping_info.pop('aval_host_lun_ids', None)
        conn = {'driver_volume_type': 'fibre_channel', 'data': mapping_info}
        LOG.info('Initialize FC connection successfully: %s.', conn)
        zm_utils.add_fc_zone(conn)
        return conn
Exemplo n.º 13
0
    def initialize_connection(self, volume, connector):
        self.common.client_login()
        try:
            data = {}
            data['target_lun'] = self.common.map_volume(
                volume, connector, 'wwpns')

            ports, init_targ_map = self.get_init_targ_map(connector)
            data['target_discovered'] = True
            data['target_wwn'] = ports
            data['initiator_target_map'] = init_targ_map
            info = {'driver_volume_type': 'fibre_channel', 'data': data}
            fczm_utils.add_fc_zone(info)
            return info
        finally:
            self.common.client_logout()
Exemplo n.º 14
0
    def _initialize_connection_common(self,
                                      volume,
                                      connector,
                                      common,
                                      host,
                                      target_wwns,
                                      init_targ_map,
                                      numPaths,
                                      remote_client=None):
        # check if a VLUN already exists for this host
        existing_vlun = common.find_existing_vlun(volume, host, remote_client)

        vlun = None
        if existing_vlun is None:
            # now that we have a host, create the VLUN
            if self.lookup_service and numPaths == 1:
                nsp = None
                active_fc_port_list = (
                    common.get_active_fc_target_ports(remote_client))
                for port in active_fc_port_list:
                    if port['portWWN'].lower() == target_wwns[0].lower():
                        nsp = port['nsp']
                        break
                vlun = common.create_vlun(volume, host, nsp, None,
                                          remote_client)
            else:
                vlun = common.create_vlun(volume, host, None, None,
                                          remote_client)
        else:
            vlun = existing_vlun

        info_backend = {
            'driver_volume_type': 'fibre_channel',
            'data': {
                'target_lun': vlun['lun'],
                'target_discovered': True,
                'target_wwn': target_wwns,
                'initiator_target_map': init_targ_map
            }
        }

        encryption_key_id = volume.get('encryption_key_id')
        info_backend['data']['encrypted'] = encryption_key_id is not None
        fczm_utils.add_fc_zone(info_backend)

        return info_backend
Exemplo n.º 15
0
    def initialize_connection(self, volume, connector):
        """Initializes the connection and returns connection info.

        Assign any created volume to a compute node/host so that it can be
        used from that host.

        The  driver returns a driver_volume_type of 'fibre_channel'.
        The target_wwn can be a single entry or a list of wwns that
        correspond to the list of remote wwn(s) that will export the volume.
        Example return values:

        .. code-block:: json

            {
                'driver_volume_type': 'fibre_channel'
                'data': {
                    'target_discovered': True,
                    'target_lun': 1,
                    'target_wwn': '1234567890123',
                }
            }

            or

            {
                'driver_volume_type': 'fibre_channel'
                'data': {
                    'target_discovered': True,
                    'target_lun': 1,
                    'target_wwn': ['1234567890123', '0987654321321'],
                }
            }

        :param volume: the cinder volume object
        :param connector: the connector object
        :returns: dict -- the target_wwns and initiator_target_map
        """
        device_info = self.common.initialize_connection(
            volume, connector)
        if device_info:
            conn_info = self.populate_data(device_info, volume, connector)
            fczm_utils.add_fc_zone(conn_info)
            return conn_info
        else:
            return {}
Exemplo n.º 16
0
Arquivo: fc.py Projeto: mahak/cinder
    def initialize_connection(self, volume, connector):
        """Initializes the connection and returns connection info.

        Assign any created volume to a compute node/host so that it can be
        used from that host.

        The  driver returns a driver_volume_type of 'fibre_channel'.
        The target_wwn can be a single entry or a list of wwns that
        correspond to the list of remote wwn(s) that will export the volume.
        Example return values:

        .. code-block:: json

            {
                'driver_volume_type': 'fibre_channel'
                'data': {
                    'target_discovered': True,
                    'target_lun': 1,
                    'target_wwn': '1234567890123',
                }
            }

            or

            {
                'driver_volume_type': 'fibre_channel'
                'data': {
                    'target_discovered': True,
                    'target_lun': 1,
                    'target_wwn': ['1234567890123', '0987654321321'],
                }
            }

        :param volume: the cinder volume object
        :param connector: the connector object
        :returns: dict -- the target_wwns and initiator_target_map
        """
        device_info = self.common.initialize_connection(
            volume, connector)
        if device_info:
            conn_info = self.populate_data(device_info, volume, connector)
            fczm_utils.add_fc_zone(conn_info)
            return conn_info
        else:
            return {}
Exemplo n.º 17
0
    def initialize_connection(self, volume, connector):
        """Allow connection to connector and return connection info."""
        LOG.debug('initialize_connection, volume id: %(vid)s, '
                  'wwpns: %(wwpns)s, enter method.',
                  {'vid': volume['id'], 'wwpns': connector['wwpns']})

        info = self.common.initialize_connection(volume, connector)

        data = info['data']
        init_tgt_map = (
            self.common.build_fc_init_tgt_map(connector, data['target_wwn']))
        data['initiator_target_map'] = init_tgt_map

        info['data'] = data
        LOG.debug('initialize_connection, '
                  'info: %s, exit method.', info)
        fczm_utils.add_fc_zone(info)
        return info
Exemplo n.º 18
0
    def initialize_connection(self, volume, connector):
        self.common.client_login()
        try:
            data = {}
            data['target_lun'] = self.common.map_volume(volume,
                                                        connector,
                                                        'wwpns')

            ports, init_targ_map = self.get_init_targ_map(connector)
            data['target_discovered'] = True
            data['target_wwn'] = ports
            data['initiator_target_map'] = init_targ_map
            info = {'driver_volume_type': 'fibre_channel',
                    'data': data}
            fczm_utils.add_fc_zone(info)
            return info
        finally:
            self.common.client_logout()
Exemplo n.º 19
0
    def initialize_connection(self, volume, connector):
        """Initializes the connection and returns connection info."""

        properties = {}
        properties['volume_id'] = volume.id
        properties['target_discovered'] = False
        properties['target_wwn'] = []

        init_ports = self._build_initport_list(connector)
        itls = self.common.initialize_connection(volume, 'FC', init_ports,
                                                 connector['host'])

        target_wwns = None
        initiator_target_map = None

        if itls:
            properties['target_lun'] = itls[0]['hlu']
            target_wwns, initiator_target_map = (
                self._build_initiator_target_map(itls, connector))

        properties['target_wwn'] = target_wwns
        properties['initiator_target_map'] = initiator_target_map

        auth = None
        try:
            auth = volume.provider_auth
        except AttributeError:
            pass

        if auth:
            (auth_method, auth_username, auth_secret) = auth.split()
            properties['auth_method'] = auth_method
            properties['auth_username'] = auth_username
            properties['auth_password'] = auth_secret

        LOG.debug('FC properties: %s', properties)
        conn_info = {
            'driver_volume_type': 'fibre_channel',
            'data': properties,
        }
        fczm_utils.add_fc_zone(conn_info)
        return conn_info
Exemplo n.º 20
0
 def _initialize_connection_fc(self, volume, connector):
     volume_name = self._make_volume_name(volume)
     infinidat_volume = self._get_infinidat_volume_by_name(volume_name)
     ports = [wwn.WWN(wwpn) for wwpn in connector['wwpns']]
     for port in ports:
         infinidat_host = self._get_or_create_host(port)
         mapping = self._get_or_create_mapping(infinidat_host,
                                               infinidat_volume)
         lun = mapping.get_lun()
     # Create initiator-target mapping.
     target_wwpns = list(self._get_online_fc_ports())
     target_wwpns, init_target_map = self._build_initiator_target_map(
         connector, target_wwpns)
     conn_info = dict(driver_volume_type='fibre_channel',
                      data=dict(target_discovered=False,
                                target_wwn=target_wwpns,
                                target_lun=lun,
                                initiator_target_map=init_target_map))
     fczm_utils.add_fc_zone(conn_info)
     return conn_info
Exemplo n.º 21
0
 def _initialize_connection_fc(self, volume, connector):
     volume_name = self._make_volume_name(volume)
     infinidat_volume = self._get_infinidat_volume_by_name(volume_name)
     ports = [wwn.WWN(wwpn) for wwpn in connector['wwpns']]
     for port in ports:
         infinidat_host = self._get_or_create_host(port)
         mapping = self._get_or_create_mapping(infinidat_host,
                                               infinidat_volume)
         lun = mapping.get_lun()
     # Create initiator-target mapping.
     target_wwpns = list(self._get_online_fc_ports())
     target_wwpns, init_target_map = self._build_initiator_target_map(
         connector, target_wwpns)
     conn_info = dict(driver_volume_type='fibre_channel',
                      data=dict(target_discovered=False,
                                target_wwn=target_wwpns,
                                target_lun=lun,
                                initiator_target_map=init_target_map))
     fczm_utils.add_fc_zone(conn_info)
     return conn_info
Exemplo n.º 22
0
    def initialize_connection(self, volume, connector):
        """Perform work so that an FC connection can be made.

        To be able to create a FC connection from a given host to a
        volume, we must:
        1. Translate the given WWNN to a host name
        2. Create new host on the storage system if it does not yet exist
        3. Map the volume to the host if it is not already done
        4. Return the connection information for relevant nodes (in the
           proper I/O group)

        """

        LOG.debug(
            'enter: initialize_connection: volume %(vol)s with '
            'connector %(conn)s.', {
                'vol': volume,
                'conn': connector
            })

        vdisk_name = volume['name']
        vdisk_id = volume['id']
        vdisk_params = self._get_vdisk_params(volume['volume_type_id'])

        # TODO(edwin): might fix it after vdisk copy function is
        # ready in FlashSystem thin-provision layer. As this validation
        # is to check the vdisk which is in copying, at present in firmware
        # level vdisk doesn't allow to map host which it is copy. New
        # vdisk clone and snapshot function will cover it. After that the
        # _wait_vdisk_copy_completed need some modification.
        self._wait_vdisk_copy_completed(vdisk_name)

        self._driver_assert(
            self._is_vdisk_defined(vdisk_name),
            (_('initialize_connection: vdisk %s is not defined.') %
             vdisk_name))

        lun_id = self._map_vdisk_to_host(vdisk_name, connector)

        properties = {}
        try:
            properties = self._get_vdisk_map_properties(
                connector, lun_id, vdisk_name, vdisk_id, vdisk_params)
        except exception.VolumeBackendAPIException:
            with excutils.save_and_reraise_exception():
                self.terminate_connection(volume, connector)
                LOG.error(
                    'initialize_connection: Failed to collect '
                    'return properties for volume %(vol)s and '
                    'connector %(conn)s.', {
                        'vol': volume,
                        'conn': connector
                    })

        LOG.debug(
            'leave: initialize_connection:\n volume: %(vol)s\n connector '
            '%(conn)s\n properties: %(prop)s.', {
                'vol': volume,
                'conn': connector,
                'prop': properties
            })

        fczm_utils.add_fc_zone(properties)
        return properties
Exemplo n.º 23
0
    def initialize_connection(self, volume, connector):
        """Assigns the volume to a server.

        Assign any created volume to a compute node/host so that it can be
        used from that host.

        The  driver returns a driver_volume_type of 'fibre_channel'.
        The target_wwn can be a single entry or a list of wwns that
        correspond to the list of remote wwn(s) that will export the volume.
        Example return values:

            {
                'driver_volume_type': 'fibre_channel'
                'data': {
                    'encrypted': False,
                    'target_discovered': True,
                    'target_lun': 1,
                    'target_wwn': '1234567890123',
                }
            }

            or

             {
                'driver_volume_type': 'fibre_channel'
                'data': {
                    'encrypted': False,
                    'target_discovered': True,
                    'target_lun': 1,
                    'target_wwn': ['1234567890123', '0987654321321'],
                }
            }


        Steps to export a volume on 3PAR
          * Create a host on the 3par with the target wwn
          * Create a VLUN for that HOST with the volume we want to export.

        """
        common = self._login()
        try:
            # we have to make sure we have a host
            host = self._create_host(common, volume, connector)
            target_wwns, init_targ_map, numPaths = \
                self._build_initiator_target_map(common, connector)
            if not connector.get('multipath'):
                target_wwns = target_wwns[:1]
                initiator = connector.get('wwpns')[0]
                init_targ_map[initiator] = init_targ_map[initiator][:1]
            # check if a VLUN already exists for this host
            existing_vlun = common.find_existing_vlun(volume, host)

            vlun = None
            if existing_vlun is None:
                # now that we have a host, create the VLUN
                if self.lookup_service is not None and numPaths == 1:
                    nsp = None
                    active_fc_port_list = common.get_active_fc_target_ports()
                    for port in active_fc_port_list:
                        if port['portWWN'].lower() == target_wwns[0].lower():
                            nsp = port['nsp']
                            break
                    vlun = common.create_vlun(volume, host, nsp)
                else:
                    vlun = common.create_vlun(volume, host)
            else:
                vlun = existing_vlun

            info = {
                'driver_volume_type': 'fibre_channel',
                'data': {
                    'target_lun': vlun['lun'],
                    'target_discovered': True,
                    'target_wwn': target_wwns,
                    'initiator_target_map': init_targ_map
                }
            }

            encryption_key_id = volume.get('encryption_key_id', None)
            info['data']['encrypted'] = encryption_key_id is not None
            fczm_utils.add_fc_zone(info)
            return info
        finally:
            self._logout(common)
Exemplo n.º 24
0
    def initialize_connection(self, volume, connector):
        """Allow connection to connector and return connection info."""
        """
            connector = {'ip': CONF.my_ip,
                         'host': CONF.host,
                         'initiator': self._initiator,
                         'wwnns': self._fc_wwnns,
                         'wwpns': self._fc_wwpns}

        """
        dc_fc = {}
        dc_target = {}
        lsTargetWwpn = []
        output = None
        properties = {}
        preferTargets = {}
        ret = 0
        targetIdentifier = []
        szwwpns = []
        LOG.info(
            'initialize_connection volume: %(volume)s, connector:'
            ' %(connector)s', {
                "volume": volume,
                "connector": connector
            })
        # Get Storage Fiber channel controller
        dc_fc = self._get_fc_channel()

        # Get existed FC target list to decide target wwpn
        dc_target = self._get_targets()
        if len(dc_target) == 0:
            msg = _('Backend storage did not configure fiber channel '
                    'target.')
            raise exception.VolumeBackendAPIException(data=msg)

        for keyFc in dc_fc:
            for targetuuid in dc_target:
                if dc_fc[keyFc]['hardware_address'] == \
                        dc_target[targetuuid]['targetAddr']:
                    preferTargets[targetuuid] = dc_target[targetuuid]
                    break
        # Confirm client wwpn is existed in sns table
        # Covert wwwpns to 'xx:xx:xx:xx:xx:xx:xx:xx' format
        for dwwpn in connector['wwpns']:
            szwwpn = self._convertHex2String(dwwpn)
            if len(szwwpn) == 0:
                msg = _('Invalid wwpns format %(wwpns)s') % \
                    {'wwpns': connector['wwpns']}
                raise exception.VolumeBackendAPIException(data=msg)
            szwwpns.append(szwwpn)

        if len(szwwpns):
            for targetUuid in preferTargets:
                targetWwpn = ''
                targetWwpn = preferTargets.get(targetUuid,
                                               {}).get('targetAddr', '')
                lsTargetWwpn.append(targetWwpn)
        # Use wwpns to assign volume.
        LOG.info('Prefer use target wwpn %(wwpn)s', {'wwpn': lsTargetWwpn})
        # Start to create export in all FC target node.
        assignedTarget = []
        for pTarget in lsTargetWwpn:
            try:
                ret = self._export_fc(volume['id'], str(pTarget), szwwpns,
                                      volume['name'])
                if ret:
                    break
                else:
                    assignedTarget.append(pTarget)
            except Exception as e:
                LOG.error('Failed to export fiber channel target '
                          'due to %s', e)
                ret = errno.EFAULT
                break
        if ret == 0:
            ret, output = self.dpl.get_vdev(self._conver_uuid2hex(
                volume['id']))
        nLun = -1
        if ret == 0:
            try:
                for p in output['exports']['Network/FC']:
                    # check initiator wwpn existed in target initiator list
                    for initI in p.get('permissions', []):
                        for szwpn in szwwpns:
                            if initI.get(szwpn, None):
                                nLun = initI[szwpn]
                                break
                        if nLun != -1:
                            break

                    if nLun != -1:
                        targetIdentifier.append(
                            str(p['target_identifier']).replace(':', ''))

            except Exception:
                msg = _('Invalid connection initialization response of '
                        'volume %(name)s: '
                        '%(output)s') % {
                            'name': volume['name'],
                            'output': output
                        }
                raise exception.VolumeBackendAPIException(data=msg)

        if nLun != -1:
            init_targ_map = self._build_initiator_target_map(
                connector, targetIdentifier)
            properties['target_discovered'] = True
            properties['target_wwn'] = targetIdentifier
            properties['target_lun'] = int(nLun)
            properties['volume_id'] = volume['id']
            properties['initiator_target_map'] = init_targ_map
            LOG.info(
                '%(volume)s assign type fibre_channel, properties '
                '%(properties)s', {
                    'volume': volume['id'],
                    'properties': properties
                })
        else:
            msg = _('Invalid connection initialization response of '
                    'volume %(name)s') % {
                        'name': volume['name']
                    }
            raise exception.VolumeBackendAPIException(data=msg)
        LOG.info(
            'Connect initialization info: '
            '{driver_volume_type: fibre_channel, '
            'data: %(properties)s', {'properties': properties})
        conn_info = {'driver_volume_type': 'fibre_channel', 'data': properties}
        fczm_utils.add_fc_zone(conn_info)
        return conn_info
Exemplo n.º 25
0
    def initialize_connection(self, volume, connector):
        """Perform necessary work to make a FC connection.

        To be able to create an FC connection from a given host to a
        volume, we must:
        1. Translate the given WWNN to a host name
        2. Create new host on the storage system if it does not yet exist
        3. Map the volume to the host if it is not already done
        4. Return the connection information for relevant nodes (in the
           proper I/O group)

        """
        volume_name = self._get_target_vol(volume)

        # Check if a host object is defined for this host name
        host_name = self._assistant.get_host_from_connector(connector)
        if host_name is None:
            # Host does not exist - add a new host to InStorage/MCS
            host_name = self._assistant.create_host(connector)

        volume_attributes = self._assistant.get_vdisk_attributes(volume_name)
        if volume_attributes is None:
            msg = (_('initialize_connection: Failed to get attributes'
                     ' for volume %s.') % volume_name)
            LOG.error(msg)
            raise exception.VolumeDriverException(message=msg)

        lun_id = self._assistant.map_vol_to_host(volume_name,
                                                 host_name,
                                                 True)

        try:
            preferred_node = volume_attributes['preferred_node_id']
            IO_group = volume_attributes['IO_group_id']
        except KeyError as e:
            LOG.error('Did not find expected column name in '
                      'lsvdisk: %s.', e)
            raise exception.VolumeBackendAPIException(
                data=_('initialize_connection: Missing volume attribute for '
                       'volume %s.') % volume_name)

        try:
            # Get preferred node and other nodes in I/O group
            preferred_node_entry = None
            io_group_nodes = []
            for node in self._state['storage_nodes'].values():
                if node['id'] == preferred_node:
                    preferred_node_entry = node
                if node['IO_group'] == IO_group:
                    io_group_nodes.append(node)

            if not len(io_group_nodes):
                msg = (_('initialize_connection: No node found in '
                         'I/O group %(gid)s for volume %(vol)s.') %
                       {'gid': IO_group, 'vol': volume_name})
                LOG.error(msg)
                raise exception.VolumeBackendAPIException(data=msg)

            if not preferred_node_entry:
                # Get 1st node in I/O group
                preferred_node_entry = io_group_nodes[0]
                LOG.warning('initialize_connection: Did not find a '
                            'preferred node for volume %s.', volume_name)

            properties = {}
            properties['target_discovered'] = False
            properties['target_lun'] = lun_id
            properties['volume_id'] = volume.id

            conn_wwpns = self._assistant.get_conn_fc_wwpns(host_name)

            # If conn_wwpns is empty, then that means that there were
            # no target ports with visibility to any of the initiators
            # so we return all target ports.
            if len(conn_wwpns) == 0:
                for node in self._state['storage_nodes'].values():
                    conn_wwpns.extend(node['WWPN'])

            properties['target_wwn'] = conn_wwpns

            i_t_map = self.make_initiator_target_all2all_map(
                connector['wwpns'], conn_wwpns)
            properties['initiator_target_map'] = i_t_map

        except Exception:
            with excutils.save_and_reraise_exception():
                self._do_terminate_connection(volume, connector)
                LOG.error('initialize_connection: Failed '
                          'to collect return '
                          'properties for volume %(vol)s and connector '
                          '%(conn)s.\n', {'vol': volume,
                                          'conn': connector})

        info = {'driver_volume_type': 'fibre_channel', 'data': properties, }
        fczm_utils.add_fc_zone(info)
        return info
Exemplo n.º 26
0
    def initialize_connection(self, volume, connector):
        """Perform necessary work to make a FC connection.

        To be able to create an FC connection from a given host to a
        volume, we must:
        1. Translate the given WWNN to a host name
        2. Create new host on the storage system if it does not yet exist
        3. Map the volume to the host if it is not already done
        4. Return the connection information for relevant nodes (in the
           proper I/O group)

        """
        volume_name = self._get_target_vol(volume)

        # Check if a host object is defined for this host name
        host_name = self._assistant.get_host_from_connector(connector)
        if host_name is None:
            # Host does not exist - add a new host to InStorage/MCS
            host_name = self._assistant.create_host(connector)

        volume_attributes = self._assistant.get_vdisk_attributes(volume_name)
        if volume_attributes is None:
            msg = (_('initialize_connection: Failed to get attributes'
                     ' for volume %s.') % volume_name)
            LOG.error(msg)
            raise exception.VolumeDriverException(message=msg)

        lun_id = self._assistant.map_vol_to_host(volume_name,
                                                 host_name,
                                                 True)

        try:
            preferred_node = volume_attributes['preferred_node_id']
            IO_group = volume_attributes['IO_group_id']
        except KeyError as e:
            LOG.error('Did not find expected column name in '
                      'lsvdisk: %s.', e)
            raise exception.VolumeBackendAPIException(
                data=_('initialize_connection: Missing volume attribute for '
                       'volume %s.') % volume_name)

        try:
            # Get preferred node and other nodes in I/O group
            preferred_node_entry = None
            io_group_nodes = []
            for node in self._state['storage_nodes'].values():
                if node['id'] == preferred_node:
                    preferred_node_entry = node
                if node['IO_group'] == IO_group:
                    io_group_nodes.append(node)

            if not len(io_group_nodes):
                msg = (_('initialize_connection: No node found in '
                         'I/O group %(gid)s for volume %(vol)s.') %
                       {'gid': IO_group, 'vol': volume_name})
                LOG.error(msg)
                raise exception.VolumeBackendAPIException(data=msg)

            if not preferred_node_entry:
                # Get 1st node in I/O group
                preferred_node_entry = io_group_nodes[0]
                LOG.warning('initialize_connection: Did not find a '
                            'preferred node for volume %s.', volume_name)

            properties = {}
            properties['target_discovered'] = False
            properties['target_lun'] = lun_id
            properties['volume_id'] = volume.id

            conn_wwpns = self._assistant.get_conn_fc_wwpns(host_name)

            # If conn_wwpns is empty, then that means that there were
            # no target ports with visibility to any of the initiators
            # so we return all target ports.
            if len(conn_wwpns) == 0:
                for node in self._state['storage_nodes'].values():
                    conn_wwpns.extend(node['WWPN'])

            properties['target_wwn'] = conn_wwpns

            i_t_map = utils.make_initiator_target_all2all_map(
                connector['wwpns'], conn_wwpns)
            properties['initiator_target_map'] = i_t_map

        except Exception:
            with excutils.save_and_reraise_exception():
                self._do_terminate_connection(volume, connector)
                LOG.error('initialize_connection: Failed '
                          'to collect return '
                          'properties for volume %(vol)s and connector '
                          '%(conn)s.\n', {'vol': volume,
                                          'conn': connector})

        info = {'driver_volume_type': 'fibre_channel', 'data': properties, }
        fczm_utils.add_fc_zone(info)
        return info
Exemplo n.º 27
0
    def initialize_connection(self, volume, connector):
        """Map the created volume."""

        conn_info = self.proxy.initialize_connection(volume, connector)
        fczm_utils.add_fc_zone(conn_info)
        return conn_info
Exemplo n.º 28
0
 def _retype_hyperswap_volume(self, ctxt, volume, host, old_opts, new_opts,
                              old_pool, new_pool, vdisk_changes, need_copy,
                              new_type):
     if (old_opts['volume_topology'] != 'hyperswap'
             and new_opts['volume_topology'] == 'hyperswap'):
         LOG.debug(
             'retype: Convert a normal volume %s to hyperswap '
             'volume.', volume.name)
         conn_info = {}
         if volume.previous_status == 'in-use':
             vdisk_info = self._helpers.ssh.lsvdiskhostmap(volume.name)
             peer_pool = new_opts['peer_pool']
             iogrp_list = self._helpers.get_hyperswap_pool_io_grp(
                 self._state, new_pool, peer_pool)
             for mapping_info in vdisk_info:
                 host = mapping_info['host_name']
                 try:
                     host_info = self._helpers.ssh.lshost(host)
                     conn_info[host] = self._get_volume_connection_info(
                         ctxt, volume, host_info, iogrp_list)
                     host_site = self._get_volume_host_site_from_conf(
                         volume, conn_info[host].get('connector'))
                     self._update_host_site_for_hyperswap_volume(
                         host, host_site)
                     self._helpers.ssh.addhostiogrp(host, iogrp_list)
                 except Exception as ex:
                     msg = _('Error updating host %(host)s due to %(ex)s', {
                         'host': host,
                         'ex': ex
                     })
                     raise exception.VolumeBackendAPIException(data=msg)
         self._helpers.convert_volume_to_hyperswap(volume.name, new_opts,
                                                   self._state)
         if volume.previous_status == 'in-use':
             for host, info in conn_info.items():
                 try:
                     fczm_utils.add_fc_zone(info)
                 except Exception as ex:
                     self._helpers.convert_hyperswap_volume_to_normal(
                         volume.name, new_opts['peer_pool'])
                     msg = _(
                         'Zoning failed for volume %(vol)s and host '
                         '%(host)s due to %(ex)s.', {
                             'vol': volume.name,
                             'host': host,
                             'ex': ex
                         })
                     raise exception.VolumeBackendAPIException(data=msg)
     elif (old_opts['volume_topology'] == 'hyperswap'
           and new_opts['volume_topology'] != 'hyperswap'):
         LOG.debug(
             'retype: Convert a hyperswap volume %s to normal '
             'volume.', volume.name)
         if new_pool == old_pool:
             self._helpers.convert_hyperswap_volume_to_normal(
                 volume.name, old_opts['peer_pool'])
         elif new_pool == old_opts['peer_pool']:
             self._helpers.convert_hyperswap_volume_to_normal(
                 volume.name, old_pool)
         if volume.previous_status == 'in-use':
             vdisk_info = self._helpers.ssh.lsvdiskhostmap(volume.name)
             for mapping_info in vdisk_info:
                 res = self._helpers.check_host_mapped_vols(
                     mapping_info['host_name'])
                 if len(res) == 1:
                     self._helpers.update_host(mapping_info['host_name'],
                                               None)
     else:
         rel_info = self._helpers.get_relationship_info(volume.name)
         aux_vdisk = rel_info['aux_vdisk_name']
         if need_copy:
             self.add_vdisk_copy(aux_vdisk,
                                 old_opts['peer_pool'],
                                 new_type,
                                 auto_delete=True)
         elif vdisk_changes:
             self._helpers.change_vdisk_options(aux_vdisk, vdisk_changes,
                                                new_opts, self._state)
     if need_copy:
         self.add_vdisk_copy(volume.name,
                             old_pool,
                             new_type,
                             auto_delete=True)
     elif vdisk_changes:
         self._helpers.change_vdisk_options(volume.name, vdisk_changes,
                                            new_opts, self._state)
Exemplo n.º 29
0
 def initialize_connection(self, volume, connector):
     conn_info = self.fc_initialize_connection(volume, connector)
     fczm_utils.add_fc_zone(conn_info)
     return conn_info
Exemplo n.º 30
0
    def initialize_connection(self, volume, connector):
        """Allow connection to connector and return connection info."""
        """
            connector = {'ip': CONF.my_ip,
                         'host': CONF.host,
                         'initiator': self._initiator,
                         'wwnns': self._fc_wwnns,
                         'wwpns': self._fc_wwpns}

        """
        dc_fc = {}
        dc_target = {}
        lsTargetWwpn = []
        output = None
        properties = {}
        preferTargets = {}
        ret = 0
        targetIdentifier = []
        szwwpns = []
        LOG.info('initialize_connection volume: %(volume)s, connector:'
                 ' %(connector)s',
                 {"volume": volume, "connector": connector})
        # Get Storage Fiber channel controller
        dc_fc = self._get_fc_channel()

        # Get existed FC target list to decide target wwpn
        dc_target = self._get_targets()
        if len(dc_target) == 0:
            msg = _('Backend storage did not configure fiber channel '
                    'target.')
            raise exception.VolumeBackendAPIException(data=msg)

        for keyFc in dc_fc:
            for targetuuid in dc_target:
                if dc_fc[keyFc]['hardware_address'] == \
                        dc_target[targetuuid]['targetAddr']:
                    preferTargets[targetuuid] = dc_target[targetuuid]
                    break
        # Confirm client wwpn is existed in sns table
        # Covert wwwpns to 'xx:xx:xx:xx:xx:xx:xx:xx' format
        for dwwpn in connector['wwpns']:
            szwwpn = self._convertHex2String(dwwpn)
            if len(szwwpn) == 0:
                msg = _('Invalid wwpns format %(wwpns)s') % \
                    {'wwpns': connector['wwpns']}
                raise exception.VolumeBackendAPIException(data=msg)
            szwwpns.append(szwwpn)

        if len(szwwpns):
            for targetUuid in preferTargets:
                targetWwpn = ''
                targetWwpn = preferTargets.get(targetUuid,
                                               {}).get('targetAddr', '')
                lsTargetWwpn.append(targetWwpn)
        # Use wwpns to assign volume.
        LOG.info('Prefer use target wwpn %(wwpn)s',
                 {'wwpn': lsTargetWwpn})
        # Start to create export in all FC target node.
        assignedTarget = []
        for pTarget in lsTargetWwpn:
            try:
                ret = self._export_fc(volume['id'], str(pTarget), szwwpns,
                                      volume['name'])
                if ret:
                    break
                else:
                    assignedTarget.append(pTarget)
            except Exception as e:
                LOG.error('Failed to export fiber channel target '
                          'due to %s', e)
                ret = errno.EFAULT
                break
        if ret == 0:
            ret, output = self.dpl.get_vdev(self._conver_uuid2hex(
                volume['id']))
        nLun = -1
        if ret == 0:
            try:
                for p in output['exports']['Network/FC']:
                    # check initiator wwpn existed in target initiator list
                    for initI in p.get('permissions', []):
                        for szwpn in szwwpns:
                            if initI.get(szwpn, None):
                                nLun = initI[szwpn]
                                break
                        if nLun != -1:
                            break

                    if nLun != -1:
                        targetIdentifier.append(
                            str(p['target_identifier']).replace(':', ''))

            except Exception:
                msg = _('Invalid connection initialization response of '
                        'volume %(name)s: '
                        '%(output)s') % {'name': volume['name'],
                                         'output': output}
                raise exception.VolumeBackendAPIException(data=msg)

        if nLun != -1:
            init_targ_map = self._build_initiator_target_map(connector,
                                                             targetIdentifier)
            properties['target_discovered'] = True
            properties['target_wwn'] = targetIdentifier
            properties['target_lun'] = int(nLun)
            properties['volume_id'] = volume['id']
            properties['initiator_target_map'] = init_targ_map
            LOG.info('%(volume)s assign type fibre_channel, properties '
                     '%(properties)s',
                     {'volume': volume['id'], 'properties': properties})
        else:
            msg = _('Invalid connection initialization response of '
                    'volume %(name)s') % {'name': volume['name']}
            raise exception.VolumeBackendAPIException(data=msg)
        LOG.info('Connect initialization info: '
                 '{driver_volume_type: fibre_channel, '
                 'data: %(properties)s', {'properties': properties})
        conn_info = {'driver_volume_type': 'fibre_channel',
                     'data': properties}
        fczm_utils.add_fc_zone(conn_info)
        return conn_info
Exemplo n.º 31
0
    def initialize_connection(self, volume, connector):
        lun_id, lun_type = self.get_lun_id_and_type(volume)
        wwns = connector['wwpns']
        LOG.info(
            'initialize_connection, initiator: %(wwpns)s,'
            ' LUN ID: %(lun_id)s.',
            {'wwpns': wwns,
             'lun_id': lun_id},)

        portg_id = None
        host_id = self.client.add_host_with_check(connector['host'])

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

        if self.fcsan:
            # Use FC switch.
            zone_helper = fc_zone_helper.FCZoneHelper(self.fcsan, self.client)
            try:
                (tgt_port_wwns, portg_id, init_targ_map) = (
                    zone_helper.build_ini_targ_map(wwns, host_id, lun_id,
                                                   lun_type))
            except Exception as err:
                self.remove_host_with_check(host_id)
                msg = _('build_ini_targ_map fails. %s') % err
                raise exception.VolumeBackendAPIException(data=msg)

            for ini in init_targ_map:
                self.client.ensure_fc_initiator_added(ini, host_id)
        else:
            # Not use FC switch.
            online_wwns_in_host = (
                self.client.get_host_online_fc_initiators(host_id))
            online_free_wwns = self.client.get_online_free_wwns()
            fc_initiators_on_array = self.client.get_fc_initiator_on_array()
            wwns = [i for i in wwns if i in fc_initiators_on_array]

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

                    msg = _('No FC initiator can be added to host.')
                    LOG.error(msg)
                    raise exception.VolumeBackendAPIException(data=msg)

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

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

        # Add host into hostgroup.
        hostgroup_id = self.client.add_host_to_hostgroup(host_id)

        metadata = huawei_utils.get_volume_private_data(volume)
        LOG.info("initialize_connection, metadata is: %s.", metadata)
        hypermetro_lun = metadata.get('hypermetro_id') is not None

        map_info = self.client.do_mapping(lun_id, hostgroup_id,
                                          host_id, portg_id,
                                          lun_type, hypermetro_lun)
        host_lun_id = self.client.get_host_lun_id(host_id, lun_id,
                                                  lun_type)

        # 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}, }

        # Deal with hypermetro connection.
        if hypermetro_lun:
            loc_tgt_wwn = fc_info['data']['target_wwn']
            local_ini_tgt_map = fc_info['data']['initiator_target_map']
            hyperm = hypermetro.HuaweiHyperMetro(self.client,
                                                 self.rmt_client,
                                                 self.configuration)
            rmt_fc_info = hyperm.connect_volume_fc(volume, connector)

            rmt_tgt_wwn = rmt_fc_info['data']['target_wwn']
            rmt_ini_tgt_map = rmt_fc_info['data']['initiator_target_map']
            fc_info['data']['target_wwn'] = (loc_tgt_wwn + rmt_tgt_wwn)
            wwns = connector['wwpns']
            for wwn in wwns:
                if (wwn in local_ini_tgt_map
                        and wwn in rmt_ini_tgt_map):
                    fc_info['data']['initiator_target_map'][wwn].extend(
                        rmt_ini_tgt_map[wwn])

                elif (wwn not in local_ini_tgt_map
                        and wwn in rmt_ini_tgt_map):
                    fc_info['data']['initiator_target_map'][wwn] = (
                        rmt_ini_tgt_map[wwn])
                # else, do nothing

            loc_map_info = fc_info['data']['map_info']
            rmt_map_info = rmt_fc_info['data']['map_info']
            same_host_id = self._get_same_hostid(loc_map_info,
                                                 rmt_map_info)

            self.client.change_hostlun_id(loc_map_info, same_host_id)
            hyperm.rmt_client.change_hostlun_id(rmt_map_info, same_host_id)

            fc_info['data']['target_lun'] = same_host_id
            hyperm.rmt_client.logout()

        fczm_utils.add_fc_zone(fc_info)
        LOG.info("Return FC info is: %s.", fc_info)
        return fc_info
Exemplo n.º 32
0
 def _do_initialize_connection_locked(system_id, host):
     conn_info = self._do_initialize_connection(volume, connector)
     fczm_utils.add_fc_zone(conn_info)
     return conn_info
Exemplo n.º 33
0
    def initialize_connection(self, volume, connector):
        """Initializes the connection and returns connection info.

        Assign any created volume to a compute node/host so that it can be
        used from that host.

        The  driver returns a driver_volume_type of 'fibre_channel'.
        The target_wwn can be a single entry or a list of wwns that
        correspond to the list of remote wwn(s) that will export the volume.
        """

        # We use id to name the volume name as it is a
        # known unique name.
        volume_name = volume.get('id')
        provider_id = volume.get('provider_id')
        islivevol = self._is_live_vol(volume)
        LOG.debug('Initialize connection: %s', volume_name)
        with self._client.open_connection() as api:
            try:
                wwpns = connector.get('wwpns')
                # Find the volume on the storage center. Note that if this
                # is live volume and we are swapped this will be the back
                # half of the live volume.
                scvolume = api.find_volume(volume_name, provider_id, islivevol)
                if scvolume:
                    # Get the SSN it is on.
                    ssn = scvolume['instanceId'].split('.')[0]
                    # Find our server.
                    scserver = self._find_server(api, wwpns, ssn)

                    # No? Create it.
                    if scserver is None:
                        scserver = api.create_server(
                            wwpns, self.configuration.dell_server_os, ssn)
                    # We have a volume and a server. Map them.
                    if scserver is not None:
                        mapping = api.map_volume(scvolume, scserver)
                        if mapping is not None:
                            # Since we just mapped our volume we had
                            # best update our sc volume object.
                            scvolume = api.get_volume(scvolume['instanceId'])
                            lun, targets, init_targ_map = api.find_wwns(
                                scvolume, scserver)

                            # Do we have extra live volume work?
                            if islivevol:
                                # Get our live volume.
                                sclivevolume = api.get_live_volume(provider_id)
                                # Do not map to a failed over volume.
                                if (sclivevolume and not
                                    api.is_failed_over(provider_id,
                                                       sclivevolume)):
                                    # Now map our secondary.
                                    lvlun, lvtargets, lvinit_targ_map = (
                                        self.initialize_secondary(api,
                                                                  sclivevolume,
                                                                  wwpns))
                                    # Unmapped. Add info to our list.
                                    targets += lvtargets
                                    init_targ_map.update(lvinit_targ_map)

                            # Roll up our return data.
                            if lun is not None and len(targets) > 0:
                                data = {'driver_volume_type': 'fibre_channel',
                                        'data': {'target_lun': lun,
                                                 'target_discovered': True,
                                                 'target_wwn': targets,
                                                 'initiator_target_map':
                                                 init_targ_map,
                                                 'discard': True}}
                                LOG.debug('Return FC data: %s', data)
                                fczm_utils.add_fc_zone(data)
                                return data
                            LOG.error('Lun mapping returned null!')

            except Exception:
                with excutils.save_and_reraise_exception():
                    LOG.error('Failed to initialize connection.')

        # We get here because our mapping is none so blow up.
        raise exception.VolumeBackendAPIException(
            data=_('Unable to map volume.'))
Exemplo n.º 34
0
    def initialize_connection(self, volume, connector):
        """Map the created volume."""

        conn_info = self.proxy.initialize_connection(volume, connector)
        fczm_utils.add_fc_zone(conn_info)
        return conn_info