'FlashCopy mapping check helper.'

def _check_vdisk_fc_mappings(self, name, allow_snaps=True, allow_fctgt=False):

    LOG.debug('Loopcall:    _check_vdisk_fc_mappings(),    vdisk    %s.', name)
    mapping_ids = self._get_vdisk_fc_mappings(name)
    wait_for_copy = False
    for map_id in mapping_ids:
        attrs = self._get_flashcopy_mapping_attributes(map_id)
        if ((not attrs) or ('yes' == attrs['rc_controlled'])):
            continue
        source = attrs['source_vdisk_name']
        target = attrs['target_vdisk_name']
        copy_rate = attrs['copy_rate']
        status = attrs['status']
        if (allow_fctgt and (target == name) and (status == 'copying')):
            self.ssh.stopfcmap(map_id)
            attrs = self._get_flashcopy_mapping_attributes(map_id)
            if attrs:
                status = attrs['status']
        if (copy_rate == '0'):
            if (source == name):
                if (not allow_snaps):
                    raise loopingcall.LoopingCallDone(retvalue=False)
                self.ssh.chfcmap(map_id, copyrate='50', autodel='on')
                wait_for_copy = True
            else:
                if (target != name):
                    msg = (_('Vdisk    %(name)s    not    involved    in    mapping    %(src)s    ->    %(tgt)s.') % {'name': name, 'src': source, 'tgt': target})
                    LOG.error(msg)
                    raise exception.VolumeDriverException(message=msg)
                if (status in ['copying', 'prepared']):
                    self.ssh.stopfcmap(map_id)
                    wait_for_copy = True
                elif (status in ['stopping', 'preparing']):
                    wait_for_copy = True
                else:
                    self.ssh.rmfcmap(map_id)
        elif (status == 'prepared'):
            self.ssh.stopfcmap(map_id)
            self.ssh.rmfcmap(map_id)
        elif (status in ['idle_or_copied', 'stopped']):
            self.ssh.rmfcmap(map_id)
        else:
            wait_for_copy = True
    if ((not wait_for_copy) or (not len(mapping_ids))):
        raise loopingcall.LoopingCallDone(retvalue=True)
