On 07/02/2014 01:12 PM, Kashyap Chamarthy wrote:
We have this simple chain:
base <- snap1
Let's quickly examine the contents of 'base' and 'snap1' images:
Now, let's do a live blockcopy (with a '--finish' to graecully finish
the mirroring):
$ virsh blockcopy --domain testvm2 vda \
/export/dst/copy.qcow2 \
--wait --verbose --finish
This defaults to a full copy (copy.qcow2 will contain everything in the
latest state of the original chain, but with no backing file).
If I'm reading the man page of 'blockcopy' correctly, shouldn't it
'flatten' the entire chain, by also copying the contents of base into
copy.qcow2? i.e. the 'copy' should have files (including the file foo
from 'base':
foo, bar, baz, jazz
True or false?
False. This is NOT a union mount. Sometime in between base and snap1,
you deleted foo. That is recorded in snap1, and when reading a chain,
you stop at the first level of the chain that provides information.
When flattening, it means you are inherently losing any information
about the state that existed before snap1 changed the state, at least
when using the flattened chain to try and find that information.
Graphically (well, using ASCII), let's look at it like this. When you
start your guest originally, you have a big blank disk being tracked by
the base image, and write into some sectors of that disk. So, use "A"
to represent the initial OS install, and "X" to represent a sector not
yet written:
base: AAAAXXXXXXXXXXXX
====
guest: AAAAXXXXXXXXXXXX
Then, you modify the guest to write the file foo, represent that with
"B" for the sectors that were modified:
base: AAABBBBBXXXXXXXX
====
guest: AAABBBBBXXXXXXXX
then you take a snapshot, at the point you take it, snap1 is completely
empty, but notice that the guest view of the world is still unchanged:
base: AAABBBBBXXXXXXXX
snap1: XXXXXXXXXXXXXXXX
====
guest: AAABBBBBXXXXXXXX
now you do some more modification, such as deleting foo, and creating
bar (note that deleting a file can be done by writing one sector, and
may still leave remnants of the file behind in other sectors, but in
such a way that the guest file system will never retrieve those
contents). Represent these changes with "C"
base: AAABBBBBXXXXXXXX
snap1: XXXCXXXXCCCCXXXX
====
guest: AAACBBBBCCCCXXXX
When you are doing a full blockcopy, you are asking to create a new file
whose contents match what the guest sees. When the copy finally reaches
sync, you have:
base: AAABBBBBXXXXXXXX
snap1: XXXCXXXXCCCCXXXX
copy: AAACBBBBCCCCXXXX
====
guest: AAACBBBBCCCCXXXX
The copy operation lasts as long as you want; in that time, the guest
can make even more changes, let's call them "D"
base: AAABBBBBXXXXXXXX
snap1: XXXDXXXXCCCCDDDD
copy: AAADBBBBCCCCDDDD
====
guest: AAADBBBBCCCCDDDD
then you finally abort or pivot the copy. Let's try a pivot, where the
next action in the guest causes changes to the disk labeled "E":
base: AAABBBBBXXXXXXXX
snap1: XXXDXXXXCCCCDDDD
copy: AAAEBBBBCCCCDDDD
====
guest: AAAEBBBBCCCCDDDD
PS: I've tested the cases of --pivot, --shallow and --reuse-external,
will post my notes about them on a wiki.
I hope those help you figure out what's going on. You seem to be hoping
for a magic bullet that gives you file system union mounts (merge the
contents of two different timestamps of a directories existence in a
common file system) - but that is NOT what disk snapshots do. All
libvirt and qemu can do is block level manipulations, not file system
manipulations. I'm not even sure if a file system tool exists that can
do file system checkpoints and/or union mount merges; but if it does, it
would be something you use in the guest at the file system level, and
not something libvirt can manage at the block device sector level.
Wow, very helpful to me.