[libvirt-users] Deleting and coalescing live snapshots

Eric Blake eblake at redhat.com
Thu Feb 28 00:16:52 UTC 2013

On 02/27/2013 11:38 AM, Skardal, Harald wrote:
> I have a service that takes new live KVM snapshots Si regularly, keeps a
> fixed number N (Si ,..,Si-N+1), and therefore needs to delete Si-N in
> this cycle.
> Until libvirt includes support for this capability that is said to be
> available in qemu, what is a safe workflow to delete old live KVM
> snapshots w/o losing data. Do I need to pause/shut down the VM?

> The development environment is Fedora 18 with qemu, libvirtd and libvirt
> upgrades to the more recent stable versions.

Are you using the fedora-virt-preview repo?  If so, that gives you:

which is indeed the latest upstream releases of both projects at the
time of my email.  In which case, you're in luck!  You can delete old
snapshots without any guest downtime.

Next question: are your snapshots internal or external?  Or in other
words, what command did you use to create the snapshots?  I'll try to
answer for both setups:

Assuming your snapshot was internal (such as one created via 'virsh
snapshot-create' without the --disk-only or --memspec flag), then you
have the following setup:

'virsh snapshot-list $dom' shows a list of snapshots, and 'qemu-img info
/path/to/file' also shows[*] the same list of internal snapshots.  You
can delete the snapshots you no longer need with 'virsh snapshot-delete
$dom $snapname' whether the guest is running or offline; but be aware
that while it frees up the reference counting in the qcow2 file, current
qemu is unable to make decent use of that space (that is, qemu is lousy
at defragmentation).  If you must reclaim disk space, then using
'qemu-img convert' or something like 'virt-sparsify' from libguestfs,
while your guest is offline, would be a good followup operation for
saving JUST the current image, but I don't know of any good command for
preserving all of the existing internal snapshots of a qcow2 image while
still compacting away unused space.

[*] Technically, using qemu-img info on a file in active use by qemu is
not guaranteed to be safe, but as a read-only operation, the worst it
can do is see inconsistent information.  Be careful, though, as there
are other qemu-img operations that can corrupt an in-use image in a
manner visible to the guest.  Hence, I prefer to use qemu-img only on
files while the guest is offline.

Assuming your snapshot was external (such as one created via 'virsh
snapshot-create --disk-only'), then your version of libvirt does not yet
support deletion of entire snapshots (although we have posted some
design ideas on the list on how we plan to get there in a future
libvirt).  But what you can do is one of two techniques to shorten the
backing chain, then tell libvirt to discard the metadata for the
snapshots that no longer make sense, then manually delete the files you
no longer need.  Notationally, you are starting from a disk chain that
looks like:

base <- snap1 <- snap2 <- snap3 <- current

and you want to get rid of snap1.  The two choices are to commit the
contents of snap1 into a lower level, using 'virsh blockcommit $dom
$disk --top snap2 --base base ...':

base' <- snap2 <- snap3 <- current

or to pull the contents of snap1 into a higher level, using 'virsh
blockpull $dom $disk --base base ...':

base <- current'

Use 'virsh help blockcommit' or 'virsh help blockpull' to see more
details on the commands, and use 'virsh domblklist $dom' to see a list
of disk names tied to a given domain.  Personally, I like the '--wait
--verbose' flags, as it gives a nice log of progress in a potentially
long-running operation.

Blockcommit in your version of qemu has a limitation - it can only
commit data from one backing file into another (that is, you can commit
from snap3 into any earlier image to remove snap3 from the chain, but
cannot commit from current into snap3 to remove current from the chain).
 We are still trying to design how to make blockcommit run from the top
of a chain, although it might not make qemu 1.5.  Also, blockcommit has
a caveat - if you use thin provisioning (that is, if more than one guest
shares a common base file), then you must NOT commit into that common
base file (someday, I'd like to teach libvirt to have the smarts to
prevent you from doing stupid actions on common shared backing files,
but that also involves teaching libvirt to track entire backing chain
information in domain xml).

Likewise, blockpull in your version of qemu has a limitation - it can
only pull data into the current (topmost) image of the chain; we are
still trying to design how to make blockpull target an intermediate
point in the chain of a running qemu, but that might not make qemu 1.5.
 However, while blockcommit invalidates any images that have branched
off a common backing file, blockpull leaves all other images intact, so
you can still revert to the images that have been removed from the
backing chain.

Additionally both of these commands are limited to working on a running
guest; the same operations can be done for offline disk images with
manual use of qemu-img ['qemu-img commit' and 'qemu-img rebase'], but I
hope to someday wire up libvirt to support the same operations without
making you have to use anything outside of virsh.  Depending on what
manual qemu-img actions you do, you might also have to 'virsh edit $dom'
to teach libvirt about the manual changes you made.

Then, whether you used commit or pull to shorten your backing chains,
you would then use 'virsh snapshot-delete $dom $name --metadata' to tell
libvirt to discard the metadata about the snapshots that no longer make

Finally, since you are using new enough libvirt and qemu, I would
suggest looking into using 'virsh blockcopy ...' as a potential backup
mechanism.  Unlike 'virsh snapshot-create' which lengthens the backing
chain of the running image so that you can then back up from the backing
file, 'virsh blockcopy' can create backups of a running guest without
ever affecting the chain length of the running image.  That also comes
with a caveat - in your current tool versions, blockcopy can only be
done on a transient guest; we are waiting for persistent bitmap support
to be added in qemu 1.5 before libvirt will allow a blockcopy on a
persistent guest.  But at least you can temporarily 'virsh undefine' a
guest to make it transient, do the block copy, then 'virsh define' the
guest again, all while the guest remains running.  Blockcopy can also be
used to do some more interesting (aka more complex) conversions: by
doing a shallow copy, you can effectively rebase a live current image
onto a new backing chain with the same contents as the original but
where the division of contents in the new backing chain is completely
under your control.

Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 621 bytes
Desc: OpenPGP digital signature
URL: <http://listman.redhat.com/archives/libvirt-users/attachments/20130227/4193a255/attachment.sig>

More information about the libvirt-users mailing list