L'uso di questo sito
autorizza anche l'uso dei cookie
necessari al suo funzionamento.
(Altre informazioni)

Wednesday, December 23, 2015

Using Linux LVM snapshots to run "experiments" on VMs


I am going to show how to create a LVM (Logical Volume Manager) snapshot and use it to return its base to a previous state.

This is useful for experiments, e.g on a LVM-based virtual machine (VM):
  • take a partition snapshot of the FS where the VM lives.
  • experiment with the VM (make config changes etc.)
  • if your tests are successful, lvremove the snapshot and keep the experiment's results
  • if you want to discard the tests, stop the VM then lvconvert –merge -v <snapshot> will restore the partition to its snapshot state.

Check required capabilities

# dmsetup targets
zero             v1.1.0
mirror           v1.13.2
snapshot-merge   v1.3.0
snapshot-origin  v1.9.0
snapshot         v1.13.0
striped          v1.5.1
linear           v1.2.1
error            v1.3.0

For the rest of the tutorial to work, we need the snapshot-merge target to exist.
If (as it happened to me) you run this on a machine with no kernel support for merging, you will be stumped in the last passage (lvcreate –merge). You can get out of this pickle by either:
  1. Grabbing a Live DVD of a distribution that has merge support
  2. run the last step from the live environment
or:
  1. Boot rescue from a distribution that has merge support
  2. Do not mount the LV partitions involved when/if asked
  3. run the last step from the rescue environment
While the first course of action worked perfectly in my case, it is the second one that redhat reccommends. When I tried it, however, the rescue environment was missing the required device files /dev/SataGroup and I could not proceed.

Create volume, make a filesystem, mount it.

# lvcreate --size 100m -n test SataGroup01
# mkfs.ext2 /dev/SataGroup01/test
# mkdir /tmp/test
#  mount /dev/SataGroup01/test /tmp/test
# cd /tmp/test
# ls
# mkdir a{0..2}
# ls
a0  a1  a2   lost+found
# for i in {0..2}; do touch a$i/b$i ; done
# ls a0
b0

Create a snapshot on the base volume, then mount it.

When the snapshot is created, care must be taken to make a large enough snapshot to avoid filling it. If the snapshot fills up, you will end up with a stuck snapshot and you'll have to go to hell and back to get rid of it (I may show how in a followup post).

# lvcreate --snapshot --size 100m -n test-snap /dev/SataGroup01/test
# mkdir /tmp/test-snap
# mount /dev/SataGroup01/test-snap /tmp/test-snap
The contents of the volumes are identical:
# ls /tmp/test
a0  a1  a2 lost+found
[root@cane test]# ls /tmp/test-snap/
a0  a1  a2 lost+found
Change them in different ways:
# mkdir /tmp/test/b0
# rm -rf  /tmp/test/a1
# mkdir /tmp/test-snap/c0
# ls /tmp/test*
/tmp/test:
a0  a2  b0  lost+found

/tmp/test-snap:
a0  a1  a2 c0  lost+found

Now unmount them:


# umount /tmp/test
# umount /tmp/test-test snap

End the experiment

If we now throw away test-snap, we'd be left with the changes done in test. If we want to back up our changes, and keep what was done in snap instead, do:

# lvconvert --merge -v /dev/SataGroup01/test-snap 
    Using logical volume(s) on command line.
    Archiving volume group "SataGroup01" metadata (seqno 41).
    Loading SataGroup01-test-real table (253:14)
    Suppressed SataGroup01-test-real (253:14) identical table reload.
    Loading SataGroup01-test--snap-cow table (253:15)
    Suppressed SataGroup01-test--snap-cow (253:15) identical table reload.
    Loading SataGroup01-test table (253:16)
    Loading SataGroup01-test--snap table (253:17)
    Not monitoring SataGroup01/snapshot0
    Suspending SataGroup01-test (253:16) with filesystem sync with device flush
    Suspending SataGroup01-test--snap (253:17) with filesystem sync with device flush
    Suspending SataGroup01-test-real (253:14) with filesystem sync with device flush
    Suspending SataGroup01-test--snap-cow (253:15) with filesystem sync with device flush
    Loading SataGroup01-test-real table (253:14)
    Suppressed SataGroup01-test-real (253:14) identical table reload.
    Loading SataGroup01-test--snap-cow table (253:15)
    Suppressed SataGroup01-test--snap-cow (253:15) identical table reload.
    Resuming SataGroup01-test-real (253:14)
    Resuming SataGroup01-test--snap-cow (253:15)
    Resuming SataGroup01-test (253:16)
    Resuming SataGroup01-test--snap (253:17)
    Creating volume group backup "/etc/lvm/backup/SataGroup01" (seqno 42).
  Merging of volume test-snap started.
    Checking progress before waiting every 15 seconds
  test: Merged: 100.0%
  Merge of snapshot into logical volume test has finished.
    Archiving volume group "SataGroup01" metadata (seqno 42).
    Removing snapshot test-snap
    Loading SataGroup01-test table (253:16)
    Loading SataGroup01-test--snap table (253:17)
    Suspending SataGroup01-test (253:16) with device flush
    Suspending SataGroup01-test--snap (253:17) with device flush
    Suspending SataGroup01-test--snap-cow (253:15) with device flush
    Suspending SataGroup01-test-real (253:14) with device flush
    Resuming SataGroup01-test--snap-cow (253:15)
    Resuming SataGroup01-test-real (253:14)
    Resuming SataGroup01-test (253:16)
    Removing SataGroup01-test-real (253:14)
    Removing SataGroup01-test--snap (253:17)
    Removing SataGroup01-test--snap-cow (253:15)
    Releasing logical volume "test-snap"
    Creating volume group backup "/etc/lvm/backup/SataGroup01" (seqno 44).
  Logical volume "test-snap" successfully removed

We have kept the changes originally in the snapshot volume (which as been removed by lvconvert); a1 has come back, b0 is gone, c0 - from test-snap - is now in place:

# ls  /tmp/test/ /tmp/test/a1
/tmp/test/:
a0  a1  a2 c0  lost+found

/tmp/test/a1:
b1