Commit or revert a Linux LVM snapshot?

Solution 1:

I just tried a snapshot-based upgrade with Ubuntu. And yeah, I needed to reboot several times. First rename the original root-lv to something else, so you can give the snapshot the original name (since an upgrade creates a lot of change and changes are faster on the snapshot than on the original):

 # lvrename lvm root root-old
 # lvcreate -n root -s lvm/root-old -L 10G

The size should be chosen appropriately. Then reboot, so the 'new' lvm/ubuntu gets mounted as root and you can perform the upgrade. Now you can test the new version and even change to the old system by

 # lvrename lvm root root-new
 # lvrename lvm root-old root
 # reboot

If you want to drop the upgrade, just run (from the old system)

# lvremove lvm/root-new

If you want to commit the changes, just run (from the old system)

# lvconvert --merge lvm/root-new

or, from the new system

# lvrename lvm root root-new
# lvconvert --merge lvm/root-new
# lvrename lvm root-old root

followed by a reboot. The system will refuse to do the merge right away, since the volumes are open. So the merge will be started during the boot and continued while you already can work with the system.

Oh, and by the way: When changing between the systems, remember to use the appropriate kernel. Since /boot is not part of lvm, the old and new kernels would be placed there side-by-side.

Solution 2:

Ok, I think I have it figured out from re-reading the HOWTO 3.8.

  • Read-only snapshots (like LVM1) contain the block-level differences after the snapshot creation - the original still gets changed, but the snapshot retains a representation of the original. Reading from the snapshot presents the data as it appeared at that time.
  • Read-write snapshots (default in LVM2) can be written to: they're a fork of the original partition. Writing to the snapshot doesn't change the original.

The way a snapshot works is a block-level set of changes from the original. So, when the original is written to, the following things happen:

  1. Something tries to write to the original.
  2. Original gets read, and the blocks from the original are copied to the snapshot.
  3. Original gets changed.
  4. Snapshot contains the "reverse-differences" - the changes that make the original look like it did when the snapshot was created.

So, throwing away the snapshot won't affect the original at all - because the original has been changed, and the snapshot just contained a list of those changes.

Answering my own question:

Create a new snapshot with LVM. If the update can be configured to write to the snapshot mount point, use a R/W snapshot. Otherwise, either RO or R/W will do.

Then:

  • If writing to the R/W snapshot mount point, commit by writing the snapshot to the original, and revert by throwing away the snapshot.
  • If writing to the original mount point, commit by throwing away the snapshot, and revert by writing from the snapshot to the original.

I still haven't found a tool specifically to perform this merge - and, given that my scenario isn't exactly the intended use of snapshots, there may not be one. It sounds like a job for rdiff.


Solution 3:

LVM2 / device mapper snapshots merge functionality is available if you are running Linux 2.6.33+ and using LVM 2.0.58+:

lvconvert --merge

See this post: http://www.jonnor.com/2010/02/lvm-snapshot-merging-avaliable/

It references http://kernelnewbies.org/Linux_2_6_33 (look at section 5, MD/DM) and LVM changelog at 2.0.58: ftp://sources.redhat.com/pub/lvm2/WHATS_NEW

But I can't tell you yet how to use it properly ;-)


Solution 4:

LVM works at the block level. It even 'doesn't know' what a filesystem is. So you cannot snapshot only certain directories, unless a file system from a different LVM volume is mounted there.

When you make an LVM snapshot you actually request 'copy on write' duplicate of a volume. Any block that would be changed on the snapshotted volume will be stored unmodified in the snaphot first. So to 'commit changes' you don't have to do anything. Just remove the snapshot volume.

I don't quite know what is the recommended way to 'revert changes', as I never used LVM in such scenario, but I guess it described well in the LVM documentation somewhere. Whatever it is you will probably need to restart anything that was changed, a reboot might be a good idea.


Solution 5:

  1. There is no reason to merge some. Just remove snapshot, source LV stay changed
  2. Merge needed to revert changes lvconvert --merge <snapshot name>
  3. LVM works with block devices. Any FS-related changes should be done by special utilities (xfs_growfs, e2fsck, ...) according to FS type

Snapshot 'freeze' original LV's state. Remove snapshot means forget that state. Merge snapshot means return to that state

But inside LVM it saves rewritten data in snapshot: be sure that snapshot size meet expected amount of changes on LV and snapshot