'Poll to see when a lun or snap copy to a lun is complete.
:param src_vol_id:  cinder volume ID of source volume
:param dest_vdev_id:  virtual device ID of destination, for snap copy
:param dest_obj_id:  lun object ID of destination, for lun copy
:returns: True if successful, False otherwise'

def _wait_for_lun_or_snap_copy(self, src_vol_id, dest_vdev_id=None, dest_obj_id=None):

    wait_id = None
    wait_func = None
    if dest_vdev_id:
        wait_id = dest_vdev_id
        wait_func = self.vmem_mg.snapshot.get_snapshot_copy_status
    elif dest_obj_id:
        wait_id = dest_obj_id
        wait_func = self.vmem_mg.lun.get_lun_copy_status
    else:
        return False
    def _loop_func():
        LOG.debug('Entering    _wait_for_lun_or_snap_copy    loop:    vdev=%s,    objid=%s', dest_vdev_id, dest_obj_id)
        (target_id, mb_copied, percent) = wait_func(src_vol_id)
        if (target_id is None):
            LOG.debug('lun    or    snap    copy    prepping.')
            pass
        elif (target_id != wait_id):
            LOG.debug('lun    or    snap    copy    complete.')
            raise loopingcall.LoopingCallDone(retvalue=True)
        elif (mb_copied is not None):
            LOG.debug('MB    copied:    %(copied)d,    percent    done:    %(percent)d.', {'copied': mb_copied, 'percent': percent})
            pass
        elif (percent == 0):
            LOG.debug('lun    or    snap    copy    started.')
            pass
        elif (percent == 100):
            LOG.debug('lun    or    snap    copy    complete.')
            raise loopingcall.LoopingCallDone(retvalue=True)
        else:
            LOG.debug('unexpected    case    (%(id)s,    %(bytes)s,    %(percent)s)', {'id': target_id, 'bytes': mb_copied, 'percent': six.text_type(percent)})
            raise loopingcall.LoopingCallDone(retvalue=False)
    timer = loopingcall.FixedIntervalLoopingCall(_loop_func)
    success = timer.start(interval=1).wait()
    return success
