Linux LVM

So this is my first official tutorial. I’m going teach you about utilizing Linux’s logical volume management. Everything that I say is based upon my own knowledge and understanding. I will also be doing everything as root, because I like to live dangerously.

What is LVM?
LVM (again to my understanding) is a means of easily increasing disk capacity on servers without a need to bring them down. This is especially useful in cloud environments like AWS, Google, and any other environment where you can add disks to your server on the fly.

How does it work?
LVM works by creating volume groups and logical volumes which allows disks that are properly formatted to work in a sort of pseudo cluster. This pseudo cluster allows for new disks to be added on the fly along with extending volume groups and their individual logical volumes. It also allows for new logical volumes to be created to an existing volume group. LVM implementations act as disk partitions which allow for them to be mounted at various points thus potentially preventing a systems disk space from being full, as long as you can add new disks.

Can we get into the meat and potatoes now?

Sure let’s start by verifying current disks through two different commands. I’ll be doing everything on Ubuntu, but the commands are the exact between Enterprise Linux and Debian based systems. I can’t really speak to Arch or various other distros as I don’t really use them on a regular basis (I use Red Hat in AWS for job).

To verify the current disk/system configuration there are 2 different commands we can run. The first is lsblk (list block devices) gives us a semi graphical way of viewing our system partition(s) setup and identifying any volume groups we may already have.

root@ubuntu:~# lsblk
NAME                         MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda                            8:0    0    20G  0 disk
├─sda1                         8:1    0   243M  0 part /boot
├─sda2                         8:2    0     1K  0 part
└─sda5                         8:5    0  19.8G  0 part
  ├─ubuntu--vg-root (dm-0)   252:0    0  18.8G  0 lvm  /
  └─ubuntu--vg-swap_1 (dm-1) 252:1    0  1020M  0 lvm  [SWAP]
sr0                           11:0    1  1024M  0 rom
root@ubuntu:~#

NOTE:If you see â instead of the mapping lines, you will probably want to change your PuTTY character set to UTF-8 (Settings -> Window -> Translation).

So now that we can see in our above mappings we’re fully utilizing every drive that’s attached, I’m going to add a 2 gig volume to my server and reissue lsblk to verify the addition.

root@ubuntu:~# lsblk
NAME                         MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda                            8:0    0    20G  0 disk
├─sda1                         8:1    0   243M  0 part /boot
├─sda2                         8:2    0     1K  0 part
└─sda5                         8:5    0  19.8G  0 part
  ├─ubuntu--vg-root (dm-0)   252:0    0  18.8G  0 lvm  /
  └─ubuntu--vg-swap_1 (dm-1) 252:1    0  1020M  0 lvm  [SWAP]
sdb                            8:16   0     2G  0 disk
sr0                           11:0    1  1024M  0 rom
root@ubuntu:~#

From the above we can see that a new drive of sdb (EL will show as sd{letter} or xvd{letter}) is listed. We’ll need the drive name for formatting it for our new volume group.To format the drive we’re going to do fdisk /dev/sdb, n for a new partition, to ensure we’re making a primary parition, 1 for the partition number (since we don’t have any pre-existing partitions), press return twice so we use default values and the entire disk. Next we’ll change the partition partition type by pressing t for our option and entering a hex code of 8e. This will make it a Linux LVM partition. Lastly we’ll enter the command w which will write our changes to the disk.

root@ubuntu:~# fdisk /dev/sdb
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel with disk identifier 0x9e73a87d.
Changes will remain in memory only, until you decide to write them.
After that, of course, the previous content won't be recoverable.

Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)

Command (m for help): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-4194303, default 2048):{return}
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-4194303, default 4194303):{return}
Using default value 4194303

Command (m for help): t
Selected partition 1
Hex code (type L to list codes): 8e
Changed system type of partition 1 to 8e (Linux LVM)

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.
root@ubuntu:~#

Woo hoo! Now that we’ve formatted our drive and changed the partition to enable Linux LVM we can officially start playing with LVM. The first thing we need to do is create our volume group with the command vgcreate vgtutorial /dev/sdb1. That command will create a volume group called vgtutorial on partition 1 of device /dev/sdb.

root@ubuntu:~# vgcreate vgtutorial /dev/sdb1
  No physical volume label read from /dev/sdb1
  Physical volume "/dev/sdb1" successfully created
  Volume group "vgtutorial" successfully created
root@ubuntu:~#

That wasn’t so hard was it? No? Awesome. Now it’s time to create two logical volume. We’ll call them one and two. They’ll both be created with 500Mb of space (so that we can resize them later) and will use a very similar command. The command we’ll use is lvcreate /dev/vgtutorial -n {name} -L {numerical size}{abbreviated size – T,G,M,K}. Notice that the first parameter we pass to the lvcreate command is /dev/vgtutorial? That makes it easier for us to manage things later on like mounting or adding entries to fstab.

root@ubuntu:~# lvcreate /dev/vgtutorial -n one -L 500M
  Logical volume "one" created
root@ubuntu:~# lvcreate /dev/vgtutorial -n two -L 500M
  Logical volume "two" created
root@ubuntu:~#

With our two volumes in place, it’s time format them, mount them, and confirm their mounting/availability. I’ll be formatting both of them with ext4. LV one will be mounted as /one while lv two will be mounted as /var/two. I’ll use df -hP (human readable and portability/POSIX output) to confirm that they have been mounted along with their proper paths and sizes.

root@ubuntu:~# mkfs.ext4 /dev/vgtutorial/one
mke2fs 1.42.9 (4-Feb-2014)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
Stride=0 blocks, Stripe width=0 blocks
128016 inodes, 512000 blocks
25600 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=67633152
63 block groups
8192 blocks per group, 8192 fragments per group
2032 inodes per group
Superblock backups stored on blocks:
        8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409

Allocating group tables: done
Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done

root@ubuntu:~# mkfs.ext4 /dev/vgtutorial/two
mke2fs 1.42.9 (4-Feb-2014)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
Stride=0 blocks, Stripe width=0 blocks
128016 inodes, 512000 blocks
25600 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=67633152
63 block groups
8192 blocks per group, 8192 fragments per group
2032 inodes per group
Superblock backups stored on blocks:
        8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409

Allocating group tables: done
Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done

root@ubuntu:~# mkdir /one
root@ubuntu:~# mkdir /var/two
root@ubuntu:~# mount /dev/vgtutorial/one /one
root@ubuntu:~# mount /dev/vgtutorial/two /var/two
root@ubuntu:~# df -hP
Filesystem                   Size  Used Avail Use% Mounted on
/dev/mapper/ubuntu--vg-root   19G  1.9G   16G  11% /
none                         4.0K     0  4.0K   0% /sys/fs/cgroup
udev                         486M  4.0K  486M   1% /dev
tmpfs                        100M  512K   99M   1% /run
none                         5.0M     0  5.0M   0% /run/lock
none                         497M     0  497M   0% /run/shm
none                         100M     0  100M   0% /run/user
/dev/sda1                    236M   69M  155M  31% /boot
/dev/mapper/vgtutorial-one   477M  2.3M  445M   1% /one
/dev/mapper/vgtutorial-two   477M  2.3M  445M   1% /var/two
root@ubuntu:~#

At this point in time we’ve successfully created a logical volume group, 2 logical volumes, and mounted both volumes. If we want to have the volumes available on system start we could put the following lines into /etc/fstab.

/dev/vgtutorial/one     /one            ext4    defaults        0 0
/dev/vgtutorial/two     /var/two        ext4    defaults        0 0

So the remaining parts of the tutorial are to extend a volume, resize a volume, remove a volume, and remove a volume group. Resizing a volume may be necessary when you’re running low on disk space but don’t want to do an outage to copy/rsync shift things around. You can instead use the command lvresize /dev/{volume group name}/{logical volume} -L +{numerical size}{byte indicator – T,G,M,K}. Check out the demo below where I use df to get a status report of my mounts, notice that /one is 99% full? I’ll resize /var/two to 100M since I’m not using it. If I had data on it, I would definitely not shrink it as that could cause data loss. Resizing is only recommended when you accidentally made a partition larger than you should have. Once I’ve resized /dev/vgtutorial/two to 100M I’ll extend /dev/vgtutorial/one by 1GB. After the extension I’ll have to resize the file system with resize2fs to make the new space available and verify it with df -hP.

root@ubuntu:~# df -hP
Filesystem                   Size  Used Avail Use% Mounted on
/dev/mapper/ubuntu--vg-root   19G  1.9G   16G  11% /
none                         4.0K     0  4.0K   0% /sys/fs/cgroup
udev                         486M  4.0K  486M   1% /dev
tmpfs                        100M  512K   99M   1% /run
none                         5.0M     0  5.0M   0% /run/lock
none                         497M     0  497M   0% /run/shm
none                         100M     0  100M   0% /run/user
/dev/sda1                    236M   69M  155M  31% /boot
/dev/mapper/vgtutorial-one   477M  419M   29M  94% /one
/dev/mapper/vgtutorial-two   477M  2.3M  445M   1% /var/two
root@ubuntu:~# lvresize /dev/vgtutorial/two -L 100M
  WARNING: Reducing active and open logical volume to 100.00 MiB
  THIS MAY DESTROY YOUR DATA (filesystem etc.)
Do you really want to reduce two? [y/n]: y
  Reducing logical volume two to 100.00 MiB
  Logical volume two successfully resized
root@ubuntu:~# lvextend /dev/vgtutorial/one -L +1G
  Extending logical volume one to 1.49 GiB
  Logical volume one successfully resized
root@ubuntu:~# resize2fs /dev/vgtutorial/one
resize2fs 1.42.9 (4-Feb-2014)
Filesystem at /dev/vgtutorial/one is mounted on /one; on-line resizing required
old_desc_blocks = 2, new_desc_blocks = 6
The filesystem on /dev/vgtutorial/one is now 1560576 blocks long.

root@ubuntu:~# df -hP
Filesystem                   Size  Used Avail Use% Mounted on
/dev/mapper/ubuntu--vg-root   19G  1.9G   16G  11% /
none                         4.0K     0  4.0K   0% /sys/fs/cgroup
udev                         486M  4.0K  486M   1% /dev
tmpfs                        100M  512K   99M   1% /run
none                         5.0M     0  5.0M   0% /run/lock
none                         497M     0  497M   0% /run/shm
none                         100M     0  100M   0% /run/user
/dev/sda1                    236M   69M  155M  31% /boot
/dev/mapper/vgtutorial-one   1.5G  419M  980M  30% /one
/dev/mapper/vgtutorial-two   477M  2.3M  445M   1% /var/two
root@ubuntu:~#

I also could have used lsblk to verify the status as well.

root@ubuntu:~# df -hP
Filesystem                   Size  Used Avail Use% Mounted on
/dev/mapper/ubuntu--vg-root   19G  1.9G   16G  11% /
none                         4.0K     0  4.0K   0% /sys/fs/cgroup
udev                         486M  4.0K  486M   1% /dev
tmpfs                        100M  512K   99M   1% /run
none                         5.0M     0  5.0M   0% /run/lock
none                         497M     0  497M   0% /run/shm
none                         100M     0  100M   0% /run/user
/dev/sda1                    236M   69M  155M  31% /boot
/dev/mapper/vgtutorial-one   1.5G  419M  980M  30% /one
/dev/mapper/vgtutorial-two   477M  2.3M  445M   1% /var/two
root@ubuntu:~# lsblk
NAME                         MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda                            8:0    0    20G  0 disk
├─sda1                         8:1    0   243M  0 part /boot
├─sda2                         8:2    0     1K  0 part
└─sda5                         8:5    0  19.8G  0 part
  ├─ubuntu--vg-root (dm-0)   252:0    0  18.8G  0 lvm  /
  └─ubuntu--vg-swap_1 (dm-1) 252:1    0  1020M  0 lvm  [SWAP]
sdb                            8:16   0     2G  0 disk
└─sdb1                         8:17   0     2G  0 part
  ├─vgtutorial-one (dm-2)    252:2    0   1.5G  0 lvm  /one
  └─vgtutorial-two (dm-3)    252:3    0   100M  0 lvm  /var/two
sr0                           11:0    1  1024M  0 rom
root@ubuntu:~#

So I’ve shrank /var/two because I haven’t used it and I’ve been told that I don’t actually need it. Since I got that word I’ll definitely want to go ahead and remove the logical volume. To do that I’ll need to unmount the device, then I can delete the volume and its folder. To unmount it I’ll use umount /path/to/mount and to remove the volume lvremove /dev/{volume group}/{logical volume}. Removing the directory is rm -Rf /path/to/directory.

root@ubuntu:~# umount /var/two
root@ubuntu:~# lvremove /dev/vgtutorial/two
Do you really want to remove and DISCARD active logical volume two? [y/n]: y
  Logical volume "two" successfully removed
root@ubuntu:~# rm -Rf /var/two
root@ubuntu:~#

Now that I’ve done all of that all I have left is to remove the volume group. Before we do that though we should confirm that we’ve removed the second group and freed up its space. To do that we’ll use lvs and pvs. lvs will give us the logical volume status while pvs will show us the physical volume status.

root@ubuntu:~# lvs
  LV     VG         Attr      LSize    Pool Origin Data%  Move Log Copy%  Convert
  root   ubuntu-vg  -wi-ao---   18.74g
  swap_1 ubuntu-vg  -wi-ao--- 1020.00m
  one    vgtutorial -wi-ao---    1.49g
root@ubuntu:~# pvs
  PV         VG         Fmt  Attr PSize  PFree
  /dev/sda5  ubuntu-vg  lvm2 a--  19.76g  20.00m
  /dev/sdb1  vgtutorial lvm2 a--   2.00g 520.00m
root@ubuntu:~#

Notice how lvs showed not just vgtutorial but the ubuntu-vg as well and how pvs showed 2 physical volumes? This is the default behavior of both commands unless you specify a the volume group for lvs or the physical device for pvs.

root@ubuntu:~# lvs /dev/vgtutorial
  LV   VG         Attr      LSize Pool Origin Data%  Move Log Copy%  Convert
  one  vgtutorial -wi-ao--- 1.49g
root@ubuntu:~# pvs /dev/sdb1
  PV         VG         Fmt  Attr PSize PFree
  /dev/sdb1  vgtutorial lvm2 a--  2.00g 520.00m
root@ubuntu:~#

Now it’s time to finally wrap things up. Let’s unmount /one and then blow everything up with vgremove /dev/vgtutorial. We’ll follow it up with lvs and lsblk to confirm that our volume group is gone.

root@ubuntu:~# umount /one
root@ubuntu:~# vgremove /dev/vgtutorial
Do you really want to remove volume group "vgtutorial" containing 1 logical volumes? [y/n]: y
Do you really want to remove and DISCARD active logical volume one? [y/n]: y
  Logical volume "one" successfully removed
  Volume group "vgtutorial" successfully removed
root@ubuntu:~# lvs
  LV     VG        Attr      LSize    Pool Origin Data%  Move Log Copy%  Convert
  root   ubuntu-vg -wi-ao---   18.74g
  swap_1 ubuntu-vg -wi-ao--- 1020.00m
root@ubuntu:~# lsblk
NAME                         MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda                            8:0    0    20G  0 disk
├─sda1                         8:1    0   243M  0 part /boot
├─sda2                         8:2    0     1K  0 part
└─sda5                         8:5    0  19.8G  0 part
  ├─ubuntu--vg-root (dm-0)   252:0    0  18.8G  0 lvm  /
  └─ubuntu--vg-swap_1 (dm-1) 252:1    0  1020M  0 lvm  [SWAP]
sdb                            8:16   0     2G  0 disk
└─sdb1                         8:17   0     2G  0 part
sr0                           11:0    1  1024M  0 rom
root@ubuntu:~#

That’s it. You’ve successfully created, resized, extended, and removed volume groups and logical volumes.

Sadly, there is one things I did forget. I forgot to tell you how to extend a volume group. It’s actually a lot easier than extending a logical volume. To extend an existing volume just use vgextend /dev/{volume group name} /dev/{device name}{device partition id}. I’ll add an example at the next opportunity I get.

Facebooktwitterredditpinterestlinkedintumblrmail

This site uses Akismet to reduce spam. Learn how your comment data is processed.