'Create a cloned volume from another volume.
Since we are cloning from a volume and not a snapshot, we must first
create a snapshot of the source volume.
The user has the option to limit how long a volume\'s clone chain can be
by setting rbd_max_clone_depth. If a clone is made of another clone
and that clone has rbd_max_clone_depth clones behind it, the source
volume will be flattened.'

def create_cloned_volume(self, volume, src_vref):

    src_name = utils.convert_str(src_vref.name)
    dest_name = utils.convert_str(volume.name)
    flatten_parent = False
    if (self.configuration.rbd_max_clone_depth <= 0):
        with RBDVolumeProxy(self, src_name, read_only=True) as vol:
            vol.copy(vol.ioctx, dest_name)
            self._extend_if_required(volume, src_vref)
        return
    with RADOSClient(self) as client:
        depth = self._get_clone_depth(client, src_name)
        if (depth == self.configuration.rbd_max_clone_depth):
            LOG.debug('maximum    clone    depth    (%d)    has    been    reached    -    flattening    source    volume', self.configuration.rbd_max_clone_depth)
            flatten_parent = True
        src_volume = self.rbd.Image(client.ioctx, src_name)
        try:
            if flatten_parent:
                (_pool, parent, snap) = self._get_clone_info(src_volume, src_name)
                LOG.debug('flattening    source    volume    %s', src_name)
                src_volume.flatten()
                parent_volume = self.rbd.Image(client.ioctx, parent)
                try:
                    parent_volume.unprotect_snap(snap)
                    parent_volume.remove_snap(snap)
                finally:
                    parent_volume.close()
            clone_snap = ('%s.clone_snap' % dest_name)
            LOG.debug("creating    snapshot='%s'", clone_snap)
            src_volume.create_snap(clone_snap)
            src_volume.protect_snap(clone_snap)
        except Exception:
            src_volume.close()
            raise
        try:
            LOG.debug("cloning    '%(src_vol)s@%(src_snap)s'    to    '%(dest)s'", {'src_vol': src_name, 'src_snap': clone_snap, 'dest': dest_name})
            self.RBDProxy().clone(client.ioctx, src_name, clone_snap, client.ioctx, dest_name, features=client.features)
        except Exception:
            src_volume.unprotect_snap(clone_snap)
            src_volume.remove_snap(clone_snap)
            src_volume.close()
            raise
        try:
            volume_update = self._enable_replication_if_needed(volume)
        except Exception:
            self.RBDProxy().remove(client.ioctx, dest_name)
            err_msg = _('Failed    to    enable    image    replication')
            raise exception.ReplicationError(reason=err_msg, volume_id=volume.id)
        finally:
            src_volume.close()
        self._extend_if_required(volume, src_vref)
    LOG.debug('clone    created    successfully')
    return volume_update
