Fail: Resizing /boot on Cinnamon

The current 128GB (119.2GiB) Plextor M.2 disk on cinnamon was created with a very small (256MB/243MiB) /boot partition. Turns out this was a mistake, as it will only hold 3 kernels, so I’m constantly having to go in and remove kernel n-3 to make room.
The remainder of the drive is a single extended partition, containing a 119GiB LUKS container, which contains a 119GiB LVM volume group, which has a root of 107.3GiB and an 11.7GiB swap. The root is only 13% utilized, and while it may grow a little it is in no danger or running out of space. The swap is also far larger than needed. I want to steal a couple of GB from one of them to increase the /boot, but I want to do this while retaining the contents of both the / and the /boot.
Long story short, turns out I wasn’t able to do it. But the journey was a great learning experience for me, so I’ve kept the notes, for future reference.

Doing this is tricky, involving successively resizing inner containers before resizing the outer containers. This is a test operation on a similar disk I built for doing the test. It is a 500GB (465.5GiB) disk, on which I’ve put 2 partitions, the first has an ext4 256MB/243MiB testboot, and the second an extended partition (2) holding a single logical partition of 465.5GiB (sdl5) containing a 465.5GiB Luks container (testcrypt) which in turn holds an LVM pv (vg /dev/testvg, consisting of pv /dev/mapper/testcrypt) with a 429GB/400GiB lv dev/testvg/testroot and the remainder a 70GB/65.52GiB /dev/testvg/testswap. This is all on /dev/sdl.

1) In the real case we will first have to reboot onto a dvd. Can’t perform any useful actions on the active boot drive.
2) Then, in the real case we will have to open the drive with cryptsetup luksOpen /dev/sdl5
3) Now we want to resize one of the logical volumes, to get our 5GB.
We could resize the testroot. This turns out to be harder, but just to follow the thought, if we want to resize the testroot logical volume we would first have to resize the testroot filesystem (which is inside the testroot lv (which is inside the testvg pv which is inside the luks container, which is inside partition 5 which is inside the extended partition. Whew!) We want to steal 2GiB from the 400GiB it consumes. But to be on the safe side, since we have plenty of room, we would steal 5GiB and reclaim the leftovers later.

e2fsck -fy /dev/mapper/testvg-testroot
resize2fs /dev/testvg/testroot 395G
lvresize –size -5G /dev/testvg/testroot

4) The problem with this scheme turns out to be that the free space we created is between the two logical volumes, so we can’t readily shrink the surrounding physical volume.

Looking at the layout we have:

pvs –segments /dev/mapper/testcrypt
PV                    VG     Fmt  Attr PSize   PFree Start  SSize   
/dev/mapper/testcrypt testvg lvm2 a--  465.50g 5.00g      0 101120          
/dev/mapper/testcrypt testvg lvm2 a--  465.50g 5.00g 101120   1280                                                 
/dev/mapper/testcrypt testvg lvm2 a--  465.50g 5.00g 102400  16769     

So now we have the free space between the two logical volumes. Maybe I could fix it up with pvmove, but there is nothing in the swap that needs to be preserved, so the easy way is just to lvremove the swap logical volume.

But an even easier way is to just steal the 5GB from the swap. Then we also don’t even need to resize the filesystem first. And I don’t need 11.7GB of swap.

lvresize –size -5G /dev/testvg/testswap
WARNING: Reducing active logical volume to 60.52 GiB
THIS MAY DESTROY YOUR DATA (filesystem etc.)
Do you really want to reduce testswap? [y/n]: y
Size of logical volume testvg/testswap changed from 65.52 GiB (16773 extents) to 60.52 GiB (15493 extents).
Logical volume testswap successfully resized.

followed by mkswap /dev/testvg/testswap to wipe the old signatures, and remake the swap area in the smaller partition.

Then we have:

pvs –segments /dev/mapper/testcrypt
PV                    VG     Fmt  Attr PSize   PFree Start  SSize                               
/dev/mapper/testcrypt testvg lvm2 a--  465.50g 5.00g      0 102400         
/dev/mapper/testcrypt testvg lvm2 a--  465.52g 5.00g 102400  15493
/dev/mapper/testcrypt testvg lvm2 a--  465.50g 5.00g 117889   1280

Note the SSize entry is in extents, and extentsize is 4GB, so 1280 extents is o the 5GB free space is on the end.

5) Now we resize the physical volume. We reduced the lv by 5GB, so we ought to be able to downsize the pv by the same amount. Key Words: “Ought to be able to” – the kiss of death.

pvresize –setphysicalvolumesize 460.52G /dev/mapper/testcrypt 

and I get a complaint

/dev/mapper/testcrypt: cannot resize to 117892 extents as 117893 are allocated.

This was the reason for stealing more space than we needed, so that when these little things crop up we can deal with them. We don’t really need all 5G so we reduce to 461 instead. We will reclaim excess later.

pvresize –setphysicalvolumesize 461G /dev/mapper/testcrypt

PV                    VG     Fmt  Attr PSize   PFree   Start  SSize 
/dev/mapper/testcrypt testvg lvm2 a--  461.00g 488.00m      0 102400
/dev/mapper/testcrypt testvg lvm2 a--  461.00g 488.00m 102400  15493
/dev/mapper/testcrypt testvg lvm2 a--  461.00g 488.00m 117893    122

a little bit left over we will get back later.

6) Before we go on, I want to check the disk. Since this is all about documentation, it is useful to note here that to release the disk, we have to release the logical volumes, then the physical volume, and then the device mapper entry for the luks container.

lvchange -an /dev/testvg/testswap
lvchange -an /dev/testvg/testroot
vgchange -an /dev/testvg
cryptsetup close testcrypt

That will unhook everythng, and the disk can be shut down. To get it all back, just

cryptsetup luksOpen /dev/sdl5

7) Now we have to resize the LUKS container down to retrieve space freed up from the pv.

cryptsetup status testcrypt

/dev/mapper/testcrypt is active and is in use.
  type:    LUKS1
  cipher:  aes-xts-plain64
  keysize: 256 bits
  device:  /dev/sdl5
  offset:  4096 sectors
  size:    976267312 sectors
  mode:    read/write

The pv is now 461GiB so 461*1024*1024*1024 / 512 = 966787072 sectors.

So shrink the LUKS container down around it:

cyptsetup resize -b 966787072 testcrypt
cryptsetup status testcrypt
/dev/mapper/testcrypt is active and is in use.
  type:    LUKS1
  cipher:  aes-xts-plain64
  keysize: 256 bits
  device:  /dev/sdl5
  offset:  4096 sectors
  size:    966787072 sectors
  mode:    read/write

8) The next logical step is to shrink the /dev/sdl5 partition down to the size of the LUKS container. The container is 461GiB, and the partition is still 500GB/465.5GiB.

This cannot be done with gparted, because it throws up its hands in despair when it sees the LUKS container. It can be done with parted, but can it be done without destroying everything?
There used to be a command in parted called resize, but it was replaced with a new command resizepart, where you can only specify the new ending sector.

parted /dev/sdl
print
Number  Start   End    Size   Type      File system  Flags
 1      1049kB  256MB  255MB  primary   ext4
 2      256MB   500GB  500GB  extended
 5      257MB   500GB  500GB  logical

Here I resorted to fdisk, to give me exact sector number.

fdisk /dev/sdl
p
Device   Start   End      Sectors   Size Id Type
/dev/sdl1 2048   499711    497664   243M 83 Linux
/dev/sdl2 499712 976773167 976273456 465.5G 5 Extended
/dev/sdl5 501760 976773167 976271408 465.5G 83 Linux

The partition (5) starts at 501760, and per the cryptsetup status, it now needs to be 966787072 sectors long,
so the last sector will now be (the sum -1) 967288831.

Back to parted /dev/sdl

(parted) resizepart 5 967288831s                                          
Warning: Shrinking a partition can cause data loss, are you sure you want to continue?
Yes/No? Yes                                                               
(parted) print                                                            
Model: ATA ST3500418AS (scsi)
Disk /dev/sdl: 500GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags: 

Number  Start   End    Size   Type      File system  Flags
 1      1049kB  256MB  255MB  primary   ext4
 2      256MB   500GB  500GB  extended
 5      257MB   495GB  495GB  logical                      

And this is where things have always gone wrong. I looked at it with fdisk, and it seems to be right, the logical partition 5 has shrunk exactly as we want, according to fdisk:

Device     Boot  Start       End   Sectors   Size Id Type
/dev/sdl1 2048   499711    497664   243M 83 Linux
/dev/sdl2 499712 976773167 976273456 465.5G  5 Extended
/dev/sdl5 501760 967288831 966787072 461G 83 Linux

But the display on the gnome-disks application is totally hosed. Hoping this is simply him being confused, I deactivated the lv and vg, removed the LUKS container, and removed the disk. Then I put it back in.
Huzzah, everything comes up correctly. The extended partition (2) is still 465.52 GiB, but it has a 461GiB partition 5, and 4.9GB/4.52GiB of free space on the end.

9) The next step would be to move partition 5, which has the LUKS container in it, to the right by some amount, up to 4.52GiB.
Alas, at this point, I am screwed. Parted is happy to move the end point of a partition. Gparted is happy to move either end to absorb free space, but neither will move the existing content.

Two days I’ve been working on this. I’ll keep this document because it has a lot of useful poodah, but the whole operation is a failure.

If I want a different layout on the M.2 device, I can do a full reinstall of Ubuntu, or what I will probably do is buy a new M.2, and this time get one that will do NVME.