Working with LVM

I only partition my disks using LVM anymore because it's easier to manage multiple physical disks. Something linux has always done, and windows has more recently figured out, has been to let you mount drives as a folder. In the *nix world, this is obvious because everything is a file under /. I've always preferred this approach since it lets you keep files logically organized rather than having to organize files according to physical volumes (C:\, D:\, E:\, etc) -- put the files where they're supposed to go rather than where storage capacity will let them go. But what if we've got a 500G disk mounted as /home and it's exceeding capacity? Should we buy a new (bigger) disk and migrate all the data to it? What then should be done with the empty 500G disk?

LVM answers these questions by abstracting the physical volumes and partitions. LVM partitions can join a logical volume group and have logical volumes created that span multiple physical disks. It's another layer of abstraction beyond mounting physical disks as folders; it provides a universal storage pool capable of spanning physical volumes. When /home is mounted as a logical volume (in the LVM sense -- not to be confused with a logical partition), it is simple to add a new physical volume, join it to the logical volume group and then extend the logical volume as necessary. This allows /home to grow capacity across multiple physical volumes without having to move data or get creative with mount points.

I've been partitioning drives for many years and have a lot of experience creating and managing disk partitions. I'm not as comfortable with LVM compared to traditional partitioning because there are new tools to use and they're just not as refined yet. I'm a console admin, but I prefer GUI tools for disk partitioning because I don't like calculating extents by hand. But with LVM, that just isn't really an option because the tools don't exist.

This post provides an example of working with LVM to create a new logical volume striped across two physical volumes in order to provide a large logical volume with improved performance.

VG Names

Let's take a quick look at how to choose a name for a volume group. If we called a group something like vgMain, we would have trouble if we tried to move the group to another machine, so it's good to put the hostname in the volume group. But just the hostname by itself is also too generic because it doesn't allow separation of disks. For example, I use SSDs to hold operating system files and SATA disks to hold mass storage such as data archives and home directories. Below you'll see volume groups named home.ssd and home.mass. A distinction such as this makes it easy to ensure data is physically stored in the proper location. Proper planning can help with disaster recovery by limiting the scope of failure.

We're going to skip the explination of how to create volume groups and how to add disks to them for the sake of brevity; the goal of this post is more of general overview than of specific details.

Creating a logical volume

Manage lvm with the lvm command; run this to get into the LVM console. First let's look at the physical volumes.

> pvdisplay 
  --- Physical volume ---
  PV Name               /dev/sdb1
  VG Name               home.ssd
  PV Size               59.62 GiB / not usable 4.00 MiB
  Allocatable           yes (but full)
  PE Size               4.00 MiB
  Total PE              15263
  Free PE               0
  Allocated PE          15263
  PV UUID               HrClHH-XuOm-T508-J5jP-EUP0-DAty-cclMuW
   
  --- Physical volume ---
  PV Name               /dev/sdc1
  VG Name               home.mass
  PV Size               465.76 GiB / not usable 3.99 MiB
  Allocatable           yes 
  PE Size               4.00 MiB
  Total PE              119234
  Free PE               119234
  Allocated PE          0
  PV UUID               byhjhS-BOU1-YJmw-d8VX-16BR-zccd-1kdnKq
   
  --- Physical volume ---
  PV Name               /dev/sda1
  VG Name               home.mass
  PV Size               465.76 GiB / not usable 3.99 MiB
  Allocatable           yes 
  PE Size               4.00 MiB
  Total PE              119234
  Free PE               119234
  Allocated PE          0
  PV UUID               2Wk2nA-7USB-VvKH-1IVN-nqo5-9hlv-FmHb0F

The Hard way

This method will show how to calculate extents which enables you to specify precisely where to store data.

What I want to do is create a /home partition using /dev/sda1 and /dev/sdc1. Each of these has about 500G capacity, making 1T total. I want to use about 700G for my home partition, and stripe it across the two physical volumes. The command to create this logical volume will need to know what extents to use from each disk, and how many total extents.

Looking at my physical volumes (above), I can see their extent size is 4M; time to pull out a calculator and do some basic math. I need to know how many extents are in 700G, so I calculate 700 * 1000 / 4 and get 175000. This volume will be spanning across two physical disks, so I next calculate 175000 / 2 and get 87500. Now I'm ready to create the logical volume.

> lvcreate -l175000 -i2 -nhome home.mass /dev/sdc1:0-87500 /dev/sda1:0-87500
  Using default stripesize 64.00 KiB
  Logical volume "home" created

The Easy way

Just let LVM worry about where to put the data. This is why we separate our disk types into volume groups (see the VG Names section above). We don't want our home directory to waste space on the SSD, and since our SATA disks are in a distinct volume group from our SSD(s), we don't need to worry about specifying what extents to store the data on. Just say:

> lvcreate -L700G -i2 -nhome home.mass

Finishing up

The next step is to partition the new volume.

mkfs.ext4 /dev/mapper/home.mass-home

And lastly I throw that mount point in /etc/fstab and then mount it!