Working with LVM
LVM (Logical Volume Manager) is a disk management system that adds an abstraction layer above the physical storage. It allows flexible allocation of disk space, online resizing, and snapshot-based backups, and is widely used as the storage layer for virtualization. On encrypted systems, LVM is often placed on top of a LUKS-encrypted device, so that a single unlock exposes the whole volume group.
This article covers installing LVM on Linux, creating physical volumes, volume groups, and logical volumes, resizing them, working with snapshots, and using thin provisioning.
Installing LVM
LVM is included in most Linux distributions by default. If it is missing, install the lvm2 package with the system package manager.
On Debian and Ubuntu:
sudo apt-get install lvm2
On RHEL, CentOS Stream, AlmaLinux, and Rocky Linux:
sudo dnf install lvm2
Creating a physical volume
A physical volume (PV) is the lowest-level LVM building block. It can be a whole disk (for example, /dev/sdb) or a single partition (for example, /dev/sdb1).
Using a whole disk as a PV keeps later resize operations simpler, because there is no underlying partition to grow first. Using a partition is preferred when the disk also has to host non-LVM data, or when other tools on the system expect a partition table.
Create a physical volume with pvcreate:
sudo pvcreate /dev/sdb
Replace /dev/sdb with the path to your block device.
Check the result with pvdisplay:
sudo pvdisplay
The output lists the physical volumes that LVM currently manages, with size and volume group information for each.
Creating a volume group
A volume group (VG) combines one or more physical volumes into a single pool of storage. Logical volumes are carved out of this pool.
Create a volume group named vg0 from a single physical volume:
sudo vgcreate vg0 /dev/sdb
Or from several physical volumes at once:
sudo vgcreate vg0 /dev/sdb /dev/sdc
Check the result with vgdisplay:
sudo vgdisplay
Creating a logical volume
A logical volume (LV) appears to the system as a regular block device. You can format it with a file system and mount it.
Create a logical volume lv0 of 10 GB inside the volume group vg0:
sudo lvcreate -n lv0 -L 10G vg0
The -n flag sets the name of the logical volume, and -L sets its size.
Check the result with lvdisplay:
sudo lvdisplay
Create a file system on the logical volume:
sudo mkfs.ext4 /dev/vg0/lv0
Create a mount point and mount the file system:
sudo mkdir -p /mnt/lv0 sudo mount /dev/vg0/lv0 /mnt/lv0
The new file system is now available under /mnt/lv0. To mount it automatically at boot, add a matching entry to /etc/fstab.
LVM exposes every logical volume under two equivalent paths: /dev/<vg>/<lv> and /dev/mapper/<vg>-<lv>. For the example above this is /dev/vg0/lv0 and /dev/mapper/vg0-lv0. Both paths point to the same device; tools and configuration files may use either one.
To see the full PV/VG/LV hierarchy alongside regular block devices, run:
lsblk
Resizing volumes
LVM supports online resizing at every layer: physical volumes, volume groups, and logical volumes.
pvresize updates LVM's view of a physical volume after the underlying block device has been resized (for example, after a virtual disk has been grown on the hypervisor):
sudo pvresize /dev/sdb
vgextend adds a physical volume to an existing volume group, which is how a volume group is enlarged:
sudo vgextend vg0 /dev/sdc
vgreduce removes a physical volume from a volume group:
sudo vgreduce vg0 /dev/sdc
lvresize changes the size of a logical volume. For example, to add 5 GB to lv0:
sudo lvresize -L +5G /dev/vg0/lv0
Or to extend the logical volume to use all free space in the volume group:
sudo lvresize -l +100%FREE /dev/vg0/lv0
Note the difference between -L (uppercase) and -l (lowercase). The uppercase version takes a size with a unit suffix such as M, G, or T. The lowercase version takes a number of extents or a percentage.
Resizing a logical volume does not resize the file system on it. Use the matching tool for the file system. For ext2, ext3, and ext4:
sudo resize2fs /dev/vg0/lv0
For XFS, run xfs_growfs against the mount point of the file system.
On supported file systems (including ext4 and XFS), lvextend with the -r flag resizes the logical volume and the file system in one step:
sudo lvextend -r -L +5G /dev/vg0/lv0
This is the most common form for online growth.
Shrinking a logical volume is the opposite order: the file system must be shrunk first, and only then the logical volume. Doing it the other way around truncates the underlying device while the file system still thinks it has the original size, which destroys data. For ext4, the operation is offline. Unmount the file system, run sudo e2fsck -f /dev/vg0/lv0, shrink the file system with sudo resize2fs /dev/vg0/lv0 <new_size>, shrink the logical volume to the same size with sudo lvresize -L <new_size> /dev/vg0/lv0, then mount the file system again. XFS does not support shrinking at all; the only way to make an XFS file system smaller is to back it up, create a smaller one, and restore the data.
Every command above accepts --help for the full list of options.
LVM snapshots
A snapshot captures the state of a logical volume at a specific point in time. It works through a copy-on-write mechanism: as the original logical volume changes, the modified blocks are saved into the snapshot's reserved space, so the snapshot keeps showing the original state.
Snapshots are useful for taking crash-consistent backups of a running file system, and for testing changes that can be rolled back by discarding the snapshot. Application-consistent backups require additional coordination, such as freezing the file system or quiescing the application before the snapshot is taken.
Creating a snapshot
Create a snapshot with lvcreate and the -s flag:
sudo lvcreate -L 1G -s -n myvolume_snap /dev/myvg/myvolume
This creates a snapshot named myvolume_snap of the logical volume myvolume in the volume group myvg, with 1 GB reserved for changes. Pick the reserved size based on how much data is expected to change while the snapshot exists: snapshots of mostly idle volumes need little space, while heavily written volumes may need a substantial fraction of the original size.
For long-lived snapshots and for use cases that involve many of them, consider thin snapshots inside a thin pool. They draw their space from the shared pool on demand instead of reserving a fixed amount up front, which is usually more space-efficient.
If the original logical volume changes more than the snapshot can hold, the snapshot becomes invalid and the data it captured is lost. Size the snapshot to cover the expected amount of change during its lifetime.
Using a snapshot
A snapshot can be mounted like any other logical volume. For backup and inspection workflows, mount it read-only unless write access is actually required:
sudo mkdir -p /mnt/snapshot sudo mount -o ro /dev/myvg/myvolume_snap /mnt/snapshot
Once mounted, the snapshot can be read for backup or inspection.
Removing a snapshot
When the snapshot is no longer needed, remove it with lvremove:
sudo lvremove /dev/myvg/myvolume_snap
Removing a snapshot frees the space it reserved. Any data written to the snapshot itself (rather than to the original volume) is lost.
To roll the original volume back to the state captured by the snapshot, use lvconvert --merge instead of lvremove:
sudo lvconvert --merge /dev/myvg/myvolume_snap
After the merge, the snapshot is consumed and removed automatically. If the original volume is currently in use, the merge is deferred until the next time the volume is activated.
Thin provisioning
A thin pool is a special kind of logical volume that allocates storage on demand. Logical volumes carved out of it (thin volumes) can be created with a declared size that exceeds the actual free space in the pool, and only the blocks that are written consume real storage.
This is widely used in virtualization, where many virtual disks share a single backing pool but rarely all reach their declared capacity at the same time.
Creating a thin pool
Create a thin pool mythinpool of 50 GB in the volume group myvg:
sudo lvcreate -L 50G -T -n mythinpool myvg
The -L flag sets the pool size, -T tells lvcreate to create a thin pool, and -n sets the pool name. LVM allocates the pool from the volume group's free space; specific physical volumes can be listed at the end of the command if the pool has to be placed on particular devices.
Creating a thin volume
Create a thin volume mythinvolume of 10 GB inside mythinpool:
sudo lvcreate -V 10G -T myvg/mythinpool -n mythinvolume
The -V flag sets the virtual size of the thin volume, -T references the thin pool, and -n sets the name of the new volume.
Using a thin volume
A thin volume is used like any other logical volume. Create a file system on it:
sudo mkfs.ext4 /dev/myvg/mythinvolume
After that the thin volume can be mounted and used as a regular block device.
Because thin pools can be over-committed, monitor the actual usage of the pool. Both data space and metadata space can be exhausted independently, and either one is critical: if a thin pool runs out of data space or metadata space while a thin volume is being written to, write operations to that volume will start failing.
The current data and metadata usage of every logical volume, including thin pools, can be inspected with lvs:
sudo lvs -o +data_percent,metadata_percent
When either data_percent or metadata_percent approaches 100, extend the thin pool with lvextend before it fills up.
Command reference
Common LVM commands grouped by layer.
Physical volumes:
- pvcreate initializes a block device as a physical volume.
- pvdisplay shows detailed information about physical volumes.
- pvs shows a compact summary table of physical volumes.
- pvresize updates a physical volume after the underlying device has been resized.
Volume groups:
- vgcreate creates a volume group from one or more physical volumes.
- vgextend adds a physical volume to a volume group.
- vgreduce removes a physical volume from a volume group.
- vgdisplay shows detailed information about volume groups.
- vgs shows a compact summary table of volume groups.
Logical volumes:
- lvcreate creates a logical volume.
- lvextend and lvresize change the size of a logical volume.
- lvremove removes a logical volume.
- lvconvert --merge merges a snapshot back into its origin volume.
- lvdisplay shows detailed information about logical volumes.
- lvs shows a compact summary table of logical volumes.
For daily use, the short summary commands pvs, vgs, and lvs are usually more convenient than the verbose *display variants. Each command accepts --help for the full list of options.