/boot partition is too small

21 Jan

Once upon a time when I installed my Linux I made a decision. The decision was to make my /boot into a separate partition and I also decided mere 512MB are just enough. After all the kernel is a few MB, how much more space do I need? Well, it seems 512MB for a /boot partition is simply too small.

No place for bleeding edge kernel and lts with fallbacks

So what’s actually the problem?

When I installed the OS, I had only one kernel on it. After setting everything up, drivers and stuff (Nvidia and the like) I ended up with having to load a bunch of modules into my kernel on startup. This means I already had an initramfs image which was about 100MB. Of course there is another one – initramfs-fallback code which is about the same size.

Then I had driver problems and I installed an LTS kernel version for more stability. This means there was another set of initramfs and initramfs-fallback images. As well as two kernels.

And the space is barely enough for all this. But the entire mess worked just fine, or at least until I tried to update my system. Then the package manager tried to update both kernels and with them the initramfs images.

Apparently, to do this first I need to write the new versions of the kernel and initramfs, and just then delete the old versions. Who would have thought?

Well, if you barely have enough space for the versions you use, what happens when you need to write about as much data into the same partition? The update fails, because /boot is out of space.

So what are my options?

TLDR: I moved my boot partition.

Removing fallback initramfs

Bad idea. It’ll be totally fine without it, until you mess up your kernel and you decide then to restart. Then everything is messed up, can’t load and there is no fallback. So you can do it, but this is not something a person who installs an LTS kernel should do.

Removing one of the kernels

That’s more decent of an option. Especially if you remove the non-LTS version it should be fine. There’s a reason Long-Term-Support kernels exist and the reason is, that they are much more stable. So the risk of something going totally wrong is small.

Well, that was not the case for me when I installed the LTS kernel. I had a bug with my Nvidia driver with the bleeding edge version, so normally, I tried an LTS. Then I found out I have another bug with my Nvidia driver while using the LTS kernel. So I had two buggy versions.

But that specific case aside, it should be fine for a while at least.

It does mean you give up on checking the bleeding edge features of a new version, but I’m not really using all the kernel novelties anyhow (I think), so sure.

Compressing initramfs files

This one is promising a panacea. And it probably can work. So I tried it.

What’s it all about?

Well, the kernel is stored in the /boot partition with its initramfs. When it is loaded it is read from there. But there is also the feature to read it from there and unzip it before using it. This allows for two benefits:

  1. The kernel and its initramfs image use less space on the drive.
  2. Apparently, the OS loads faster if the kernel is compressed.

The second one is very surprising, but apparently, reading compressed data from a hard disc is slow, so reading smaller amount of data and then spending computing power to expand it in memory is faster.

Also, the second one seems to be the only reason to do this in modern times, since storage is cheap.

Anyhow, I researched a bit and found out, that even now I’m having the kernel compressed on /boot. Changing the compression algorithm could help a bit, but even using the most space efficient one didn’t give me more than a few MBs of free space. Far from enough to let me update…

Resizing the boot partition

It seems my only option is to resize my /boot partition.

The plan is pretty easy:

  1. Back up the entire physical device – preferably all physical devices in the system
  2. Resize the largest partition on the drive
  3. Move all the partitions after the /boot with the amount with with the largest partition was shrunk to the right
  4. Resize the /boot partition, expanding it with the free space on the drive.

Easy, right? You just strat up Gparted and you do all this very carefully.

Don’t forget to make a full backup of your system before changing anything with the partitions.

Well, there are a few problems: I need to install Gparted and we established, no updates possible, so I need to do partial update (which is not recommended for Arch linux). Oh, and one of the partitions is a LUKS device. The one that needs to be resized. Such a pain…

The good news is that you need to do the resizing from a live USB anyhow, to prevent data and system corruption. So not being able to install programs on your system isn’t a problem, you need to be able to install it on the live USB.

The even better news is, that Gparted has a live media image which you can download from their site.

Resizing the luksdev partition

To do this, I booted into the live media and then opened a terminal. In the terminal I entered this command:

# cryptsetup luksOpen /dev/path/to/encrypted/device name_under_which_it_is_going_to_be_mapped

Then I entered the passphrase to unlock the device. Now this device can be found under /dev/mapper/name_under_which_it_is_going_to_be_mapped. Now the partition is ready for manipulating.

I opened Gparted and shrank the partition with about 10GB. I’m not planning to do this ever again, so let’s leave some space to /boot.

Moving the luksdev partition

This turned out to be a bit of a problem. I now have the space to resize /boot, but it is on the other side of the main partition. I would gladly use Gparted to move the main partition and resize /boot, but the problem is, that the damn partition doesn’t want to move at all.

When I tried to use the Move/resize tool to move the partition, the fields I need to change to move the front of the partition are simply disabled. It is not possible to move the start of the partition. It is disallowed.

Looks like this is because of the encryption. I don’t really want to spend time to find out why, so I decided I’ll just move the /boot partition to the back of the device. I’ve done this before, which helped, but it seems I haven’t described it that well…

Move /boot partition

After I’ve shrank the encrypted partition, I can easily make a new partition in the space left at the end of the device and put /boot there.

To do this I need to:

  1. Create a FAT32 partition.
  2. Set its flags to boot, eps (by default it starts with msftdata flag)
  3. Remove the msftdata flag of the old /boot
  4. Copy all the data of the old /boot to the new one
  5. reinstall the bootloader (or update it perhaps. I bet it depends on the bootloader. I just wanted to be sure).

Note: this only works, because the device is initialized with a GPT table. If you instead use a MBR, this trick wouldn’t work.

The first four steps can be done through the Gparted live media. And it’s pretty easy to do it.

The last one is a bit tricky. I can probably do it through the same live media, but I would need to have the needed packages, installation utilities and so forth.

It is much simpler for me to boot into an installation usb for Arch linux and do a few commands.

What I need to do is follow the Installation Guide of Arch to mount root, boot and then chroot into it. This basically leads to the following commands:

# lsblk -f 
# mount /dev/sdxX /mnt
# mount /dev/sdxY /mnt/boot
# chroot /mnt

If we suppose /dev/sdxX is the partition where your / directory lives, and /dev/sdxY is the new /boot partition, the mount commands would map your usual / to the current /mnt. Then the boot will be mapped to /mnt/boot.

Once the mounts are done, chroot would make it look like /mnt is /. This acrobatic is necessary to start working on your OS, instead on the bootable media.

This is when I can already reinstall the bootloader. For me this happens by executing this command:

# bootctl install

However, this may vary for you, depending on the bootloader you use.

Set Linux Boot Manager to highest priority in your BIOS

Basically at this point we have the /boot partition moved to the back of the device. One last thing may be necessary. To be sure I went to my BIOS (technically UEFI Settings or something like that) and I put the Linux Boot Manager as the highest priority partition when booting.

Problems encountered

Some of the problems I encountered were already mentioned. However they were all pretty easy to circumvent. They are there, they just don’t bother me.

The thing that really got on my nerves is that I mounted the wrong partition when installing the bootloader.

I have a dual-boot and instead of being very careful which partition I mount before executing # bootctl install , I went for “This one should be right”.

Then I wrote the bootloader into the boot partition of my Windows instead. This is potentially dangerous and I basically risked with bad odds to brick my Windows. I was lucky and instead I have a Windows which thinks it has way too many data partitions. It’s pretty messed up. It works somehow.

I also wasted a bunch of time troubleshooting why my Linux can’t mount /boot once it loaded the initramfs and unlocked the encrypted device. To avoid so much pain, please check vigorously which partition you are mounting.

Also, having more than one partition marked with boot and eps flags is confusing. Which of these is actually used? Is it the new one? Is it the old one? Removing these flags from the old /boot partition at least helps me know which is the important one. Maybe the computer can decide easily, but I’m made out of meat.

I hope my journey helps you avoid some errors I made and speeds up this lengthy and slightly annoying chore.

But at least I learned something :)