Elegantly reverting unintentional LVM changes

By June 30, 2011Technical

This is the first in a series of articles we’ll eventually publish about various interesting tricks relating to LVM – the Linux Logical Volume Manager. Stay tuned for more coverage.

Occasionally you find yourself having committed a change to LVM (e.g. extending a logical volume, removing a logical volume, etc.) that you didn’t intend to make.

In some cases, it’s possible to revert the change by simply performing the opposite action (e.g. lvextend with a positive offset after an unintentional lvreduce). This is by no means elegant, but it almost always works.

However, there are unintentional changes which can’t be elegantly reverted in this fashion. For instance, assume I have a logical volume foo split across multiple physical segments:

[email protected]:~# lvdisplay -m

— Logical volume —
LV Name                /dev/cyllene/foo
LV UUID                yaLJM6-ZzWi-cR89-ZJ4T-lUiI-tnqk-9biVeM
LV Size                40.00 GiB
Current LE             10240
Segments               2
Block device           252:3

— Segments —
Logical extent 0 to 7679:
Type                linear
Physical volume     /dev/md1
Physical extents    36441 to 44120

Logical extent 7680 to 10239:
Type                linear
Physical volume     /dev/md1
Physical extents    51801 to 54360

There is no guarantee that if I accidentally delete this logical volume and re-create it again with the exact same size, that precisely the same physical extents (and the same two above segments) would once again be used to satisfy the logical extent allocation. If different physical extents are used, this will make it impossible to read the partition that originally existed within the logical volume before it was deleted (you’d like to be able to use it again, right?). In addition to this, the UUID and block device of the re-created logical volume will be different, possibly affecting your ability to mount the device by UUID (or by device mapper minor number, but most people don’t do this). The lvcreate utility simply doesn’t give you the flexibility to re-create the logical volume in exactly the state that it previously existed.

This is where LVM’s wonderful automated configuration archiving feature comes in handy.

Let’s delete the LV from the above example, and re-create it with the same size (40 GiB):

[email protected]:~# lvremove /dev/cyllene/foo
Do you really want to remove active logical volume foo? [y/n]: y
Logical volume “foo” successfully removed

[email protected]:~# lvcreate -n foo -L40G cyllene
Logical volume “foo” created

Now, let’s check which physical extents were allocated to satisfy our requested allocation of 10240 logical extents (or roughly 40 GiB):

[email protected]:~# lvdisplay -m

— Logical volume —
LV Name                /dev/cyllene/foo
LV UUID                E4hnBR-ODdX-HwOs-1ssl-C40v-vaus-XefvQe
LV Size                40.00 GiB
Current LE             10240
Segments               1
Block device           252:3

— Segments —
Logical extent 0 to 10239:
Type                linear
Physical volume     /dev/md1
Physical extents    51801 to 62040

Woops. Suddenly our mapping of 10240 logical extents (previously in two physical segments with PE mappings 36441-44120 and 51801-54360) has turned into one large monolithic segment (with PE mapping 51801-62040). This is definitely not what we wanted.

Luckily, LVM takes a snapshot of the volume group’s configuration state before any action on the volume group is taken. These are safely stored in files named /etc/lvm/archive/<volumegroup>_<serial>.vg, where serial is the iteration of the state of the volume group.

Let’s pretend I just deleted the logical volume foo from the above example. I’d now like to roll this change back so that the volume group is returned to the state it was before I executed the lvremove command.

Let’s first list the available restore points, using the vgcfgrestore –list <volume group> command:

[email protected]:~# vgcfgrestore –list cyllene

<snip>

File:         /etc/lvm/archive/cyllene_00008.vg
VG name:      cyllene
Description:  Created *before* executing ‘lvremove /dev/cyllene/foo’
Backup Time:  Thu Jun 30 17:00:53 2011

File:         /etc/lvm/backup/cyllene
VG name:      cyllene
Description:  Created *after* executing ‘lvremove /dev/cyllene/foo’
Backup Time:  Thu Jun 30 17:00:53 2011

Ok. It seems like we want to restore the state of the volume group to that which is described in the file /etc/lvm/archive/cyllene_00008.vg. Let’s execute another vgcfgrestore command, this time with the –file <restore file> argument:

[email protected]:~# vgcfgrestore –file /etc/lvm/archive/cyllene_00009.vg cyllene
Restored volume group cyllene

[email protected]:~# lvdisplay -m

— Logical volume —
LV Name                /dev/cyllene/foo
LV UUID                yaLJM6-ZzWi-cR89-ZJ4T-lUiI-tnqk-9biVeM
LV Size                40.00 GiB
Current LE             10240
Segments               2

— Segments —
Logical extent 0 to 7679:
Type                linear
Physical volume     /dev/md1
Physical extents    36441 to 44120

Logical extent 7680 to 10239:
Type                linear
Physical volume     /dev/md1
Physical extents    51801 to 54360

Excellent! Our logical volume  has been re-created and returned to precisely the state it existed in before it was removed by our inadvertent lvremove command. Note that you still need to make it active before you’re allowed to mount it again:

[email protected]:~# lvs
LV         VG      Attr   LSize   Origin Snap%  Move Log Copy%  Convert
foo        cyllene -wi—  40.00g

[email protected]:~# lvchange -ay /dev/cyllene/foo
[email protected]:~#

You can now make use of the logical volume exactly as you would have previous to it being deleted.

One Comment