Example #1
0
    def _discover_volume_on_vios(self, vios_w, volume_id):
        """Discovers an hdisk on a single vios for the volume.

        :param vios_w: VIOS wrapper to process
        :param volume_id: Volume to discover
        :returns: Status of the volume or None
        :returns: Device name or None
        :returns: LUN or None
        """
        # Get the initiatior WWPNs, targets and Lun for the given VIOS.
        vio_wwpns, t_wwpns, lun = self._get_hdisk_itls(vios_w)

        # Build the ITL map and discover the hdisks on the Virtual I/O
        # Server (if any).
        itls = hdisk.build_itls(vio_wwpns, t_wwpns, lun)
        if len(itls) == 0:
            LOG.debug('No ITLs for VIOS %(vios)s for volume %(volume_id)s.'
                      % {'vios': vios_w.name, 'volume_id': volume_id})
            return None, None, None

        status, device_name, udid = hdisk.discover_hdisk(self.adapter,
                                                         vios_w.uuid, itls)

        if hdisk.good_discovery(status, device_name):
            LOG.info(_LI('Discovered %(hdisk)s on vios %(vios)s for '
                     'volume %(volume_id)s. Status code: %(status)s.'),
                     {'hdisk': device_name, 'vios': vios_w.name,
                      'volume_id': volume_id, 'status': str(status)})
        elif status == hdisk.LUAStatus.DEVICE_IN_USE:
            LOG.warning(_LW('Discovered device %(dev)s for volume %(volume)s '
                            'on %(vios)s is in use. Error code: %(status)s.'),
                        {'dev': device_name, 'volume': volume_id,
                         'vios': vios_w.name, 'status': str(status)})

        return status, device_name, udid
Example #2
0
    def test_lua_recovery_xml(self):
        """Validates that the LUA recovery XML is build properly."""
        i_wwpns = ['0011223344556677', '0011223344556678']
        t_wwpns = ['1111223344556677', '1111223344556678', '1111223344556679']
        all_itls = hdisk.build_itls(i_wwpns, t_wwpns, 238)

        lua_xml = ('<XML_LIST><general><cmd_version>3</cmd_version><version>'
                   '2.0</version></general><reliableITL>false</reliableITL>'
                   '<deviceList><device><vendor>OTHER</vendor><deviceTag>'
                   '1</deviceTag><itlList><number>6</number><itl>'
                   '<Iwwpn>0011223344556677</Iwwpn><Twwpn>1111223344556677'
                   '</Twwpn><lua>ee000000000000</lua></itl><itl><Iwwpn>'
                   '0011223344556677</Iwwpn><Twwpn>1111223344556678</Twwpn>'
                   '<lua>ee000000000000</lua></itl><itl><Iwwpn>'
                   '0011223344556677</Iwwpn><Twwpn>1111223344556679</Twwpn>'
                   '<lua>ee000000000000</lua></itl><itl><Iwwpn>'
                   '0011223344556678</Iwwpn><Twwpn>1111223344556677</Twwpn>'
                   '<lua>ee000000000000</lua></itl><itl><Iwwpn>'
                   '0011223344556678</Iwwpn><Twwpn>1111223344556678</Twwpn>'
                   '<lua>ee000000000000</lua></itl><itl><Iwwpn>'
                   '0011223344556678</Iwwpn><Twwpn>1111223344556679</Twwpn>'
                   '<lua>ee000000000000</lua></itl></itlList></device>'
                   '</deviceList></XML_LIST>')

        self.assertEqual(lua_xml, hdisk._lua_recovery_xml(all_itls, None))
Example #3
0
    def _discover_volume_on_vios(self, vios_w, volume_id):
        """Discovers an hdisk on a single vios for the volume.

        :param vios_w: VIOS wrapper to process
        :param volume_id: Volume to discover
        :returns: Status of the volume or None
        :returns: Device name or None
        :returns: UDID or None
        """
        # Get the initiatior WWPNs, targets and Lun for the given VIOS.
        vio_wwpns, t_wwpns, lun = self._get_hdisk_itls(vios_w)

        # Build the ITL map and discover the hdisks on the Virtual I/O
        # Server (if any).
        itls = hdisk.build_itls(vio_wwpns, t_wwpns, lun)
        if len(itls) == 0:
            LOG.debug('No ITLs for VIOS %(vios)s for volume %(volume_id)s.', {
                'vios': vios_w.name,
                'volume_id': volume_id
            },
                      instance=self.instance)
            return None, None, None

        device_id = self.connection_info.get('data', {}).get('pg83NAA')
        if device_id:
            device_id = base64.b64encode(device_id.encode())

        status, device_name, udid = hdisk.discover_hdisk(self.adapter,
                                                         vios_w.uuid,
                                                         itls,
                                                         device_id=device_id)

        if hdisk.good_discovery(status, device_name):
            LOG.info(
                'Discovered %(hdisk)s on vios %(vios)s for volume '
                '%(volume_id)s. Status code: %(status)s.', {
                    'hdisk': device_name,
                    'vios': vios_w.name,
                    'volume_id': volume_id,
                    'status': status
                },
                instance=self.instance)
        elif status == hdisk.LUAStatus.DEVICE_IN_USE:
            LOG.warning(
                'Discovered device %(dev)s for volume %(volume)s '
                'on %(vios)s is in use. Error code: %(status)s.', {
                    'dev': device_name,
                    'volume': volume_id,
                    'vios': vios_w.name,
                    'status': status
                },
                instance=self.instance)

        return status, device_name, udid
Example #4
0
    def test_build_itls(self):
        """Tests that the ITL combinations can be built out."""
        i_wwpns = ['0011223344556677', '0011223344556678']
        t_wwpns = ['1111223344556677', '1111223344556678', '1111223344556679']
        all_itls = hdisk.build_itls(i_wwpns, t_wwpns, 238)

        self.assertEqual(6, len(all_itls))

        combos = [
            hdisk.ITL(i_wwpns[0], t_wwpns[0], 238),
            hdisk.ITL(i_wwpns[0], t_wwpns[1], 238),
            hdisk.ITL(i_wwpns[0], t_wwpns[2], 238),
            hdisk.ITL(i_wwpns[1], t_wwpns[0], 238),
            hdisk.ITL(i_wwpns[1], t_wwpns[1], 238),
            hdisk.ITL(i_wwpns[1], t_wwpns[2], 238)
        ]
        self.assertListEqual(combos, all_itls)
Example #5
0
    def _discover_volume_on_vios(self, vios_w, volume_id):
        """Discovers an hdisk on a single vios for the volume.

        :param vios_w: VIOS wrapper to process
        :param volume_id: Volume to discover
        :returns: Status of the volume or None
        :returns: Device name or None
        :returns: LUN or None
        """
        # Get the initiatior WWPNs, targets and Lun for the given VIOS.
        vio_wwpns, t_wwpns, lun = self._get_hdisk_itls(vios_w)

        # Build the ITL map and discover the hdisks on the Virtual I/O
        # Server (if any).
        itls = hdisk.build_itls(vio_wwpns, t_wwpns, lun)
        if len(itls) == 0:
            LOG.debug('No ITLs for VIOS %(vios)s for volume %(volume_id)s.' % {
                'vios': vios_w.name,
                'volume_id': volume_id
            })
            return None, None, None

        status, device_name, udid = hdisk.discover_hdisk(
            self.adapter, vios_w.uuid, itls)

        if hdisk.good_discovery(status, device_name):
            LOG.info(
                _LI('Discovered %(hdisk)s on vios %(vios)s for '
                    'volume %(volume_id)s. Status code: %(status)s.'), {
                        'hdisk': device_name,
                        'vios': vios_w.name,
                        'volume_id': volume_id,
                        'status': str(status)
                    })
        elif status == hdisk.LUAStatus.DEVICE_IN_USE:
            LOG.warn(
                _LW('Discovered device %(dev)s for volume %(volume)s '
                    'on %(vios)s is in use. Error code: %(status)s.'), {
                        'dev': device_name,
                        'volume': volume_id,
                        'vios': vios_w.name,
                        'status': str(status)
                    })

        return status, device_name, udid
Example #6
0
    def connect_volume(self, adapter, host_uuid, vm_uuid, instance,
                       connection_info):
        """Connects the volume.

        :param adapter: The pypowervm adapter.
        :param host_uuid: The pypowervm UUID of the host.
        :param vm_uuid: The powervm UUID of the VM.
        :param instance: The nova instance that the volume should connect to.
        :param connection_info: Comes from the BDM.  Example connection_info:
                {
                'driver_volume_type':'fibre_channel',
                'serial':u'10d9934e-b031-48ff-9f02-2ac533e331c8',
                'data':{
                   'initiator_target_map':{
                      '21000024FF649105':['500507680210E522'],
                      '21000024FF649104':['500507680210E522'],
                      '21000024FF649107':['500507680210E522'],
                      '21000024FF649106':['500507680210E522']
                   },
                   'target_discovered':False,
                   'qos_specs':None,
                   'volume_id':'10d9934e-b031-48ff-9f02-2ac533e331c8',
                   'target_lun':0,
                   'access_mode':'rw',
                   'target_wwn':'500507680210E522'
                }
        """

        # Get the initiators
        it_map = connection_info['data']['initiator_target_map']
        volume_id = connection_info['data']['volume_id']
        lun = connection_info['data']['target_lun']
        hdisk_found = False

        i_wwpns = it_map.keys()
        t_wwpns = []
        # Build single list of target wwpns
        for it_list in it_map.values():
            t_wwpns.extend(it_list)

        # Get VIOS feed
        vios_feed = vios.get_active_vioses(adapter, host_uuid)

        # Iterate through host vios list to find valid hdisks and map to VM.
        # TODO(IBM): The VIOS should only include the intersection with
        # defined SCG targets when they are available.
        for vio_wrap in vios_feed:
            # TODO(IBM): Investigate if i_wwpns passed to discover_hdisk
            # should be intersection with VIOS pfc_wwpns
            itls = hdisk.build_itls(i_wwpns, t_wwpns, lun)
            status, device_name, udid = hdisk.discover_hdisk(
                adapter, vio_wrap.uuid, itls)
            if device_name is not None and status in [
                    hdisk.LUAStatus.DEVICE_AVAILABLE,
                    hdisk.LUAStatus.FOUND_ITL_ERR]:
                LOG.info(_LI('Discovered %(hdisk)s on vios %(vios)s for '
                         'volume %(volume_id)s. Status code: %(status)s.') %
                         {'hdisk': device_name, 'vios': vio_wrap.name,
                          'volume_id': volume_id, 'status': str(status)})
                self._add_mapping(adapter, host_uuid, vm_uuid, vio_wrap.uuid,
                                  device_name)
                connection_info['data']['target_UDID'] = udid
                self._set_udid(instance, vio_wrap.uuid, volume_id, udid)
                LOG.info(_LI('Device attached: %s'), device_name)
                hdisk_found = True
            elif status == hdisk.LUAStatus.DEVICE_IN_USE:
                LOG.warn(_LW('Discovered device %(dev)s for volume %(volume)s '
                             'on %(vios)s is in use Errorcode: %(status)s.'),
                         {'dev': device_name, 'volume': volume_id,
                          'vios': vio_wrap.name, 'status': str(status)})
        # A valid hdisk was not found so log and exit
        if not hdisk_found:
            msg = (_LE('Failed to discover valid hdisk on any Virtual I/O '
                       'Server for volume %(volume_id)s.') %
                   {'volume_id': volume_id})
            LOG.error(msg)
            if device_name is None:
                device_name = 'None'
            ex_args = {'backing_dev': device_name,
                       'instance_name': instance.name,
                       'reason': six.text_type(msg)}
            raise pexc.VolumeAttachFailed(**ex_args)