Migrating LVM on LUKS system to a larger SSD

Context#

I had a 720 GB SATA SSD that was nearly full, so I bought a 2 TB NVMe SSD as an upgrade (both in storage and speed).

As the migration will force me to resize the partitions, this is an opportunity to fix them all.

Firstly, I initially sized my ESP (EFI system partition) to be 550 MB which seemed largely enough. But, you know… a kernel image is about 15 MB, an initramfs is between 40 MB and 80 MB, a fallback initramfs can be twice as big. So it's easy to reach ~ 200 MB per kernel, but when you begin to get 3 of them or more or want to keep several versions, you're quickly out of space. So I plan to double its size to 1 GB.

Secondly, as I use several VMs with a large amount of memory, 1–2 years ago, I upgraded from 16 GB of RAM to 32 GB. Now seems the good time to adjust my swap accordingly so I can hibernate again.

Migration#

Reconnaissance#

Let's list the disk before the migration to be sure not to mess up the wrong ones.

➜ sudo lshw -class disk -class storage -short
Chemin matériel          Périphérique  Classe         Description
====================================================================
/0/100/1.3/0/1/3/0.0.0    /dev/sdd        disk           2TB SSD 990 EVO Plus
/0/100/1.3/0.1/0.0.0      /dev/sdc        disk           720GB Q-720
[…]

So /dev/sdc is the old one and /dev/sdd the new one. The state of my system was like that:

➜ lsblk
NAME             MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINTS
[…]
sdc                8:32   0 670,7G  0 disk
├─sdc1             8:33   0   550M  0 part  /boot
│                                           /efi
└─sdc2             8:34   0 670,2G  0 part
  └─cryptlvm     254:0    0 670,1G  0 crypt
    ├─myvg2-swap 254:1    0    16G  0 lvm   [SWAP]
    └─myvg2-root 254:2    0 654,1G  0 lvm   /
sdd                8:48   0   1,8T  0 disk

Disk copy#

As we're migrating to a larger SSD, the first step is surprisingly easy: just copy the old disk to the new one! I'm not using dd because it's slow, instead I used pv which is faster and also displays a progression bar.

# As root
pv < /dev/sdc > /dev/sdd

It took ~25 minutes to complete (old disk over SATA, new disk over USB).

Partition table fix#

Then we can repair partition table on the new disk, we'll get new GUID.

$ gdisk /dev/sdd
Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: present

Found valid GPT with protective MBR; using GPT.

Command (? for help): w
Warning! Secondary header is placed too early on the disk! Do you want to
correct this problem? (Y/N): Y
Have moved second header and partition table to correct location.

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): Y
OK; writing new GUID partition table (GPT) to /dev/sdc.
The operation has completed successfully.

So, after the disk copy, our system is like below, the disk was well copied on the new disk, but the partitions are the same size, and there are a lot of unused space. So we'll need to resize partitions after that.

➜ lsblk
NAME             MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINTS
[…]
sdc                8:32   0 670,7G  0 disk
├─sdc1             8:33   0   550M  0 part
└─sdc2             8:34   0 670,2G  0 part
sdd                8:48   0   1,8T  0 disk
├─sdd1             8:49   0   550M  0 part
└─sdd2             8:50   0 670,2G  0 part

Partitions resizing (ESP & LUKS)#

I choose to go the easy way, by using a GUI.

Reboot to the old SSD, and launch GParted (Unfortunately KDE partition manager doesn't support resizing FAT32 or LUKS).

I want to take the chance to enlarge my ESP, so:

  1. I moved the LUKS partition (sdd2) of 450 MB to the right,
  2. then extended my ESP (sdd1) with the newly unallocated 450 MB between the ESP and the LUKS partition
  3. and then we can extend the LUKS partition with the remaining trailing space.

If GParted offers to repair GPT partition table to use the whole space, accept it. The operation took about 1 hour (over USB).

LVM volumes resizing (SWAP and root FS)#

Reboot to an ArchLinx USB key. With only the new disk's LUKS opened (don't boot from the old SSD, else there will be some partition UUID or LVM virtual groups conflicts), then open the new SSD's LUKS partition.

sudo cryptsetup open /dev/sdd2 cryptlvm2

Activate the LVM volume group:

sudo vgchange -ay

Resize the physical volume to take all the partition remaining space:

sudo pvresize /dev/mapper/cryptlvm2

I'll take the chance to resize my Swap too (16 -> 32 GB) as I upgraded my RAM. It needs reformatting to take all the space of the updated swap partition.

sudo lvextend -L +16G /dev/myvg/swap
sudo mkswap /dev/myvg/swap

Reformatting the swap will reset the partition UUID that will need to be reflected in /etc/fstab.

Extend the logical volume to take all the physical volume remaining space:

sudo lvextend -l +100%FREE /dev/myvg/root

Resize the filesystem:

sudo e2fsck -f -y /dev/mapper/myvg-root
sudo resize2fs /dev/mapper/myvg-root
Share