'Create volume from snapshot.
InfiniBox does not yet support detached clone so use dd to copy data.
This could be a lengthy operation.
- create a clone from snapshot and map it
- create a volume and map it
- copy data from clone to volume
- unmap volume and clone and delete the clone'

@infinisdk_to_cinder_exceptions
def create_volume_from_snapshot(self, volume, snapshot):

    infinidat_snapshot = self._get_infinidat_snapshot(snapshot)
    clone_name = (self._make_volume_name(volume) + '-internal')
    infinidat_clone = infinidat_snapshot.create_child(name=clone_name)
    clone = mock.Mock(id=(str(volume.id) + '-internal'))
    try:
        infinidat_volume = self._create_volume(volume)
        try:
            src_ctx = self._device_connect_context(clone)
            dst_ctx = self._device_connect_context(volume)
            with src_ctx as src_dev:
                with dst_ctx as dst_dev:
                    dd_block_size = self.configuration.volume_dd_blocksize
                    vol_utils.copy_volume(src_dev['device']['path'], dst_dev['device']['path'], (snapshot.volume.size * units.Ki), dd_block_size, sparse=True)
        except Exception:
            infinidat_volume.delete()
            raise
    finally:
        infinidat_clone.delete()
