Skip to content
DBDeependra Bhatta~/notes
Linux#lvm · #virtualbox · #linux · #vagrant

Logical Volume Management (LVM) in Linux

Add a disk to a VirtualBox VM and take it through every LVM layer: partition, physical volume, volume group and logical volume, then an ext4 mount in fstab.

· updated · 8 min read
ON THIS PAGE

A file system that outgrows its partition normally means downtime: unmount, back up, repartition, restore. LVM (Logical Volume Manager) removes that constraint by placing a pool of storage between the disks and the file systems, so volumes can grow while they are mounted. This guide adds a new disk to an Ubuntu VirtualBox VM and takes it through every LVM layer to a mounted ext4 file system that survives a reboot.

Prerequisites

  • An Ubuntu VM in VirtualBox (mine was created with Vagrant) and root access.
  • The lvm2 package, which Ubuntu Server installs by default.

The problem with standard partitions

With standard partitions, each file system lives on a fixed slice of one disk. When /mnt/backup on a partition of /dev/sdb runs out of space, free space elsewhere does not help. Growing it requires unmounting the file system, backing up the data, recreating the partitions, restoring the data and mounting it again, with downtime and risk at every step.

How LVM works

LVM adds three layers between the disks and the file systems:

LVM layers: hard drives, partitions, physical volumes, a volume group datavg, and logical volumes mounted as file systems

LayerWhat it isCommands
Physical volume (PV)A disk or partition prepared for LVMpvcreate, pvs, pvdisplay
Volume group (VG)A pool of storage made from one or more PVsvgcreate, vgextend, vgs
Logical volume (LV)A "virtual partition" cut from the VG; this is what you format and mountlvcreate, lvextend, lvs

Adding capacity later follows a fixed sequence:

  1. Add a new disk.
  2. Create a partition on it (optional; LVM can also use the whole disk).
  3. Turn it into a physical volume with pvcreate.
  4. Add it to the volume group with vgextend.
  5. Grow the logical volume with lvextend.
  6. Grow the file system on it.

Every step runs while the file system stays mounted and in use.

Add a disk and create a logical volume

1. Check the current disks

Run lsblk to see the starting layout. In my lab the VM had one 64 GB disk, and the Ubuntu installer had already placed the root file system on LVM (ubuntu--vg-ubuntu--lv):

lsblk output showing disk sda with sda1, sda2 mounted on /boot, and sda3 holding the ubuntu-vg root logical volume

2. Attach a new disk in VirtualBox

Open the VM's Settings > Storage, select the SATA controller, and click the add hard disk icon:

VirtualBox Storage settings with the SATA controller selected and the add hard disk button highlighted

In the Hard Disk Selector, click Create, choose a disk file type (VMDK here), keep the default options, set a size, and attach the disk:

VirtualBox Create Virtual Hard Disk dialog with VMDK selected as the disk file type

After boot, the new disk appears as sdb in lsblk. It is absent from df -h because it has no file system and is not mounted:

lsblk showing the new 10.2G disk sdb highlighted, and df -h without any sdb entry

3. Create a partition with fdisk

Open a root shell with sudo -i (the remaining commands run as root), then open the disk in fdisk:

terminal
$ fdisk /dev/sdb

fdisk is interactive: m shows help, p prints the partition table, n creates a partition, t changes its type, and w writes the changes to disk. Create one 4 GB primary partition:

TXTPlain text
Command (m for help): p
Disk /dev/sdb: 10.19 GiB, 10943545344 bytes, 21374112 sectors
Disk model: VBOX HARDDISK
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xc79cf7d5
 
Command (m for help): n
Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-21374111, default 2048): 2048
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-21374111, default 21374111): +4G
 
Created a new partition 1 of type 'Linux' and of size 4 GiB.
 
Device     Boot Start     End Sectors Size Id Type
/dev/sdb1        2048 8390655 8388608   4G 83 Linux

Press t to change the partition type. L lists all type codes; 8e is Linux LVM:

fdisk partition type code list with 8e Linux LVM among the entries

TXTPlain text
Hex code or alias (type L to list all): 8e
Changed type of partition 'Empty' to 'Linux LVM'.
 
Device     Boot Start     End Sectors Size Id Type
/dev/sdb1        2048 8390655 8388608   4G 8e Linux LVM

Press w to write the table. lsblk now lists the partition sdb1:

lsblk output with the new 4G partition sdb1 under sdb highlighted

4. Create the physical volume

terminal
$ pvcreate /dev/sdb1
  Physical volume "/dev/sdb1" successfully created.
$ pvs
  PV         VG        Fmt  Attr PSize   PFree
  /dev/sda3  ubuntu-vg lvm2 a--  <62.00g 31.00g
  /dev/sdb1            lvm2 ---    4.00g  4.00g

/dev/sdb1 is a PV now, but it does not belong to a volume group yet.

5. Create the volume group

terminal
$ vgcreate vg0 /dev/sdb1
  Volume group "vg0" successfully created
$ vgs
  VG        #PV #LV #SN Attr   VSize   VFree
  ubuntu-vg   1   1   0 wz--n- <62.00g 31.00g
  vg0         1   0   0 wz--n-  <4.00g <4.00g

6. Create the logical volume

terminal
$ lvcreate -L 3.8G -n lv0 vg0
  Rounding up size to full physical extent 3.80 GiB
  Logical volume "lv0" created.
$ lvs
  LV        VG        Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  ubuntu-lv ubuntu-vg -wi-ao---- <31.00g
  lv0       vg0       -wi-a-----   3.80g

-L sets the size, -n names the new LV, and vg0 is the volume group that supplies the space. A leading + in the size (-L +3.8G) belongs with lvextend, where it means "add this much".

terminal
$ lsblk
NAME                      MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
sda                         8:0    0   64G  0 disk
├─sda1                      8:1    0    1M  0 part
├─sda2                      8:2    0    2G  0 part /boot
└─sda3                      8:3    0   62G  0 part
  └─ubuntu--vg-ubuntu--lv 252:0    0   31G  0 lvm  /
sdb                         8:16   0 10.2G  0 disk
└─sdb1                      8:17   0    4G  0 part
  └─vg0-lv0               252:1    0  3.8G  0 lvm

7. Create a file system

A logical volume behaves like an empty partition and needs a file system before it can be mounted. ext4 and XFS are the usual choices on Linux.

terminal
$ mkfs -t ext4 /dev/vg0/lv0
mke2fs 1.47.0 (5-Feb-2023)
Creating filesystem with 996352 4k blocks and 249488 inodes
Filesystem UUID: 3bd870c2-3150-421d-8c12-04f4690f2e39
...
Writing superblocks and filesystem accounting information: done

8. Mount the volume

terminal
$ mkdir /data
$ mount /dev/vg0/lv0 /data

The sdb part of lsblk now shows the logical volume mounted on /data:

TXTPlain text
sdb                         8:16   0 10.2G  0 disk
└─sdb1                      8:17   0    4G  0 part
  └─vg0-lv0               252:1    0  3.8G  0 lvm  /data

9. Make the mount permanent

A manual mount does not survive a reboot. Add the volume to /etc/fstab to mount it at every boot:

TXTfstab
etcfstab
/dev/vg0/lv0 /data ext4 defaults 0 0
FieldValueMeaning
1/dev/vg0/lv0The device (a path, or UUID=... from blkid)
2/dataMount point
3ext4File system type
4defaultsMount options, such as ro, rw or noexec
50Whether the old dump backup tool should back it up (normally 0)
60fsck check order at boot: 0 never, 1 the root file system, 2 other file systems

Extend the volume

vg0 has only about 0.2 GB free, while sdb still has about 6 GB unpartitioned. To add that space, create /dev/sdb2 with fdisk (type 8e), then run:

terminal
$ pvcreate /dev/sdb2
$ vgextend vg0 /dev/sdb2
$ lvextend -r -L +5G /dev/vg0/lv0

-r (--resizefs) grows the ext4 file system together with the logical volume, while /data stays mounted.

Useful commands

CommandWhat it shows
lsblkDisks, partitions and LVs as a tree, with mount points
df -hMounted file systems and their usage
fdisk -lPartition tables of all disks
blkidUUIDs and file system types
pvs, vgs, lvsShort summaries of PVs, VGs and LVs
pvdisplay, vgdisplay, lvdisplayDetailed information

Key takeaways

  • LVM stacks three layers: physical volumes, a volume group pool, and logical volumes you format and mount.
  • The flow for a new disk is: partition (type 8e), pvcreate, vgcreate or vgextend, lvcreate, mkfs, mount.
  • A mount is temporary until it is in /etc/fstab; test every fstab change with mount -a.
  • With vgextend and lvextend -r, you can grow a file system without unmounting it.