LVM – Logical Volume Management in Linux

With the implementation of LVM we can reallocate storage space and extend our storage volumes really easily. In the example below I’d like to show how. Keep in mind that these examples are for learning purposes only, it doesn’t make a lot of sense in real life. So what I did here is that I found an old thumb drive in my drawer and I partitioned it with my Raspberry Pi to practice LVM in Linux. So let’s begin.

First let’s install the lvm2 package on our Linux system, since we’re using a Debian-based system we’ll use the apt package manager:

For learning and for demonstration purposes I used a simple 8 gig thumb drive which I’ve divided to 5 partitions with fdisk before.

It’s important to change the default ‘Linux Filesystem’ partition type to ‘Linux LVM’ in fdisk for each partition:

These are the partitions I’ve created with fdisk:

So this our initial state, I didn’t put any filesystem on the partitions, I didn’t mount anything.

Step 1 – Create Physical Volumes

With the pvcreate command we’re creating physical volumes, we simply assign an LVM header to the partitions meaning that now they can be added to a volume group. We’re utilizing the brace expansion feature of the bash shell here, so we don’t need to list each partitions with its absolute path.

We can make sure that the physical volumes has been created successfully with pvdisplay (more verbose) or the pvs (less verbose output) command. We can also discover the physical volumes on our system with the pvscan command.

Step 2 – Create the Volume Group

At this point we simply group together our partitions into a “pool” which we’ve designated before with the LVM header using pvcreate command. I name the volume group simply VG_TEST:

As we’ve seen before with the physical volumes we can utilize the vgdisplay and the vgs commands to check that our volume has been successfully created:

As we can see we still have all the free disk space, since we didn’t create any logical volumes yet.

Step 3 – Create Logical Volumes

We’re going to “carve out” spaces from our volume group to create logical volumes using the lvcreate command specifying its size and name. We have two choices here: we can specify the logical volume as fixed size, as I did below:

or we can define as how much % of the volume group we’d like “cut out”. Issuing the command below will create a logical volume with half the size of the volume group, I named it BIGCHUNK:

Similarly to Step 1 and 2 I issued the lvdisplay and the lvs commands as well as the vgdisplay command: now it can be seen that the free space in the volume group has been reduced since we’ve created 2 logical volumes and allocated free space for them with the size of 500 MB and 3.48 GB.

Step 4 – Create a Filesystem on the Logical Volumes

We can refer to the logical volumes with 2 methods: we can use /dev/VG_TEST/LILCHUNK and /dev/VG_TEST/BIGCHUNK (lvm1 naming convention) or we can use the more modern way with the mapper referring to virtual volumes: /dev/mapper/VG_TEST-LILCHUNK and /dev/mapper/VG_TEST-BIGCHUCK. Feel free to use either of them, both of them works.

To be able to mount and store files on the logical volumes we need to put a filesystem on them. There is nothing special or extraordinary here, we simply use the mkfs command as we would do with any other regular partition.

I created different filesystems on each logical volumes (ext3 and ext4), just to demonstrate that they don’t necessarily have to be the same. Since both of ext3 and ext4 has journaling capabilities it doesn’t make any practical difference here, in real life you’d prefer ext4 for it’s improved performance, I guess.

Step 5 – Mount the Logical Volumes

Now we mount the logical volumes as we’d do with any other regular partition using the mount command. Before issuing the mount command we’ll have to create two empty directories for both logical volumes:

As it can be seen above I demonstrate both naming convention, both of them works just fine, so don’t get confused because of the naming difference.

Step 6 – Extend the Logical Volume

The real advantage using logical volumes is that they can be extended (or reduced) on the fly, the disk space can be allocated dynamically for the partitions. You’re out of free space? You just need to add more space from the “pool” (volume group) as much as you exactly need. So let’s write some random data to the LILCHUCK exhausting all the free space:

As we can see from the output of the df command, LILCHUNK is full.

So let’s allocate some free space from the volume group, again we have two choices: can specify either the exact value we’d like to add to the logical volume (‘L’ flag) or the percentage of the free space in the volume group (‘l’ flag). In this example I add +500MB of free space to LILCHUNK:

So according to the output we should have a logical partition with the size of around ~1GB. But the df command still doesn’t show that it has been extended properly:

The issue here that the ext3 filesystem on the logical volume hasn’t been resized yet, we can do that with the resize2fs utility, if we don’t specify anything it’ll extend the filesystem on the whole volume:

In the example below let’s extend BIGCHUNK with specifying the ‘-l’ option, I also use the –resizefs option, so we won’t need to run the resize2fs command separately.

So this is how we can create and extend logical volumes in a nutshell. LVM is a very useful thing, the capability to dynamically extend or reduce your volume size according to your needs is something really powerful. LVM has many additional features on top of that, for example we can create snapshots, and restore files we’ve deleted for some reason. I might write about that in a future post.