Ubuntu: Extending capacity of an LVM volume group using an existing or new disk

ubuntuIt is common for a virtualized Guest OS base image to have a generic storage capacity.  This capacity can easily be exceeded by production scenarios, performance testing, logging, or even the general cruft of running a machine 24×7.

If your VM is using Logical Volume Management (LVM), adding space can be done by following a relatively simply recipe.

In this post, I will use the parted utility to create a new partition on an existing or new disk on an Ubuntu Focal guest OS.  Then we will create a physical volume from this partition and associate it with the volume group.  Finally, we extend the volume group and then have it recognized at the filesystem level.

For a visual representation of an LVM volume group, physical volumes, physical partitions, logical volumes, and filesystems the LVM wikipedia page has a nice graphic shown below.

Allocate additional storage

The first step is to either add a disk or extend the storage capacity of an existing disk for the specific virtualization backend being used.

This can be done with the virtualization engine’s preferred GUI or CLI tool.  For example, using:

Note that having snapshots on this VM may keep you from performing an extension of an existing disk.

Create the new physical partition

There are two ways you can add a new physical partition to extend the LVM volume group.

  1. Create a partition from space added to an existing disk
  2. Create a partition from a newly added disk

Important Note: Manipulating partitions can lead to a bricking of the virtualized guest OS.  If you are not completely comfortable with this procedure in a development environment, do not even consider running it in production.  Backup all critical data before executing this on a production system.

Option1: Create partition from newly added space on existing disk

If you added capacity to an existing disk, then you should be able to see it using the parted disk partition utility.  In this example, we have added 11Gb to the existing “/dev/vda”.

# install parted
sudo apt-get install parted -y

# show list of available devices (e.g. /dev/vda)
# but new partition is not shown yet because it is not defined
lsblk

We now use parted to show us the partitions on /dev/vda.

# show partitions on /dev/vda in human readable form
# press "F" when asked to fix GPT to correct size
$ sudo parted -a optimal /dev/vda print free

Warning: Not all of the space available to /dev/vda appears to be used, you can fix the GPT to use all of the space (an extra 2097152 blocks) or continue with the current setting? 
Model: Virtio Block Device (virtblk)
Disk /dev/vda: 33.3GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags: 

Number  Start   End     Size    File system  Name  Flags
        17.4kB  1049kB  1031kB  Free Space
 1      1049kB  2097kB  1049kB                     bios_grub
 2      2097kB  1076MB  1074MB  ext4
 3      1076MB  21.5GB  20.4GB
        21.5GB  33.3GB  11.8GB  Free Space

The GPT size is now corrected, and we can see the free 11.8Gb of space available.  But in order to create the partition we need to use the sector number so we change the units.

# show partition sector numbers
$ sudo parted -s -a optimal /dev/vda unit s print free

Model: Virtio Block Device (virtblk)
Disk /dev/vda: 65011712s
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags: 

Number  Start      End        Size       File system  Name  Flags
        34s        2047s      2014s      Free Space
 1      2048s      4095s      2048s                         bios_grub
 2      4096s      2101247s   2097152s   ext4
 3      2101248s   41940991s  39839744s
        41940992s  65011678s  23070687s  Free Space

From the output, we can see the free space has a starting sector at ‘41940992s’.  We will use this information to create a partition now.

$ sudo parted -s -a optimal /dev/vda unit s \
mkpart primary 41940992s 100% \
set 1 lvm on \
align-check optimal 1 \
print free


Model: Virtio Block Device (virtblk)
Disk /dev/vda: 65011712s
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags: 

Number  Start      End        Size       File system  Name     Flags
        34s        2047s      2014s      Free Space
 1      2048s      4095s      2048s                            lvm
 2      4096s      2101247s   2097152s   ext4
 3      2101248s   41940991s  39839744s
 4      41940992s  65009663s  23068672s               primary
        65009664s  65011678s  2015s      Free Space

Now the space starting at 41940992s has been assigned to partition #4.  There is a little bit of extra free space, but ignore that.  That is purposeful leftover used to maintain healthy alignment.

A quick validation will show the extra capacity at /vda4.  But creating this physical partition within an existing disk is just the prerequisite for adding it to the LVM volume group.

# should now show 11G at /vda4
lsblk
Option2: Create partition from new disk

If you created and attached a new disk, then you should be able to see it from a listing of the block devices. In this example, we have added a new 15Gb disk that shows up as “/dev/vdb”.

# install parted
sudo apt-get install parted -y

# show list of available devices (e.g. /dev/vdb)
lsblk

We now use parted to create a new partition on /dev/vdb from the newly added space.

# create partition on /dev/vdb
$ sudo parted -a optimal /dev/vdb unit s \
mklabel gpt \
mkpart primary 2048s 100% \
align-check optimal 1 \
set 1 lvm on \
print free

odel: Virtio Block Device (virtblk)
Disk /dev/vdb: 31457280s
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags: 

Number  Start      End        Size       File system  Name     Flags
        34s        2047s      2014s      Free Space
 1      2048s      31455231s  31453184s               primary  lvm
        31455232s  31457246s  2015s      Free Space

We can see the free 15Gb (31453184 sectors) of space is available at partition #1.  There is a little bit of extra free space on both ends, but ignore that. That is unnecessary leftover to maintain healthy alignment.

A quick validation will show the extra capacity at /dev/vdb1.  But creating this physical partition on a new disk is just the prerequisite for adding it to the LVM volume group.

# should now show 15G at /dev/vdb1
lsblk

Create LVM PV from physical partition

Regardless of which path you took in the previous step; whether a physical partition was created on an extended existing disk (e.g. /dev/vda4) or a new disk (e.g. /dev/vdb1), you now have a physical partition.

Use ‘pvcreate’ so LVM recognizes this physical partition.

# use variable for the name of your physical partition
# '/dev/vda4' or '/dev/vdb1' for this example
export mypartition="/dev/vda4"

# see list of current phys volumes known to LVM
sudo pvs

# create physical volume (force wipe) 
sudo -E pvcreate $mypartition -f

# should now see new partition recognized
sudo pvs

Associate physical partition to volume group

You need to associate the physical partition with the LVM volume group, which is done with ‘vgextend’.

# name of LVM volume groups
sudo vgs

# put name of LVM volume group into variable
export vgname=$(sudo vgs --noheading | awk '{print $1}')
echo "LVM vg name is $vgname"


# associate device to volume group 
sudo -E vgextend $vgname $mypartition

# will now show relationship between partition and volume group
sudo pvs

Resize LVM volume group

Use ‘lvresize’ to have the LVM logical volume use the new physical partition.

# logical volume will still show old capacity
sudo lvs

# show logical volume full path (e.g. /dev/ubuntu-vg/ubuntu-lv)
sudo lvdisplay | grep "LV Path"

# put lv full path into variable
export lvfullpath=$(sudo lvdisplay -c | awk -F':' '{print $1}' | tr -d ' ')
echo "lv full path is $lvfullpath"

# have lv use all its available space
sudo -E lvresize -l +100%FREE $lvfullpath

# logical volume will now show new capacity
sudo lvs

Have filesystem recognize expanded space

While LVM now sees the additional space, the filesystem does not.  For ext4 filesystems you can use resize2fs to have the space recognized.

# show space on LVM mount
df -h

# use to extend
sudo -E resize2fs $lvfullpath

# LVM mount now increased in size
df -h

The new space is now reflected in the LVM mount and is available for use by the system.

 

 

REFERENCE

howtogeek.com, LVM cheat sheet

linux.die.net, parted man page

gnu.org, parted description of resizepart

tecmint.com, parted for creating rescue partitions

linoxide.com, parted for managing partitions

superuser.com, scripting parted

thegeekdiary.com, how to extend the fs partition with parted

linuxhint.com, parted

rainbow.chard.org, how to align partitions

tylersguides.com, add disk to LVM, xfs_growfs

woshub.com, how to extend increase kvm disk, xfs_growfs/resize2fs

microhowto.info, how to increase LVM logical volume

computingforgeeks.com, extend kvm disk

slice2.com, resize default LVM on ubuntu 18

NOTES

alternative to lsblk to show devices

lshw -class disk -short

If using a non-LVM managed host, then you extend the ending sector of the existing partition on /dev/vda.  Then resize2fs to have it recognized at filesystem level.

$ sudo parted /dev/vda
GNU Parted 3.3
Using /dev/vda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print free 
Warning: Not all of the space available to /dev/vda appears to be used, you can fix the GPT to use all of the
space (an extra 20971520 blocks) or continue with the current setting? 
Fix/Ignore? F

unit s

print free
odel: Virtio Block Device (virtblk)
Disk /dev/vda: 25583616s
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags: 

Number  Start     End        Size       File system  Name  Flags
        34s       2047s      2014s      Free Space
14      2048s     10239s     8192s                         bios_grub
15      10240s    227327s    217088s    fat32              boot, esp
 1      227328s   4612062s   4384735s   ext4
        4612063s  25583582s  20971520s  Free Space


(parted) resizepart 
Partition number? 1 
Warning: Partition /dev/vda1 is being used. Are you sure you want to continue?
Yes/No? Y 
End? [4612062s]? 25583582s

(parted) quit

# resize the filesystem
$ sudo resize2fs /dev/vda1

# verify disk change recognized
$ df -h