Linux LVM Cheatsheet

What is this page?

This article is a "cheat sheet" for LVM2 (Logical Volume Manager), a storage management system which is commonly used on Linux machines for much more flexible "partitioning".

In this cheatsheet, you'll find examples for viewing, creating, and modifying LVM2 volumes, including thin pools and snapshots.

This is NOT intended to be an in-depth explanation on using LVM2 - this article is aimed at those who already have at least some basic knowledge of using LVM. It's simply some of the most common commands summarised with clear examples on how to do certain things.

Viewing physical volumes, volume groups, and logical volumes

Show physical volumes:

root@host ~ # pvs
PV         VG   Fmt  Attr PSize   PFree
/dev/sdb1       lvm2 ---  <20.00g <20.00g
/dev/sdc1  vghd lvm2 a--  142.14g   1.00g

Show volume groups:

root@host ~ # vgs
VG   #PV #LV #SN Attr   VSize   VFree
vghd   1   3   0 wz--n- 142.14g 1.00g

Show logical volumes:

root@host ~ # lvs
LV       VG   Attr       LSize   Pool   Origin Data%  Meta%  Move Log Cpy%Sync Convert
dogecoin vghd Vwi-aotz-- 100.00g lvthin        38.35
lvthin   vghd twi-aotz-- 140.00g               85.81  48.93
monero   vghd Vwi-aotz-- 100.00g lvthin        81.79

Extending thin pools / increase metadata:

# Increase the size of the thin pool
root@host ~ # lvextend -L+100G vghd/lvthin

Size of logical volume vghd/lvthin_tdata changed from 140.00 GiB 
(35840 extents) to 240.00 GiB (61440 extents).
   Logical volume vghd/lvthin_tdata successfully resized.

# Extend metadata (notice above that 48% metadata used)
root@host ~ # lvextend --poolmetadatasize +1G vghd/lvthin

Size of logical volume vghd/lvthin_tmeta changed from 72.00 MiB 
(18 extents) to 1.07 GiB (274 extents).
   Logical volume vghd/lvthin_tmeta successfully resized.

Extending logical volumes, and automatically resize the underlying filesystem:

# Extend vghd/monero - the option '-r' will automatically run the appropriate
# filesystem resizing tool such as 'resize2fs' or 'xfs_growfs' on the volume :)

root@host ~ # lvextend -L+80G -r vghd/monero

Size of logical volume vghd/monero changed from 100.00 GiB (25600 extents) 
to 180.00 GiB (46080 extents).
  Logical volume vghd/monero successfully resized.

resize2fs 1.44.1 (24-Mar-2018)
Filesystem at /dev/mapper/vghd-monero is mounted on /blockchains/monero; 
on-line resizing required
old_desc_blocks = 13, new_desc_blocks = 23
The filesystem on /dev/mapper/vghd-monero is now 47185920 (4k) blocks long.

Setting up an LVM, creating a thin pool, creating a thin volume, and handling thin volumes

Make sure thin-provisioning-tools is installed

WARNING: For freshly installed Ubuntu/Debian systems, you MUST install thin-provisioning-tools

You will encounter various strange errors trying to manage thin pools if you don't have thin-provisioning-tools installed.

If in doubt, try to install the package via your package manager:

user@host ~ $ sudo su -
root@host ~ # apt update -y
root@host ~ # apt install -y thin-provisioning-tools

Convert sda into an lvm "physical volume":

pvcreate /dev/sda

Create volume group called vg0

vgcreate vg0 /dev/sda

Create a 130G thin pool called lvthin on vg0

lvcreate --type thin-pool -L 130G --thinpool lvthin vg0

Create a 100G thin volume named myvol on thin pool lvthin using volgroup vg0

lvcreate -V 100G --thinpool lvthin -n myvol vg0

Expand the size of thin pool 'lvthin' by 1G

lvextend -L+1G vg0/lvthin

Use 100% of available space (lower case l (L))

lvcreate -l 100%FREE -n myvol vg0

Increase / expand thin pool metadata (the meta column displayed by lvs)

lvextend --poolmetadatasize +2G vg0/lvthin

Using LVM2 snapshots

Review your existing volumes

First run lvs to get an overview of your LVM volumes, such as their names, and which VG (Volume Group) they're located on.

root@host ~ # lvs

  LV         VG     Attr       LSize   Pool     Origin Data%  Meta%  Move Log Cpy%Sync Convert
  btrfs_data vgdata Vwi-aotz--  45.00g thindata        49.39
  docker     vgdata Vwi-aotz--  30.00g thindata        34.34
  thindata   vgdata twi-aotz-- 120.00g                 27.11  1.51
  dogecoin   vghd   Vwi-aotz-- 100.00g lvthin          41.12
  lvthin     vghd   twi-aotz-- 240.00g                 54.89  4.31
  monero     vghd   Vwi-aotz-- 180.00g lvthin          50.35

Create a snapshot

To create a snapshot for the existing volume dogecoin (located on VG vghd), we'd run:

 root@host ~ # lvcreate -s -n dogecoin_snap25mar vghd/dogecoin

    Using default stripesize 64.00 KiB.
    Logical volume "dogecoin_snap25mar" created.

Confirm the snapshot was created

If we now run lvs you should see the snapshot:

  LV                 VG     Attr       LSize   Pool     Origin   Data%  Meta%  Move Log Cpy%Sync Convert
  btrfs_data         vgdata Vwi-aotz--  45.00g thindata          46.47
  docker             vgdata Vwi-aotz--  30.00g thindata          34.34
  thindata           vgdata twi-aotz-- 120.00g                   26.01  1.49
  dogecoin           vghd   Vwi-aotz-- 100.00g lvthin            39.24
  dogecoin_snap25mar vghd   Vwi---tz-k 100.00g lvthin   dogecoin
  lvthin             vghd   twi-aotz-- 240.00g                   54.06  4.28
  monero             vghd   Vwi-aotz-- 180.00g lvthin            50.27

Force activate the snapshot if needed

You may notice in the previous lvs output, the dogecoin snapshot was missing it's data usage percentage, and was also missing the a flag in it's attributes. This meant it was deactivated and could not be mounted.

First, try to activate the snapshot volume using lvchange:

root@host ~ # lvchange -v -a y vghd/dogecoin_snap25mar
  ACTIVATION_SKIP flag set for LV vghd/dogecoin_snap25mar, skipping activation.

If you get the ACTIVATION_SKIP flag set error, we'll need to force LVM to activate the volume, by adding the -K flag.

root@host ~ # lvchange -v -K -a y vghd/dogecoin_snap25mar
  Activating logical volume vghd/dogecoin_snap25mar exclusively.
  activation/volume_list configuration setting not defined: Checking only host tags for vghd/dogecoin_snap25mar.
  ...
  Creating vghd-dogecoin_snap25mar
  Loading vghd-dogecoin_snap25mar table (253:12)
  Resuming vghd-dogecoin_snap25mar (253:12)
  vghd/lvthin already monitored.

Let's run lvs again to confirm it was activated:

root@host ~ # lvs
  LV                 VG     Attr       LSize   Pool     Origin   Data%  Meta%  Move Log Cpy%Sync Convert
  dogecoin           vghd   Vwi-aotz-- 100.00g lvthin            39.24
  dogecoin_snap25mar vghd   Vwi-a-tz-k 100.00g lvthin   dogecoin 39.24

As we can see the a attribute within it's Attr column, we're good to mount it.

Mount the snapshot

Just like any other LVM volume, we can mount the snapshot onto any folder. Below, we mount the snapshot onto /snapshot/dogecoin, and we do an ls -la to confirm that the snapshot worked correctly.

root@host ~ # mkdir -p /snapshot/dogecoin
root@host ~ # mount -v /dev/vghd/dogecoin_snap25mar /snapshot/dogecoin
mount: /dev/mapper/vghd-dogecoin_snap25mar mounted on /snapshot/dogecoin.

root@host ~ # ls -la /snapshot/dogecoin
drwxrwxr-x 5 dogecoin dogecoin  4096 Mar 25 19:47 .dogecoin
-rwx------ 2 dogecoin dogecoin   106 Jul 23  2019 dogecoin.conf

HELP! I can't mount my XFS snapshot!?

(NOTE: Original commands sourced from RedHat Learning)

If you've snapshotted a volume which was formatted using the XFS Filesystem, you'll probably get an error that looks like this when you try and mount it:

root@host ~ # mount -t xfs /dev/vg0/my_snapshot /snapshot/my_ss
    mount: /snapshot/my_ss: wrong fs type, bad option, bad 
    superblock on /dev/mapper/vg0-my_snapshot, missing codepage 
    or helper program, or other error.

Don't worry, it can be fixed. It's caused by the snapshot having the same label and/or UUID as the original volume, causing XFS to believe it's already mounted.

Option 1. Mount the filesystem with UUIDs disabled

If you only need to mount the snapshot temporarily, then you can simply disable the use of UUIDs while mounting. For longer term usage of a mounted snapshot, you should use Option 2 which is a permanent fix.

mount -v -o nouuid -t xfs /dev/vg0/my_snapshot /snapshot/my_ss

Option 2. Clear the XFS log and regenerate the UUID

We use xfs_repair to zero the filesystem journal (ensures there's no old references to the original filesystem), as well as detecting / fixing any integrity errors.

root@host ~ # xfs_repair -L /dev/mapper/vg0-my_snapshot
    Phase 1 - find and verify superblock...
        - reporting progress in intervals of 15 minutes
    Phase 2 - using internal log
            - zero log...
    ALERT: The filesystem has valuable metadata changes in a log which is being
    destroyed because the -L option was used.

After we've repaired the filesystem, we use xfs_admin to regenerate the UUID, allowing it to be mounted successfully:

root@host ~ # xfs_admin -U $(uuidgen) /dev/mapper/vg0-my_snapshot
Clearing log and setting UUID
writing all SBs
new UUID = ce81b4d1-2f7f-4096-8cd2-2e9c62d9f98d

Hopefully, your snapshot should now be mountable, like so:

root@host ~ # mount -v -t xfs /dev/vg0/my_snapshot /snapshot/my_ss
mount: /dev/mapper/vg0-my_snapshot mounted on /snapshot/my_ss

Removing a snapshot

Unmount the snapshot if it's currently mounted

root@host ~ # umount /snapshot/dogecoin

For safety, you may wish to deactivate the snapshot volume - this may warn you if you've got any leftover mounts of the snapshot:

root@host ~ # lvchange -v -a n vghd/dogecoin_snap25mar
  Deactivating logical volume vghd/dogecoin_snap25mar.
  Removing vghd-dogecoin_snap25mar (253:12)

Finally, let's remove the snapshot. We can delete it just like any other LVM volume, using lvremove:

root@host ~ # lvremove vghd/dogecoin_snap25mar
Do you really want to remove and DISCARD logical volume vghd/dogecoin_snap25mar? [y/n]: y
  Logical volume "dogecoin_snap25mar" successfully removed

Thin Pools during boot

If you have /boot or your root filesystem / stored within an LVM thin pool, you may find that Grub / Linux will fail to boot and throw various errors trying to mount your volumes.

Below is a solution which should allow LVM thin pools to work during the boot process.

The solution has been tested by Privex on Ubuntu 16.04, 18.04, as well as certain Debian versions with varying success rates.

Original source: https://bugs.launchpad.net/ubuntu/+source/lvm2/+bug/1539934/comments/2

I found a temporary solution that seems ok for now.

This article walks through the addition of an initramfs hook to add the necessary kernel modules and and executables to the initramfs image so that the boot process can deal with lvm thinpools and thinvolumes.

http://askubuntu.com/questions/673815/how-do-i-start-my-laptop-with-root-partition-on-lvm2-thin-pool

First, create the file /etc/initramfs-tools/hooks/thin-provisioning-tools

#!/bin/sh
PREREQ="lvm2"
prereqs()
{
        echo ""
}
case $1 in
prereqs)
        prereqs
        exit 0
        ;;
esac
. /usr/share/initramfs-tools/hook-functions
copy_exec /usr/sbin/thin_check
copy_exec /usr/sbin/thin_dump
copy_exec /usr/sbin/thin_repair
copy_exec /usr/sbin/thin_restore
copy_exec /sbin/dmeventd
manual_add_modules dm_thin_pool

Then update the initramfs image:

root@host ~ # chmod 755 /etc/initramfs-tools/hooks/thin-provisioning-tools
root@host ~ # update-initramfs -u

NOTE: On some systems the command might be update-initramfs-tools instead.

After reboot, things should work as expected.