'Snapshot the given volume-backed instance.
:param instance: nova.objects.instance.Instance object
:param name: name of the backup or snapshot
:param extra_properties: dict of extra image properties to include
:returns: the new image metadata'

@check_instance_state(vm_state=[vm_states.ACTIVE, vm_states.STOPPED, vm_states.SUSPENDED])
def snapshot_volume_backed(self, context, instance, name, extra_properties=None):

    image_meta = self._initialize_instance_snapshot_metadata(instance, name, extra_properties)
    image_meta['size'] = 0
    for attr in ('container_format', 'disk_format'):
        image_meta.pop(attr, None)
    properties = image_meta['properties']
    for key in ('block_device_mapping', 'bdm_v2', 'root_device_name'):
        properties.pop(key, None)
    if instance.root_device_name:
        properties['root_device_name'] = instance.root_device_name
    quiesced = False
    if (instance.vm_state == vm_states.ACTIVE):
        try:
            self.compute_rpcapi.quiesce_instance(context, instance)
            quiesced = True
        except (exception.InstanceQuiesceNotSupported, exception.QemuGuestAgentNotEnabled, exception.NovaException, NotImplementedError) as err:
            if strutils.bool_from_string(instance.system_metadata.get('image_os_require_quiesce')):
                raise
            else:
                LOG.info('Skipping    quiescing    instance:    %(reason)s.', {'reason': err}, instance=instance)
    bdms = objects.BlockDeviceMappingList.get_by_instance_uuid(context, instance.uuid)
    mapping = []
    for bdm in bdms:
        if bdm.no_device:
            continue
        if bdm.is_volume:
            volume = self.volume_api.get(context, bdm.volume_id)
            name = (_('snapshot    for    %s') % image_meta['name'])
            LOG.debug('Creating    snapshot    from    volume    %s.', volume['id'], instance=instance)
            snapshot = self.volume_api.create_snapshot_force(context, volume['id'], name, volume['display_description'])
            mapping_dict = block_device.snapshot_from_bdm(snapshot['id'], bdm)
            mapping_dict = mapping_dict.get_image_mapping()
        else:
            mapping_dict = bdm.get_image_mapping()
        mapping.append(mapping_dict)
    if quiesced:
        self.compute_rpcapi.unquiesce_instance(context, instance, mapping)
    if mapping:
        properties['block_device_mapping'] = mapping
        properties['bdm_v2'] = True
    return self.image_api.create(context, image_meta)
