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.







You must log in to post a comment.