'Create a volume efficiently from an existing image.
Verify the image ID being used:
(1) If there is no existing cache volume, create one and transfer
image data to it. Take a snapshot.
(2) If a cache volume already exists, verify if it is either alternated
or updated. If so try to remove it, raise exception if removal fails.
Create a new cache volume as in (1).
Clone a volume from the cache volume and returns it to Cinder.
A file lock is placed on this method to prevent:
(a) a race condition when a cache volume has been verified, but then
gets deleted before it is cloned.
(b) failure of subsequent clone_image requests if the first request is
still pending.'

@utils.synchronized('zfssaiscsi', external=True)
def clone_image(self, context, volume, image_location, image_meta, image_service):

    LOG.debug('Cloning    image    %(image)s    to    volume    %(volume)s', {'image': image_meta['id'], 'volume': volume['name']})
    lcfg = self.configuration
    if (not lcfg.zfssa_enable_local_cache):
        return (None, False)
    cachevol_size = image_meta['size']
    if (('virtual_size' in image_meta) and image_meta['virtual_size']):
        cachevol_size = image_meta['virtual_size']
    cachevol_size_gb = int(math.ceil((float(cachevol_size) / units.Gi)))
    if ((cachevol_size % units.Gi) == 0):
        cachevol_size_gb += 1
    if (cachevol_size_gb > volume['size']):
        exception_msg = ('Image    size    %(img_size)dGB    is    larger    than    volume    size    %(vol_size)dGB.', {'img_size': cachevol_size_gb, 'vol_size': volume['size']})
        LOG.error(exception_msg)
        return (None, False)
    specs = self._get_voltype_specs(volume)
    specs.update({'custom:cinder_managed': True})
    cachevol_props = {'size': cachevol_size_gb}
    try:
        (cache_vol, cache_snap) = self._verify_cache_volume(context, image_meta, image_service, specs, cachevol_props)
        self.zfssa.clone_snapshot(lcfg.zfssa_pool, lcfg.zfssa_cache_project, cache_vol, cache_snap, lcfg.zfssa_project, volume['name'], specs)
        if (cachevol_size_gb < volume['size']):
            self.extend_volume(volume, volume['size'])
    except exception.VolumeBackendAPIException as exc:
        exception_msg = ('Cannot    clone    image    %(image)s    to    volume    %(volume)s.    Error:    %(error)s.', {'volume': volume['name'], 'image': image_meta['id'], 'error': exc.msg})
        LOG.error(exception_msg)
        return (None, False)
    return (None, True)
