The Complete Beginner's Guide to LVM in Linux
Everything necessary you need to know and learn about the logical volume management in Linux.
This is a complete beginner's guide to LVM (Logical Volume Manager) in Linux.
In this tutorial, you'll learn the concept of LVM, its components and why you should be using it.
I won't be limited to just the theoretical explanation. I'll also show hands-on examples for creating and managing LVMs in Linux.
In short, I'm going to give you all the necessary information that you'd need to start working with LVM in the real world.
What is LVM in Linux?
LVM stands for Logical Volume Manager. A mechanism that provides an alternative method of managing storage systems than the traditional partition-based one. In LVM, instead of creating partitions, you create logical volumes, and then you can just as easily mount those volumes in your filesystem as you'd a disk partition.
/boot
. That is because GRUB (the most common bootloader for Linux) can't read from logical volumes. The well-known alternative to GRUB, systemd-boot on the other hand reads only vfat filesystems, so that's not going to work either.Components of LVM
There are three main components to LVM:
- Physical Volumes
- Volume Groups
- Logical Volumes
Although the list consists of three components, only two of them are direct counterparts to the partitioning system. The following table logs that.
Disk Partitioning System | LVM |
---|---|
Partitions | Logical Volumes |
Disks | Volume Groups |
Physical volumes do not have any direct counterpart, but I'll talk about that soon.
Why use LVM?
The main advantage of LVM is how easy it is to resize a logical volume or volume group. It abstracts away all the ugly parts (partitions, raw disks) and leaves us with a central storage pool to work with.
If you've ever experienced the horror of partition resizing, you'd wanna use LVM.
Lab preparation for hands-on
This article is not just theory. I'll be showing actual command examples along the way and the best way to learn something is to work with it, hands-on. For that, I recommend you use a virtual machine.
To help you with that I already have prepared a simple Vagrantfile that you can use to spin up a very light virtual machine with VirtualBox. This virtual machine has three additional disks that you and I can use for the command examples below.
Create a directory somewhere in your filesystem and save the following in a file there, named Vagrantfile
.
Vagrant.configure "2" do |config|
config.vm.box = "ubuntu/focal64"
config.vm.hostname = "lvm"
3.times {|i| config.vm.disk :disk, size: "5GB", name: "drive-#{i}"}
config.vm.provider :virtualbox do |machine|
machine.memory = 1024
machine.cpus = 1
machine.customize ["modifyvm", :id, "--cpuexecutioncap", "50"]
end
end
# vi: set ft=ruby
Or if you'd like, you can use wget or curl to download the file from my gist.
wget https://gist.githubusercontent.com/debdutdeb/98ed1b6aef36885d07ce8247188dfd5e/raw/524259da5dfa2d8750883d01c8159829729e224d/Vagrantfile
Make sure you have Vagrant and VirtualBox installed.
Once the Vagrantfile is in place, set the environment variable VAGRANT_EXPERIMENTAL
to disks
.
export VAGRANT_EXPERIMENTAL=disks
Finally, start the virtual machine using the following command (make sure you're in the same directory as the Vagrantfile):
vagrant up
Once the machine is running, you can use vagrant ssh
to SSH into it and run the example commands from this article.
Remember to run vagrant destroy
from the same directory as the Vagrantfile after you're done.
Installing LVM
Before you can use any of the commands, you need to install the lvm2
package. This should be preinstalled in most of the modern distributions, especially the Ubuntu-based ones. But still, I had to mention this before moving forward. To install lvm2
, consult your distribution's documentation.
Hands-on with LVM
For this hands-on walk-through, I've built a virtual machine with 40G root storage (unimportant) and three external disks of size 5G. The size of these disks are arbitrary.
vagrant@lvm:~$ lsblk -o name,size,fstype
NAME SIZE FSTYPE
loop0 55.5M squashfs
loop1 32.3M squashfs
loop2 70.4M squashfs
sda 40G
└─sda1 40G ext4
sdb 10M iso9660
sdc 5G
sdd 5G
sde 5G
As you can see the devices I'm going to use are sdc
, sdd
and sde
.
Remember I told you there are three main components to LVM?
- Physical Volumes
- Volume Groups
- Logical Volumes
It is time to see them one by one.
1. Physical Volumes
The very first thing you need to know about LVM, is physical volumes. Physical volumes are the raw materials or building blocks that are used to achieve the abstraction that is logical volumes. In simpler words, physical volumes are the logical unit of an LVM system.
A physical volume can be anything, a raw disk, or a disk partition. Creating and initializing a physical volume are the same thing. Both mean you're just preparing the building blocks (i.e. partitions, disks) for further operations. This will become clearer in moment.
Utilities: All utilities that manage physical volumes start with the letters pv
for Physical Volume. E.g. pvcreate
, pvchange
, pvs
, pvdisplay
etc.
Creating physical volumes
You can create a physical volume using a raw non-partitioned disk or the partitions themselves.
As I previously mentioned I have three external drives attached to my virtual machine, let's start with /dev/sdc
.
We use the pvcreate
command to create a physical volume. Just pass the device name to it and nothing else.
sudo pvcreate /dev/sdc
You should see something like this:-
vagrant@lvm:~$ sudo pvcreate /dev/sdc
Physical volume "/dev/sdc" successfully created.
Next I'll be partitioning /dev/sdd
into equal parts. Use any tool, cfdisk
, parted
, fdisk
etc, there are many tools to achieve this job.
vagrant@lvm:~$ lsblk -o name,size,fstype | grep sdd
sdd 5G
├─sdd1 2.5G
└─sdd2 2.5G
You can now quickly create two more physical volumes out of these two partitions in one single step, pass both of these devices to pvcreate
at once.
sudo pvcreate /dev/sdd1 /dev/sdd2
Take a look:-
vagrant@lvm:~$ sudo pvcreate /dev/sdd1 /dev/sdd2
Physical volume "/dev/sdd1" successfully created.
Physical volume "/dev/sdd2" successfully created.
Listing the available physical volumes
There are three commands that you can use to get the list of the available physical volumes, pvscan
, pvs
and pvdisplay
. You generally don't need to pass anything to these commands.
pvscan
:-
vagrant@lvm:~$ sudo pvscan
PV /dev/sdc lvm2 [5.00 GiB]
PV /dev/sdd1 lvm2 [2.50 GiB]
PV /dev/sdd2 lvm2 [<2.50 GiB]
Total: 3 [<10.00 GiB] / in use: 0 [0 ] / in no VG: 3 [<10.00 GiB]
pvs
:-
vagrant@lvm:~$ sudo pvs
PV VG Fmt Attr PSize PFree
/dev/sdc lvm2 --- 5.00g 5.00g
/dev/sdd1 lvm2 --- 2.50g 2.50g
/dev/sdd2 lvm2 --- <2.50g <2.50g
pvdisplay
:-
vagrant@lvm:~$ sudo pvdisplay
"/dev/sdc" is a new physical volume of "5.00 GiB"
--- NEW Physical volume ---
PV Name /dev/sdc
VG Name
PV Size 5.00 GiB
Allocatable NO
PE Size 0
Total PE 0
Free PE 0
Allocated PE 0
PV UUID SzSkdD-xKYa-4y7P-teyU-481p-uiQ8-qieMJJ
"/dev/sdd1" is a new physical volume of "2.50 GiB"
--- NEW Physical volume ---
PV Name /dev/sdd1
VG Name
PV Size 2.50 GiB
Allocatable NO
PE Size 0
Total PE 0
Free PE 0
Allocated PE 0
PV UUID 553Iy4-JJ21-LfIw-udtO-j9Cd-7gFS-iXXFVS
"/dev/sdd2" is a new physical volume of "<2.50 GiB"
--- NEW Physical volume ---
PV Name /dev/sdd2
VG Name
PV Size <2.50 GiB
Allocatable NO
PE Size 0
Total PE 0
Free PE 0
Allocated PE 0
PV UUID bf7ghn-QkPm-EUdp-GdyW-shMG-5sMn-VhNtYB
As you can see along with just listing the physical volumes these commands also give you a ton of other information about these volumes.
Removing a physical volume
You can remove a physical volume with the pvremove
command. Just like pvcreate
, just pass the devices (that are initialized as physical volumes) to pvremove
command.
For demonstration, I'll remove /dev/sdd2
from the list.
sudo pvremove /dev/sdd2
The output should be identical to this:-
vagrant@lvm:~$ sudo pvremove /dev/sdd2
Labels on physical volume "/dev/sdd2" successfully wiped.
Now list the physical volumes with sudo pvs
vagrant@lvm:~$ sudo pvs
PV VG Fmt Attr PSize PFree
/dev/sdc lvm2 --- 5.00g 5.00g
/dev/sdd1 lvm2 --- 2.50g 2.50g
/dev/sdd2
is no more here.
2. Volume Groups
Volume groups are collections of physical volumes. It is the next level of abstraction in LVM. Volume groups are the storage pool that combines the storage capacity of multiple raw storage devices.
Utilities: All volume group utility names start with vg
, stands for Volume Group, e.g. vgcreate
, vgs
, vgrename
etc.
Creating volume groups
Volume groups are created using the vgcreate
command. The first argument to vgcreate
is the name you want to give this volume group, and the rest are the list of the physical volumes that are going to back the storage pool.
sudo vgcreate lvm_tutorial /dev/sdc /dev/sdd1
Example:-
vagrant@lvm:~$ sudo vgcreate lvm_tutorial /dev/sdc /dev/sdd1
Volume group "lvm_tutorial" successfully created
Listing the volume groups
Listing volume groups is similar to listing physical volumes, you can use different commands with varying levels of verbosity, vgdisplay
, vgscan
and vgs
.
I personally prefer the vgs
command, sudo vgs
vagrant@lvm:~$ sudo vgs
VG #PV #LV #SN Attr VSize VFree
lvm_tutorial 2 0 0 wz--n- 7.49g 7.49g
vgscan
:-
vagrant@lvm:~$ sudo vgscan
Found volume group "lvm_tutorial" using metadata type lvm2
vgdisplay
:-
vagrant@lvm:~$ sudo vgdisplay
--- Volume group ---
VG Name lvm_tutorial
System ID
Format lvm2
Metadata Areas 2
Metadata Sequence No 1
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 0
Open LV 0
Max PV 0
Cur PV 2
Act PV 2
VG Size 7.49 GiB
PE Size 4.00 MiB
Total PE 1918
Alloc PE / Size 0 / 0
Free PE / Size 1918 / 7.49 GiB
VG UUID LYVE9P-vY0G-OAW6-an8q-yfBx-rrB1-YU61m1
Listing the physical volumes attached to a volume group
You can list all the physical volumes that are connected to a specific volume group by using the following command:-
sudo pvdisplay -S vgname=<volume_group_name> -C -o pv_name
Example:-
vagrant@lvm:~$ sudo pvdisplay -S vgname=lvm_tutorial -C -o pv_name
PV
/dev/sdc
/dev/sdd1
You can also get the count of physical volumes.
sudo vgdisplay -S vgname=<volume_group_name> -C -o pv_count
Example:-
vagrant@lvm:~$ sudo vgdisplay -S vgname=lvm_tutorial -C -o pv_count
#PV
3
Extending a volume group
Extending a volume group means adding additional physical volumes to a volume group. To do so the vgextend
command is used. The syntax is simple:-
vgextend <volume_group> <physical_volume1> <physical_volume2> ....
Let's extend our lvm_tutorial
volume by /dev/sdd2
.
sudo vgextend lvm_tutorial /dev/sdd2
Focus on the output:-
vagrant@lvm:~$ sudo vgextend lvm_tutorial /dev/sdd2
Physical volume "/dev/sdd2" successfully created.
Volume group "lvm_tutorial" successfully extended
In the physical volume section we ended up with removing /dev/sdd2
as a physical volume, but a partition or raw disk must be initialized as a physical volume otherwise LVM won't be able to manage it as part of a volume group. So vgextend
readies /dev/sdd2
before adding it to the volume group.
Now list the physical volumes attached to this volume group, just to be sure.
sudo pvdisplay -S vgname=lvm_tutorial -C -o pv_name
Output:-
vagrant@lvm:~$ sudo pvdisplay -S vgname=lvm_tutorial -C -o pv_name
PV
/dev/sdc
/dev/sdd1
/dev/sdd2
/dev/sdd2
is now in the list as expected.
Reducing a volume group
Just like extending a volume group means adding another physical volume, reducing it means removing one or more physical volumes.
We use the vgreduce
command to do this. The general syntax is as follows:-
vgreduce <vgname> <physical_volume1> <physical_volume2> ....
Let's remove the physical volumes /dev/sdc
and /dev/sdd1
.
sudo vgreduce lvm_tutorial /dev/sdc /dev/sdd1
Example:-
vagrant@lvm:~$ sudo vgreduce lvm_tutorial /dev/sdc /dev/sdd1
Removed "/dev/sdc" from volume group "lvm_tutorial"
Removed "/dev/sdd1" from volume group "lvm_tutorial"
List the physical volumes again.
sudo pvdisplay -S vgname=lvm_tutorial -C -o pv_name
Output:-
vagrant@lvm:~$ sudo pvdisplay -S vgname=lvm_tutorial -C -o pv_name
PV
/dev/sdd2
Those two physical volumes are gone.
Now for the sake of the rest of this article, add those two physical volumes back.
sudo vgextend lvm_tutorial /dev/sdc /dev/sdd1
Removing a volume group
You can remove a logical volume with the vgremove
command.
sudo vgremove lvm_tutorial
Don't run this command right now, otherwise you'd have to recreate the volume group. If you want to test it out, run it at the very end of this article.
3. Logical Volumes
This is what you're going to mostly work with. A logical volume is like a partition, but instead of sitting on top of a raw disk, it sits on top of a volume group. You can,
- Format a logical volume with whichever filesystem you want.
- Mount it anywhere in the filesystem you want.
In this section you'll be learning,
- How to create logical volumes.
- Common operations on a logical volume.
- Resizing a logical volume.
- Removing a logical volume.
Utilities: All volume group utility names start with lv
, stands for Logical Volume. e.g. lvcreate
, lvs
, lvreduce
etc.vgcreate
, vgs
, vgrename
etc.
Creating logical volumes
Logical volumes are created using the lvcreate
command. The commonly used syntax looks as follows,
sudo lvcreate -L <size> -n <lvname> <vgname>
Let me break it down for you:-
- The
-L
option is for the size of the new logical volume, you can use any integer with "GB", "MB" or "KB" at the end. E.g. "1GB". - The
-n
option is for naming this logical volume. - Finally you need to pass it the name of the volume group this logical volume will be a part of. So while providing the logical volume with a size, make sure the volume group has the space available.
Run the following command on the virtual machine:-
sudo lvcreate -L 5GB -n lv1 lvm_tutorial
Example output:-
vagrant@lvm:~$ sudo lvcreate -L 5GB -n lv1 lvm_tutorial
Logical volume "lv1" created.
Common operations on a logical volume
As I previously said, you can put a filesystem on a logical volume as well as mount it anywhere on the filesystem.
Once created you can find the logical volume in /dev/<vgname>/<lvname>
path. For example in our case the volume is going to be in /dev/lvm_tutorial/lv1
.
vagrant@lvm:~$ ls -l /dev/lvm_tutorial/lv1
lrwxrwxrwx 1 root root 7 May 17 02:09 /dev/lvm_tutorial/lv1 -> ../dm-0
Now you can use it like any partition. Format it with ext4,
sudo mkfs.ext4 /dev/lvm_tutorial/lv1
Mount it at some place in your current directory structure like /mnt
,
sudo mount -t ext4 /dev/lvm_tutorial/lv1 /mnt
Resizing a logical volume
You can extend a logical volume using lvextend
command and reduce its size using lvreduce
command. Or you can use the single command lvresize
to accomplish both tasks.
First let's see if the volume group has any space left in it or not.
sudo vgs -S vgname=lvm_tutorial -o vg_free
Output:-
vagrant@lvm:~$ sudo vgs -S vgname=lvm_tutorial -o vg_free
VFree
<4.99g
According to the output, I have some space left, so let's increase the volume size by 2GB.
Remember the logical volume is still mounted at /mnt
.
vagrant@lvm:~$ mount | grep '/mnt'
/dev/mapper/lvm_tutorial-lv1 on /mnt type ext4 (rw,relatime)
Use the following command to resize the volume:-
sudo lvresize -L +2GB lvm_tutorial/lv1
The general syntax is something like this:-
lvresize -L [+|-][Size] <vgname>/<lvname>
The symbol + or - after -L
depends on whether you're trying to increase the size of the volume or decrease it respectively.
After the volume size has increased, the filesystem must be resized as well. For ext4, the command to use is resize2fs
.
sudo resize2fs /dev/lvm_tutorial/lv1
Output:-
vagrant@lvm:~$ sudo resize2fs /dev/lvm_tutorial/lv1
resize2fs 1.45.5 (07-Jan-2020)
Filesystem at /dev/lvm_tutorial/lv1 is mounted on /mnt; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 1
The filesystem on /dev/lvm_tutorial/lv1 is now 1835008 (4k) blocks long.
Reducing a logical volume is a slightly more complicated task and I'm not going to talk about that here in this article. I'm reducing the size of this volume by 1GB.
Removing a logical volume
You remove a logical volume with the lvremove
command. The command syntax is as follows:-
lvremove <vgname>/<lvname>
Run this command on the virtual machine:-
sudo lvremove lvm_tutorial/lv1
Output:-
vagrant@lvm:~$ sudo lvremove lvm_tutorial/lv1
Do you really want to remove and DISCARD active logical volume lvm_tutorial/lv1? [y/n]: y
Logical volume "lv1" successfully removed
Conclusion
There are a multitude of other operations doable on logical volumes, physical volumes and volume groups, but it's not possible to write all that into a single article.
I've left you with one more disk /dev/sde
in the virtual machine. Use it, practice some of the commands from this article, create a new volume group, extend an existing one, just practice.
I hope this article was helpful for you, if you'd like to see more on this in the future, let me know in the comment section down below.