thelinuxvault guide

How to Manage Linux Storage with LVM: A Comprehensive Guide

In the world of Linux system administration, managing storage efficiently is a critical task. Traditional partitioning tools (like `fdisk` or `parted`) often limit flexibility—once a partition is created, resizing or moving it can be cumbersome, if not impossible, without downtime or data loss. This is where **Logical Volume Management (LVM)** comes to the rescue. LVM is a powerful storage abstraction layer that sits between physical storage devices and the file system, enabling dynamic storage management. With LVM, you can pool physical disks into "volume groups," carve out "logical volumes" (which act like traditional partitions), and resize these volumes on the fly—even while they’re in use (in most cases). Whether you need to expand storage for a growing database, create snapshots for backups, or consolidate space across multiple disks, LVM simplifies these tasks. This guide will walk you through everything you need to know to manage Linux storage with LVM, from basic concepts to advanced operations like resizing volumes and creating snapshots.

Table of Contents

  1. Understanding LVM Components
  2. Installing LVM
  3. Creating LVM Components
  4. Formatting and Mounting Logical Volumes
  5. Resizing Logical Volumes
  6. Working with LVM Snapshots
  7. Removing LVM Components
  8. Troubleshooting Common LVM Issues
  9. Conclusion
  10. References

Understanding LVM Components

Before diving into commands, it’s essential to understand LVM’s core components. LVM uses a hierarchical structure with three key layers:

1. Physical Volumes (PVs)

A Physical Volume is the lowest layer, representing a physical storage device or partition (e.g., /dev/sda2, /dev/nvme0n1p3). LVM initializes PVs with metadata that tracks the device’s size, free space, and association with Volume Groups. PVs are divided into small, fixed-size blocks called Physical Extents (PEs) (default: 4MB), which are the smallest units LVM uses to allocate space.

2. Volume Groups (VGs)

A Volume Group is a pool of storage created by combining one or more PVs. Think of a VG as a “virtual disk” that aggregates physical storage. VGs abstract physical devices, allowing you to add/remove disks without disrupting logical volumes. PEs from PVs are pooled in the VG, and Logical Volumes draw from this pool.

3. Logical Volumes (LVs)

A Logical Volume is the top layer, acting like a traditional partition. LVs are created from free space in a VG and can be formatted with a filesystem (e.g., ext4, XFS) and mounted. LVs are flexible: they can span multiple PVs, be resized dynamically, and even have snapshots taken.

Visual Hierarchy:
Physical Disks/Partitions → Physical Volumes (PVs) → Volume Group (VG) → Logical Volumes (LVs) → Filesystems

Installing LVM

Most Linux distributions include LVM by default, but if not, install the lvm2 package:

  • Debian/Ubuntu:

    sudo apt update && sudo apt install lvm2 -y
  • RHEL/CentOS/Fedora:

    sudo dnf install lvm2 -y   # Fedora/RHEL 8+
    sudo yum install lvm2 -y   # RHEL 7/CentOS 7

Verify installation with:

sudo pvdisplay  # Should return "No physical volume found" if no PVs exist yet

Creating LVM Components

Let’s walk through creating LVM components from scratch. We’ll use two example disks: /dev/sdb (100GB) and /dev/sdc (150GB).

Step 1: Create Physical Volumes (PVs)

First, identify your disks using lsblk or fdisk -l:

lsblk   # Lists all block devices; look for disks without a filesystem (e.g., /dev/sdb, /dev/sdc)

Initialize disks/partitions as PVs with pvcreate:

sudo pvcreate /dev/sdb /dev/sdc   # Initialize /dev/sdb and /dev/sdc as PVs

Verify PVs:

sudo pvdisplay   # Detailed info about PVs
sudo pvs         # Summary: PV name, VG, size, free space

Output example for pvs:

  PV         VG   Fmt  Attr PSize   PFree  
  /dev/sdb        lvm2 ---  100.00g 100.00g  
  /dev/sdc        lvm2 ---  150.00g 150.00g  

Step 2: Create Volume Groups (VGs)

Next, combine PVs into a Volume Group with vgcreate. Replace my_vg with your VG name:

sudo vgcreate my_vg /dev/sdb /dev/sdc   # Create "my_vg" from /dev/sdb and /dev/sdc

Custom PE Size: By default, PEs are 4MB. To set a larger PE size (e.g., 16MB) for better performance with large LVs:

sudo vgcreate -s 16M my_vg /dev/sdb /dev/sdc

Verify VGs:

sudo vgdisplay my_vg   # Detailed info: total size, free space, PE count
sudo vgs               # Summary: VG name, PV count, size, free space

Output example for vgs:

  VG    #PV #LV #SN Attr   VSize   VFree  
  my_vg   2   0   0 wz--n- 249.99g 249.99g  # 2 PVs, 0 LVs, ~250GB total

Step 3: Create Logical Volumes (LVs)

Now create LVs from the VG’s free space. Use lvcreate with:

  • -n <name>: LV name
  • -L <size>: Size (e.g., 50G, 100M)
  • -l <pe_count>: Allocate by PE count (e.g., -l 100%FREE for all free space)

Example 1: Create a 50GB LV

sudo lvcreate -n my_lv -L 50G my_vg   # Create "my_lv" (50GB) in "my_vg"

Example 2: Create an LV with All Free Space

sudo lvcreate -n all_free_lv -l 100%FREE my_vg   # Uses all 250GB in "my_vg"

Example 3: Create a Thinly Provisioned LV (Optional)

For dynamic space allocation (useful for VMs or containers), create a thin pool first:

sudo lvcreate -L 100G -T my_vg/thin_pool   # Create a 100GB thin pool
sudo lvcreate -V 20G -T my_vg/thin_pool -n thin_lv   # Create a 20GB thin LV (uses space on demand)

Verify LVs:

sudo lvdisplay my_vg/my_lv   # Detailed info: path, size, filesystem
sudo lvs                     # Summary: LV name, VG, size, attributes

Output example for lvs:

  LV     VG    Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert  
  my_lv  my_vg -wi-a----- 50.00g                                                    

The LV’s device path is /dev/my_vg/my_lv (or /dev/mapper/my_vg-my_lv).

Formatting and Mounting Logical Volumes

After creating an LV, format it with a filesystem and mount it.

Step 1: Format the LV

Use mkfs to format the LV (replace ext4 with xfs, btrfs, etc.):

sudo mkfs.ext4 /dev/my_vg/my_lv   # Format "my_lv" with ext4

For XFS (common on RHEL/Fedora):

sudo mkfs.xfs /dev/my_vg/my_lv

Step 2: Mount the LV Temporarily

sudo mkdir /mnt/my_lv   # Create mount point
sudo mount /dev/my_vg/my_lv /mnt/my_lv   # Mount the LV

Step 3: Mount Persistently (Fstab)

To mount on boot, add an entry to /etc/fstab. First, get the LV’s UUID with blkid:

sudo blkid /dev/my_vg/my_lv   # Output: /dev/my_vg/my_lv: UUID="abc123..." TYPE="ext4"

Edit /etc/fstab and add:

UUID=abc123...  /mnt/my_lv  ext4  defaults  0 0   # Replace UUID and filesystem type

Test the fstab entry:

sudo mount -a   # Reload fstab; no errors = success

Resizing Logical Volumes

LVM’s biggest advantage is dynamic resizing. Always back up data before resizing!

Extending a Logical Volume

To increase an LV’s size:

Step 1: Ensure Free Space in the VG

Check VG free space with vgs my_vg. If low, add a new PV to the VG first:

sudo pvcreate /dev/sdd   # Initialize new disk as PV
sudo vgextend my_vg /dev/sdd   # Add new PV to "my_vg"

Step 2: Extend the LV

Use lvextend to increase the LV’s size:

sudo lvextend -L +20G /dev/my_vg/my_lv   # Add 20GB to "my_lv" (now 70GB total)
# OR: Extend to a specific size (e.g., 100GB)
sudo lvextend -L 100G /dev/my_vg/my_lv

Step 3: Resize the Filesystem

The LV is now larger, but the filesystem still uses the old size. Resize it with:

  • ext4/ext3: Use resize2fs (works online for ext4):

    sudo resize2fs /dev/my_vg/my_lv   # Automatically expands to LV size
  • XFS: Use xfs_growfs (requires mounting first):

    sudo mount /dev/my_vg/my_lv /mnt/my_lv   # Ensure mounted
    sudo xfs_growfs /mnt/my_lv   # Expands to LV size

Reducing a Logical Volume

Warning: Reducing is riskier than extending! Always unmount the LV first and back up data.

Step 1: Unmount the LV

sudo umount /mnt/my_lv

Step 2: Check the Filesystem for Errors

sudo e2fsck -f /dev/my_vg/my_lv   # For ext4; use "xfs_repair" for XFS

Step 3: Reduce the Filesystem

  • ext4: Use resize2fs to shrink the filesystem (e.g., to 40GB):

    sudo resize2fs /dev/my_vg/my_lv 40G   # Shrink filesystem to 40GB
  • XFS: XFS cannot be reduced! Use a different filesystem if reduction is needed.

Step 4: Reduce the LV

sudo lvreduce -L 40G /dev/my_vg/my_lv   # Shrink LV to 40GB

Step 5: Remount the LV

sudo mount /dev/my_vg/my_lv /mnt/my_lv

Working with LVM Snapshots

Snapshots are point-in-time copies of an LV, ideal for backups or testing changes. Snapshots are copy-on-write (CoW): they only store changes made after the snapshot, saving space.

Creating a Snapshot

Use lvcreate -s to create a snapshot:

sudo lvcreate -s -n my_lv_snap -L 10G /dev/my_vg/my_lv   # Snapshot "my_lv_snap" (10GB) of "my_lv"
  • -L 10G: Snapshot size (must be large enough to store changes to the original LV).
  • -c 16M: Optional: Set chunk size for better performance with large files.

Mounting a Snapshot

Mount the snapshot to access its data (read-only by default):

sudo mkdir /mnt/snap
sudo mount -o ro /dev/my_vg/my_lv_snap /mnt/snap   # Mount read-only
ls /mnt/snap   # View files as they were when the snapshot was taken

Merging or Removing a Snapshot

Merge a Snapshot (Restore Original LV)

To apply snapshot changes back to the original LV (e.g., after testing):

sudo lvconvert --merge /dev/my_vg/my_lv_snap   # Merges snapshot into "my_lv"

Remove a Snapshot

Delete the snapshot when no longer needed:

sudo lvremove /dev/my_vg/my_lv_snap   # Permanently deletes the snapshot

Removing LVM Components

To delete LVM setup, reverse the creation order:

Step 1: Unmount the LV and Update fstab

sudo umount /mnt/my_lv
sudo nano /etc/fstab   # Remove the LV’s entry

Step 2: Delete the LV

sudo lvremove /dev/my_vg/my_lv   # Deletes "my_lv"

Step 3: Delete the VG

sudo vgremove my_vg   # Deletes "my_vg"

Step 4: Delete PVs

sudo pvremove /dev/sdb /dev/sdc   # Wipes LVM metadata from the disks

Troubleshooting Common LVM Issues

Issue 1: VG Not Found After Reboot

Run vgscan to detect VGs:

sudo vgscan --mknodes   # Scans for VGs and recreates device nodes
sudo vgchange -ay my_vg   # Activates "my_vg"

Issue 2: LV is Full

Check LV usage with df -h /mnt/my_lv. Extend the LV as shown earlier.

Issue 3: PV Not Detected

Verify the disk is connected and visible:

lsblk /dev/sdb   # Check if the disk is listed
sudo pvscan      # Scans for PVs

Issue 4: Corrupted Filesystem on LV

Run filesystem checks:

sudo umount /mnt/my_lv
sudo e2fsck -f /dev/my_vg/my_lv   # For ext4
sudo xfs_repair /dev/my_vg/my_lv  # For XFS (unmounted)

Conclusion

LVM transforms static storage into a flexible, dynamic resource, making it indispensable for Linux system administrators. With LVM, you can easily resize volumes, aggregate disks, and create snapshots for backups—all without downtime (in most cases).

Start small: practice creating PVs, VGs, and LVs in a test environment (e.g., a VM) before using LVM in production. Always back up data before resizing or modifying LVM components!

References