Beispiel #1
0
    def attach_volume(self):
        """Attaches the volume."""

        # Check if the VM is in a state where the attach is acceptable.
        lpar_w = vm.get_instance_wrapper(self.adapter, self.instance)
        capable, reason = lpar_w.can_modify_io()
        if not capable:
            raise exc.VolumeAttachFailed(volume_id=self.volume_id,
                                         reason=reason)

        # Its about to get weird.  The transaction manager has a list of
        # VIOSes.  We could use those, but they only have SCSI mappings (by
        # design).  They do not have storage (super expensive).
        #
        # We need the storage xag when we are determining which mappings to
        # add to the system.  But we don't want to tie it to the stg_ftsk.  If
        # we do, every retry, every etag gather, etc... takes MUCH longer.
        #
        # So we get the VIOSes with the storage xag here, separately, to save
        # the stg_ftsk from potentially having to run it multiple times.
        attach_ftsk = pvm_tx.FeedTask(
            'attach_volume_to_vio',
            pvm_vios.VIOS.getter(
                self.adapter,
                xag=[pvm_const.XAG.VIO_STOR, pvm_const.XAG.VIO_SMAP]))

        # Find valid hdisks and map to VM.
        attach_ftsk.add_functor_subtask(self._attach_volume_to_vio,
                                        provides='vio_modified',
                                        flag_update=False)

        ret = attach_ftsk.execute()

        # Check the number of VIOSes
        vioses_modified = 0
        for result in ret['wrapper_task_rets'].values():
            if result['vio_modified']:
                vioses_modified += 1

        # Validate that a vios was found
        if vioses_modified == 0:
            msg = (_('Failed to discover valid hdisk on any Virtual I/O '
                     'Server for volume %(volume_id)s.') % {
                         'volume_id': self.volume_id
                     })
            ex_args = {'volume_id': self.volume_id, 'reason': msg}
            raise exc.VolumeAttachFailed(**ex_args)

        self.stg_ftsk.execute()
Beispiel #2
0
    def attach_volume(self, connection_info, instance_name, ebs_root=False):
        self.ensure_share_mounted(connection_info)

        disk_path = self._get_disk_path(connection_info)

        try:
            if ebs_root:
                ctrller_path = self._vmutils.get_vm_ide_controller(
                    instance_name, 0)
                slot = 0
            else:
                ctrller_path = self._vmutils.get_vm_scsi_controller(
                    instance_name)
                slot = self._vmutils.get_free_controller_slot(ctrller_path)

            self._vmutils.attach_drive(instance_name, disk_path, ctrller_path,
                                       slot)
        except os_win_exc.HyperVException as exn:
            LOG.exception(
                _LE('Attach volume failed to %(instance_name)s: '
                    '%(exn)s'), {
                        'instance_name': instance_name,
                        'exn': exn
                    })
            raise exception.VolumeAttachFailed(
                volume_id=connection_info['data']['volume_id'],
                reason=exn.message)
Beispiel #3
0
    def connect_volume(self, connection_info):
        connection_properties = connection_info['data']
        auth_method = connection_properties.get('auth_method')

        if auth_method and auth_method.upper() != 'CHAP':
            LOG.error(
                _LE("Unsupported iSCSI authentication "
                    "method: %(auth_method)s."), dict(auth_method=auth_method))
            raise exception.UnsupportedBDMVolumeAuthMethod(
                auth_method=auth_method)

        volume_connected = False
        for (initiator_name, target_portal, target_iqn,
             target_lun) in self._get_all_paths(connection_properties):
            try:
                msg = _LI("Attempting to estabilish an iSCSI session to "
                          "target %(target_iqn)s on portal %(target_portal)s "
                          "acessing LUN %(target_lun)s using initiator "
                          "%(initiator_name)s.")
                LOG.info(
                    msg,
                    dict(target_portal=target_portal,
                         target_iqn=target_iqn,
                         target_lun=target_lun,
                         initiator_name=initiator_name))
                self._iscsi_utils.login_storage_target(
                    target_lun=target_lun,
                    target_iqn=target_iqn,
                    target_portal=target_portal,
                    auth_username=connection_properties.get('auth_username'),
                    auth_password=connection_properties.get('auth_password'),
                    mpio_enabled=CONF.hyperv.use_multipath_io,
                    initiator_name=initiator_name)

                volume_connected = True
                if not CONF.hyperv.use_multipath_io:
                    break
            except os_win_exc.OSWinException:
                LOG.exception(_LE("Could not connect iSCSI target %s."),
                              target_iqn)

        if not volume_connected:
            raise exception.VolumeAttachFailed(
                _("Could not connect volume %s.") %
                connection_properties['volume_id'])
Beispiel #4
0
    def attach_volume(self,
                      connection_info,
                      instance_name,
                      disk_bus=constants.CTRL_TYPE_SCSI):
        tries_left = CONF.hyperv.volume_attach_retry_count + 1

        while tries_left:
            try:
                self._attach_volume(connection_info, instance_name, disk_bus)
                break
            except Exception as ex:
                tries_left -= 1
                if not tries_left:
                    LOG.exception(
                        "Failed to attach volume %(connection_info)s "
                        "to instance %(instance_name)s.", {
                            'connection_info':
                            strutils.mask_dict_password(connection_info),
                            'instance_name':
                            instance_name
                        })

                    self.disconnect_volume(connection_info)
                    raise exception.VolumeAttachFailed(
                        volume_id=connection_info['serial'], reason=ex)
                else:
                    LOG.warning(
                        "Failed to attach volume %(connection_info)s "
                        "to instance %(instance_name)s. "
                        "Tries left: %(tries_left)s.", {
                            'connection_info':
                            strutils.mask_dict_password(connection_info),
                            'instance_name':
                            instance_name,
                            'tries_left':
                            tries_left
                        })

                    time.sleep(CONF.hyperv.volume_attach_retry_interval)