def _migrate_volume_generic(self, ctxt, volume, host, new_type_id):
    rpcapi = volume_rpcapi.VolumeAPI()
    skip = (self._VOLUME_CLONE_SKIP_PROPERTIES | {'host'})
    new_vol_values = {k: volume[k] for k in (set(volume.keys()) - skip)}
    if new_type_id:
        new_vol_values['volume_type_id'] = new_type_id
    new_volume = objects.Volume(context=ctxt, host=host['host'], status='creating', attach_status='detached', migration_status=('target:%s' % volume['id']), **new_vol_values)
    new_volume.create()
    rpcapi.create_volume(ctxt, new_volume, host['host'], None, None, allow_reschedule=False)
    starttime = time.time()
    deadline = (starttime + CONF.migration_create_volume_timeout_secs)
    new_volume = objects.Volume.get_by_id(ctxt, new_volume.id)
    tries = 0
    while (new_volume.status != 'available'):
        tries += 1
        now = time.time()
        if (new_volume.status == 'error'):
            msg = _('failed to create new_volume on destination host')
            self._clean_temporary_volume(ctxt, volume, new_volume, clean_db_only=True)
            raise exception.VolumeMigrationFailed(reason=msg)
        elif (now > deadline):
            msg = _('timeout creating new_volume on destination host')
            self._clean_temporary_volume(ctxt, volume, new_volume, clean_db_only=True)
            raise exception.VolumeMigrationFailed(reason=msg)
        else:
            time.sleep((tries ** 2))
        new_volume = objects.Volume.get_by_id(ctxt, new_volume.id)
    try:
        attachments = volume.volume_attachment
        if (not attachments):
            self.driver.before_volume_copy(ctxt, volume, new_volume, remote='dest')
            self._copy_volume_data(ctxt, volume, new_volume, remote='dest')
            self.driver.after_volume_copy(ctxt, volume, new_volume, remote='dest')
            self.migrate_volume_completion(ctxt, volume.id, new_volume.id, error=False, volume=volume, new_volume=new_volume)
        else:
            nova_api = compute.API()
            for attachment in attachments:
                instance_uuid = attachment['instance_uuid']
                nova_api.update_server_volume(ctxt, instance_uuid, volume.id, new_volume.id)
    except Exception:
        with excutils.save_and_reraise_exception():
            LOG.exception(_LE('Failed to copy volume %(vol1)s to %(vol2)s'), {'vol1': volume.id, 'vol2': new_volume.id})
            self._clean_temporary_volume(ctxt, volume, new_volume)
def _migrate_volume_generic(self, ctxt, volume, host, new_type_id):
    rpcapi = volume_rpcapi.VolumeAPI()
    skip = (self._VOLUME_CLONE_SKIP_PROPERTIES | {'host'})
    new_vol_values = {k: volume[k] for k in (set(volume.keys()) - skip)}
    if new_type_id:
        new_vol_values['volume_type_id'] = new_type_id
    new_volume = objects.Volume(context=ctxt, host=host['host'], status='creating', attach_status='detached', migration_status=('target:%s' % volume['id']), **new_vol_values)
    new_volume.create()
    rpcapi.create_volume(ctxt, new_volume, host['host'], None, None, allow_reschedule=False)
    starttime = time.time()
    deadline = (starttime + CONF.migration_create_volume_timeout_secs)
    new_volume = objects.Volume.get_by_id(ctxt, new_volume.id)
    tries = 0
    while (new_volume.status != 'available'):
        tries += 1
        now = time.time()
        if (new_volume.status == 'error'):
            msg = _('failed to create new_volume on destination host')
            self._clean_temporary_volume(ctxt, volume, new_volume, clean_db_only=True)
            raise exception.VolumeMigrationFailed(reason=msg)
        elif (now > deadline):
            msg = _('timeout creating new_volume on destination host')
            self._clean_temporary_volume(ctxt, volume, new_volume, clean_db_only=True)
            raise exception.VolumeMigrationFailed(reason=msg)
        else:
            time.sleep((tries ** 2))
        new_volume = objects.Volume.get_by_id(ctxt, new_volume.id)
    try:
        attachments = volume.volume_attachment
        if (not attachments):
            self.driver.before_volume_copy(ctxt, volume, new_volume, remote='dest')
            self._copy_volume_data(ctxt, volume, new_volume, remote='dest')
            self.driver.after_volume_copy(ctxt, volume, new_volume, remote='dest')
            self.migrate_volume_completion(ctxt, volume.id, new_volume.id, error=False, volume=volume, new_volume=new_volume)
        else:
            nova_api = compute.API()
            for attachment in attachments:
                instance_uuid = attachment['instance_uuid']
                nova_api.update_server_volume(ctxt, instance_uuid, volume.id, new_volume.id)
    except Exception:
        with excutils.save_and_reraise_exception():
            LOG.exception(_LE('Failed to copy volume %(vol1)s to %(vol2)s'), {'vol1': volume.id, 'vol2': new_volume.id})
            self._clean_temporary_volume(ctxt, volume, new_volume)