This article describes how I managed to extend my encrypted Btrfs root partition from my running system.
Situation
- I do not have access to an external boot medium (USB install key, or an other bootable partition)
- I am running low on disk space on a partition I cannot unmount (e.g. the
/
partition). - I have room (unformatted space) to the right of this partition.
Clarification
Sorry I lied: To the extent of my knowledge it is NOT possible to resize a LUKS partition live. That is, without unmounting it at some point. But if you can afford a reboot, "at some point" may be good enough for you.
When talking about filesystems and partitions, "live" (or "hot", or "online") operations are operations that can be carried out while the filesystem is mounted. So my using of the term "live" in the title of this article is incorrect, because the process I describe does involve unmounting the partition. (Sorry sysadmins, if you came here for a machine you cannot reboot, I don't have a solution for you.)
However, most articles I found about resizing LUKS partitions talk about full-offline resizing, which usually means rebooting into a live system when it comes to the root partition. This process is slow and involved, especially so with LUKS when you are using keyfiles for encryption. So, naturally, I looked for "live" solutions, although that was not exactly my need. Hence the title of this article. I hope you will forgive me.
In a nutshell
- Resize partition (
fdisk
) - Reboot (or close then open, if you can afford it)
- Resize filesystem (
btrfs filesystem resize
)
⚠ WARNING ⚠
This article is meant for a tech savvy audience. I expect you to know what you are doing, and cannot be held responsible for any loss of data.
The commands I am about to give you modify your partitions and filesystems. The usual safety precautions apply: Backup your data first. Triple-check every command you are about to run.
I have read a number of warnings when researching this myself. Those warnings are here for a reason, I am just reporting what worked for me.
Resizing the partition
This is the most dangerous step.
fdisk
accesses your disk directly, but will not actually change anything before you issue the w
(write) command.
If at any point you are unsure, you can cancel everything with the q
command (quit without applying).
I have an NVME drive, and the partition I want to resize is partition 11.
❯ sudo fdisk /dev/nvme0n1
Command: p
Command: d
Partition number: 11
Command: n
Partition number: 11
First sector: 355895296
Last sector:
Do you want to remove the signature?: n
Command: w
- I first
p
rint the partition layout to get the start of the existing partition (sector355895296
). - Then delete partition 11 and create a new partition.
- Make sure it has the same number (
11
) and start sector (355895296
). Last sector
is left blank and will default to occupying all available space.- I especially do not want to remove the LUKS signature, since I want to keep the partition. (The delete-then-create-new-partition trick is just a low-level resize.)
- Finally, I am ready to apply the changes as one batch.
Rebooting
At this point, everything is still working the same, and my system is not broken (which is already something). Except my Btrfs partition does not see the change (yet):
❯ sudo btrfs device usage /
(You can run this command again once you have rebooted to see the difference.)
So how do you resize the LUKS partition? Actually, you don't. You just have to close then open it again. In my case, a reboot does the job.
The key to understanding how that works, is this bit from the cryptsetup
documentation:
neither dm-crypt nor LUKS1 stores partition size and LUKS2 uses a generic "whole device" size as default
When opening the LUKS partition again (after the reboot), cryptsetup will use the new size of the partition.
Resizing the Btrfs filesystem
This is just a breeze as Btrfs does support online extending:
❯ sudo btrfs filesystem resize max /