'Migrate the volume to the specified host or cluster.'

@wrap_check_policy
def migrate_volume(self, context, volume, host, cluster_name, force_copy, lock_volume):

    elevated = context.elevated()
    svc_host = (host and volume_utils.extract_host(host, 'backend'))
    svc_cluster = (cluster_name and volume_utils.extract_host(cluster_name, 'backend'))
    try:
        svc = objects.Service.get_by_id(elevated, None, is_up=True, topic=constants.VOLUME_TOPIC, host=svc_host, disabled=False, cluster_name=svc_cluster, backend_match_level='pool')
    except exception.ServiceNotFound:
        msg = (_("No    available    service    named    '%s'") % (cluster_name or host))
        LOG.error(msg)
        raise exception.InvalidHost(reason=msg)
    cluster_name = svc.cluster_name
    expected = {'status': ('available', 'in-use'), 'migration_status': self.AVAILABLE_MIGRATION_STATUS, 'replication_status': (None, 'disabled'), 'consistencygroup_id': (None, ''), 'group_id': (None, '')}
    if cluster_name:
        expected['cluster_name'] = db.Not(cluster_name)
    else:
        expected['host'] = db.Not(host)
    filters = [(~ db.volume_has_snapshots_filter())]
    updates = {'migration_status': 'starting', 'previous_status': volume.model.status}
    if lock_volume:
        updates['status'] = db.Case([((volume.model.status == 'available'), 'maintenance')], else_=volume.model.status)
    result = volume.conditional_update(updates, expected, filters)
    if (not result):
        msg = (_('Volume    %s    status    must    be    available    or    in-use,    must    not    be    migrating,    have    snapshots,    be    replicated,    be    part    of    a    group    and    destination    host/cluster    must    be    different    than    the    current    one') % {'vol_id': volume.id})
        LOG.error(msg)
        raise exception.InvalidVolume(reason=msg)
    volume_type = {}
    if volume.volume_type_id:
        volume_type = volume_types.get_volume_type(context.elevated(), volume.volume_type_id)
    request_spec = {'volume_properties': volume, 'volume_type': volume_type, 'volume_id': volume.id}
    self.scheduler_rpcapi.migrate_volume(context, volume, (cluster_name or host), force_copy, request_spec)
    LOG.info('Migrate    volume    request    issued    successfully.', resource=volume)
