'Post operations for live migration.
This method is called from live_migration
and mainly updating database record.
:param ctxt: security context
:param instance: instance dict
:param dest: destination host
:param block_migration: if true, prepare for block migration
:param migrate_data: if not None, it is a dict which has data
required for live migration without shared storage'

@wrap_exception()
@wrap_instance_fault
def _post_live_migration(self, ctxt, instance, dest, block_migration=False, migrate_data=None):

    LOG.info('_post_live_migration()    is    started..', instance=instance)
    bdms = objects.BlockDeviceMappingList.get_by_instance_uuid(ctxt, instance.uuid)
    block_device_info = self._get_instance_block_device_info(ctxt, instance, bdms=bdms)
    self.driver.post_live_migration(ctxt, instance, block_device_info, migrate_data)
    connector = self.driver.get_volume_connector(instance)
    for bdm in bdms:
        if bdm.is_volume:
            self.volume_api.terminate_connection(ctxt, bdm.volume_id, connector)
    network_info = self.network_api.get_instance_nw_info(ctxt, instance)
    self._notify_about_instance_usage(ctxt, instance, 'live_migration._post.start', network_info=network_info)
    LOG.debug('Calling    driver.unfilter_instance    from    _post_live_migration', instance=instance)
    self.driver.unfilter_instance(instance, network_info)
    migration = {'source_compute': self.host, 'dest_compute': dest}
    self.network_api.migrate_instance_start(ctxt, instance, migration)
    destroy_vifs = False
    try:
        self.driver.post_live_migration_at_source(ctxt, instance, network_info)
    except NotImplementedError as ex:
        LOG.debug(ex, instance=instance)
        destroy_vifs = True
    post_at_dest_success = True
    try:
        self.compute_rpcapi.post_live_migration_at_destination(ctxt, instance, block_migration, dest)
    except Exception as error:
        post_at_dest_success = False
        LOG.exception('Post    live    migration    at    destination    %s    failed', dest, instance=instance, error=error)
    (do_cleanup, destroy_disks) = self._live_migration_cleanup_flags(migrate_data)
    if do_cleanup:
        LOG.debug('Calling    driver.cleanup    from    _post_live_migration', instance=instance)
        self.driver.cleanup(ctxt, instance, network_info, destroy_disks=destroy_disks, migrate_data=migrate_data, destroy_vifs=destroy_vifs)
    self.instance_events.clear_events_for_instance(instance)
    self.update_available_resource(ctxt)
    self._update_scheduler_instance_info(ctxt, instance)
    self._notify_about_instance_usage(ctxt, instance, 'live_migration._post.end', network_info=network_info)
    if post_at_dest_success:
        LOG.info('Migrating    instance    to    %s    finished    successfully.', dest, instance=instance)
    if (migrate_data and migrate_data.obj_attr_is_set('migration')):
        migrate_data.migration.status = 'completed'
        migrate_data.migration.save()
