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