You have installed your linux using reasonable defaults. This means, you might have a EFI partition, a boot partition and all the remaining space is used for a big encrypted partition (LUKS - Linux Unified Key Setup), which hosts a physical volume to be used by LVM (logical volume manager). Since you need to be able to unlock this encrypted partition before using, this is done in the initial ram disk stored on the boot partition, which is not encrypted.

During the time however, a couple of linux kernel updates will be installed and sooner or later this boot partition is more and more filled. Eventually a new initrd can’t be created because there is no space left on the boot device.

Increasing the boot partition is not so simple, since it involves that the LUKS-encrypted partition is being shrunk and moved, in order to make space. Luckily this is possible with the help of the live linux Gnome Partition Editor (gparted).

  1. Boot from the live linux CD / USB Stick and start gparted
  2. Unlock the encrypted LUKS partition
  3. The LVM volumes should be active now, check in a terminal with sudo pvdisplay and sudo lvdisplay.

I have one physical volume, which is entirely used up by two logical volumes: the “root” file system and a “swap” volume.

Now we’re going to shrink the root volume first:

sudo lvreduce --resizefs --verbose --size -20G /dev/my-volume-group-vg/root

This will make the root filesystem and the root volume by 20 gigabytes smaller. It is important, to have the flag resizefs present as well, because this will first shrink the filesystem and afterwards shrink the volume. If the filesystem is not shrunk before, you’ll loose data…

Once this is finished, you can verify with sudo pvdisplay, that there are now free extents available again for allocation on this PV. However, if you try to shrink now the PV, this is not possible, because the PV is framented: there is now a whole in the middle, you can see this with sudo pvs -v --segments:

PV                          VG                 Fmt  Attr PSize    PFree  Start  SSize  LV     Start Type   PE Ranges                                
/dev/mapper/nvme0n1p3_crypt my-volume-group-vg lvm2 a--  <476,20g 20,00g      0 112729 root       0 linear /dev/mapper/nvme0n1p3_crypt:0-112728     
/dev/mapper/nvme0n1p3_crypt my-volume-group-vg lvm2 a--  <476,20g 20,00g 112729   5120            0 free                                            
/dev/mapper/nvme0n1p3_crypt my-volume-group-vg lvm2 a--  <476,20g 20,00g 117849   4057 swap_1     0 linear /dev/mapper/nvme0n1p3_crypt:117849-121905

We first need to manually defragment. This means, we move the swap volume to the beginning. As you can see, my swap volume is smaller than the free space, so we can move it in one go. Look at the columns “Start” and “SSize”. These show, where the segment starts and how big it is. We use these numbers to move the swap segment into the free space: sudo pvmove --alloc anywhere /dev/mapper/nvme0n1p3_crypt:117849+4057

The option “alloc anywhere” is needed, since we are moving it on the same physical volume. It will just move the extents somewhere else, where there is free space. If you get the numbers wrong, you might introduce more fragmentation, but you can easily recover from this with some more “pvmove” calls.

This might take a while and you see some progress report during the move. After that, we’ll check the result with sudo pvs -v --segments again:

PV                          VG                 Fmt  Attr PSize    PFree  Start  SSize  LV     Start Type   PE Ranges                                
/dev/mapper/nvme0n1p3_crypt my-volume-group-vg lvm2 a--  <476,20g 20,00g      0 112729 root       0 linear /dev/mapper/nvme0n1p3_crypt:0-112728     
/dev/mapper/nvme0n1p3_crypt my-volume-group-vg lvm2 a--  <476,20g 20,00g 112729   4057 swap_1     0 linear /dev/mapper/nvme0n1p3_crypt:112729-116785
/dev/mapper/nvme0n1p3_crypt my-volume-group-vg lvm2 a--  <476,20g 20,00g 116786   5120            0 free                       

Now we see, that the free space is at the end of the PV. We could now use pvresize, but it’s hard to get the correct size since we want to shrink the whole partition as well. That’s why we’ll now use gparted again.

In gparted, you can now resize the partition containing the PV. Just shrink it by the 20g, that we have freed.

Once this is done, you should see, that there is now some unpartitioned space on the disk at the end.

Now you need to deactive and lock the LUKS partition in gparted. Only after this, it is possible to move this partition further to the end to make free unpartitioned space at the beginning, where the EFI and boot partitions are.

I wanted to increase both EFI and boot, so I moved first my big partition by 2.5g further to the end, then I moved the boot partition by 0.5g (and increased it up to about 2g) and after that I increased the EFI partition.

Since I moved the big partition by only 2.5g, there is now still an unpartition space of about 17.5g available. I then increased this partition again. After that I opened (unlocked) the LUKS partition again, so I could increase the PV again to use the whole space again. I didn’t allocate yet the free extents, but I could now anytime.

Tip: If possible, try to reduce the logical volume (via lvreduce) as much as possible and make the PV as small as possible. This means, that gparted as to move less data around when you move the partition and that makes it faster. You can increase the volumes later again.

Note: If you need to reformat your EFI partition (sure, you have backed up the data before and restored the bootloaders), the UUID might have changed. Make sure to update then the reference in /etc/fstab on your root partition, otherwise you might not be able to boot properly anymore.