3.5 LVM from the Start: Planning Flexible Storage
Right, let’s talk about LVM. You might be tempted to just click “Use Entire Disk” and call it a day. I get it. It’s easy. But easy is for people who enjoy reinstalling their OS from scratch when they run out of space on / while /home is sitting on a half-empty drive. We are not those people. LVM—Logical Volume Management—is your ticket out of that particular circus. Think of it as storage with a undo button and a stretchy waistband. It lets you abstract your actual physical disks (hard drives, SSDs, whatever) into a flexible pool of storage that you can carve up, resize, and move around on the fly. It’s one of those things that, once you get used to it, you’ll wonder how you ever lived without it. The goal here is to set it up correctly from the beginning, so your future self will send you a thank-you note.
The Core Concepts: PVs, VGs, and LVs (The Alphabet Soup)
LVM has three simple, hierarchical concepts you need to grind into your brain. It’s not magic, it’s just labels.
- Physical Volumes (PVs): This is the raw stuff. It’s a hard drive, a partition, or even a loop device. You take this block of storage and you initialize it for use by LVM. We use
pvcreatefor this. It’s basically telling LVM, “Hey, you can use this.” - Volume Group (VG): This is your storage pool. You toss one or more Physical Volumes into this pool. The VG’s total size is the sum of all the PVs you put in it. This is the abstraction layer that makes everything else possible. You create this with
vgcreate. - Logical Volumes (LVs): This is what you actually use. You create these within the Volume Group. This is what gets formatted with a filesystem (like ext4 or XFS) and then mounted to
/home,/var, etc. You create these withlvcreate. The key here is that an LV isn’t tied to a specific physical disk; it just draws from the big pool of space you created.
So the data flow is always: Physical Disk -> Partition -> Physical Volume (PV) -> Volume Group (VG) -> Logical Volume (LV) -> Filesystem -> Mount Point.
Planning Your Partition Scheme
Before you even boot the installer, think. What physical disks do you have? Let’s say you have a fast 256GB NVMe SSD (/dev/nvme0n1) and a slower 2TB HDD (/dev/sda). The sane thing to do is put your root (/) and boot (/boot) filesystems on the fast SSD and your bulk data (/home) on the big HDD. But with LVM, you can make this even smarter.
We’ll create one big VG that contains both disks. Then we can create all our LVs from that pool. Want a super-fast LV for your root? Allocate it from the SSD portion of the pool. Want a big, cheap LV for your movies? Allocate it from the HDD part. LVM will handle placing the data on the appropriate physical disk automatically. This is the real power.
A CRITICAL WARNING: Do NOT put /boot on an LVM logical volume unless it’s on a volume group stored on a partition that uses a standard partition type. Many bootloaders (especially older ones) can’t read filesystems from within LVM. The safe, boring, and correct choice is to give /boot its own dedicated, non-LVM partition (usually 512MiB to 1GiB, formatted ext4). Trust me, you don’t want to create an unbootable system for the sake of aesthetic purity.
A Practical Example: Setting Up LVM at Installation
Most modern Linux installers (Debian, Ubuntu, Fedora, etc.) have excellent graphical LVM support. But since we’re brilliant friends, we’re going to do it manually in the terminal so we understand what’s actually happening. This is typically done from the installer’s “expert” mode or a shell.
First, we partition our disks. We’ll assume a UEFI system, so we need an EFI System Partition (ESP) as well.
# Let's partition the NVMe drive. We'll create a ESP, a /boot, and a partition for LVM.
parted /dev/nvme0n1 mklabel gpt
parted /dev/nvme0n1 mkpart primary fat32 1MiB 513MiB
parted /dev/nvme0n1 set 1 esp on
parted /dev/nvme0n1 mkpart primary ext4 513MiB 1537MiB
parted /dev/nvme0n1 mkpart primary 1537MiB 100%
parted /dev/nvme0n1 set 3 lvm on
# Now the HDD. We'll just make one big partition for LVM.
parted /dev/sda mklabel gpt
parted /dev/sda mkpart primary 1MiB 100%
parted /dev/sda set 1 lvm on
Now, we create our Physical Volumes. We’re using the partitions we just made.
pvcreate /dev/nvme0n1p3
pvcreate /dev/sda1
Next, we create a Volume Group named vg0 (creative, I know) and add both PVs to it.
vgcreate vg0 /dev/nvme0n1p3 /dev/sda1
Now for the fun part: carving out Logical Volumes. We’ll make a root and a swap on the fast pool (which will preferentially use the NVMe) and a home on the slow pool.
# Create a 40GB root volume
lvcreate -L 40G -n root vg0
# Create an 8GB swap volume
lvcreate -L 8G -n swap vg0
# Create a 'home' volume that uses all remaining space in the VG
lvcreate -l 100%FREE -n home vg0
Finally, format them and get them ready for the OS.
# Format the ESP and /boot
mkfs.fat -F32 /dev/nvme0n1p1
mkfs.ext4 /dev/nvme0n1p2
# Format the LVs
mkfs.ext4 /dev/vg0/root
mkfs.ext4 /dev/vg0/home
mkswap /dev/vg0/swap
Now you can mount /dev/vg0/root to /mnt, /dev/vg0/home to /mnt/home, etc., and continue with your installation. The installer’s GUI would have done all this with clicks, but now you know the incantations behind the curtain.
Why This Approach is Your Future-Proof Armor
Next week, when you realize 40GB for root was laughably optimistic, you can fix it without a single USB stick or prayer. Is the home LV on the HDD getting full? No problem. vgextend your vg0 pool with a new drive, then lvextend the home LV and resize2fs the filesystem. It’s a few commands, done live, without unmounting anything. You can snapshot LVs for consistent backups before doing something stupid. This flexibility is why every enterprise system under the sun uses LVM. It’s time your desktop learned the same tricks.