'Perform volume snapshot.
:param guest: VM that volume is attached to
:param volume_id: volume UUID to snapshot
:param new_file: relative path to new qcow2 file present on share'

def _volume_snapshot_create(self, context, instance, guest, volume_id, new_file):

    xml = guest.get_xml_desc()
    xml_doc = etree.fromstring(xml)
    device_info = vconfig.LibvirtConfigGuest()
    device_info.parse_dom(xml_doc)
    disks_to_snap = []
    network_disks_to_snap = []
    disks_to_skip = []
    for guest_disk in device_info.devices:
        if (guest_disk.root_name != 'disk'):
            continue
        if (guest_disk.target_dev is None):
            continue
        if ((guest_disk.serial is None) or (guest_disk.serial != volume_id)):
            disks_to_skip.append(guest_disk.target_dev)
            continue
        disk_info = {'dev': guest_disk.target_dev, 'serial': guest_disk.serial, 'current_file': guest_disk.source_path, 'source_protocol': guest_disk.source_protocol, 'source_name': guest_disk.source_name, 'source_hosts': guest_disk.source_hosts, 'source_ports': guest_disk.source_ports}
        if (disk_info['current_file'] is not None):
            current_file = disk_info['current_file']
            new_file_path = os.path.join(os.path.dirname(current_file), new_file)
            disks_to_snap.append((current_file, new_file_path))
        elif (disk_info['source_protocol'] == 'netfs'):
            network_disks_to_snap.append((disk_info, new_file))
    if ((not disks_to_snap) and (not network_disks_to_snap)):
        msg = _('Found    no    disk    to    snapshot.')
        raise exception.InternalError(msg)
    snapshot = vconfig.LibvirtConfigGuestSnapshot()
    for (current_name, new_filename) in disks_to_snap:
        snap_disk = vconfig.LibvirtConfigGuestSnapshotDisk()
        snap_disk.name = current_name
        snap_disk.source_path = new_filename
        snap_disk.source_type = 'file'
        snap_disk.snapshot = 'external'
        snap_disk.driver_name = 'qcow2'
        snapshot.add_disk(snap_disk)
    for (disk_info, new_filename) in network_disks_to_snap:
        snap_disk = vconfig.LibvirtConfigGuestSnapshotDisk()
        snap_disk.name = disk_info['dev']
        snap_disk.source_type = 'network'
        snap_disk.source_protocol = disk_info['source_protocol']
        snap_disk.snapshot = 'external'
        snap_disk.source_path = new_filename
        old_dir = disk_info['source_name'].split('/')[0]
        snap_disk.source_name = ('%s/%s' % (old_dir, new_filename))
        snap_disk.source_hosts = disk_info['source_hosts']
        snap_disk.source_ports = disk_info['source_ports']
        snapshot.add_disk(snap_disk)
    for dev in disks_to_skip:
        snap_disk = vconfig.LibvirtConfigGuestSnapshotDisk()
        snap_disk.name = dev
        snap_disk.snapshot = 'no'
        snapshot.add_disk(snap_disk)
    snapshot_xml = snapshot.to_xml()
    LOG.debug('snap    xml:    %s', snapshot_xml, instance=instance)
    image_meta = instance.image_meta
    try:
        self._can_quiesce(instance, image_meta)
        try:
            guest.snapshot(snapshot, no_metadata=True, disk_only=True, reuse_ext=True, quiesce=True)
            return
        except libvirt.libvirtError:
            if self._requires_quiesce(image_meta):
                raise
            LOG.exception(_('Unable    to    create    quiesced    VM    snapshot,    attempting    again    with    quiescing    disabled.'), instance=instance)
    except (exception.InstanceQuiesceNotSupported, exception.QemuGuestAgentNotEnabled) as err:
        if self._requires_quiesce(image_meta):
            raise
        LOG.info('Skipping    quiescing    instance:    %(reason)s.', {'reason': err}, instance=instance)
    try:
        guest.snapshot(snapshot, no_metadata=True, disk_only=True, reuse_ext=True, quiesce=False)
    except libvirt.libvirtError:
        LOG.exception(_('Unable    to    create    VM    snapshot,    failing    volume_snapshot    operation.'), instance=instance)
        raise
