Last update: Nov 2024
Preface / Motivation
Everybody who experienced a default installation of Ubuntu 24.04 or Ubuntu 23.10 and wanted the default encryption to be enabled, will inevitably come across the same problems. Ubuntu’s new installer does not allow you to use your predefined LUKS partitions anymore. LVM (Logical Volume Manager) is mandatory now. Therefore I’m writing this small blogpost as kind of a cheatsheet, because I’m sure some of you will encounter the same problems. One of my first problems was, that the Ubuntu installer takes up all your free space during LVM+LUKS creation. This is typically not what I’m asking for. And since Canocial decided to eliminate the Legacy Desktop Installer (which was able to use LUKS without LVM), there is no other way except playing around with LVM. So here we go.
Overview about LVM
First of all we need some knowledge about the relationsships. Using the following graphic of linuxconfig.org, we explain how the individual elements relate to each other.
LVM (Logical Volume Manager) consists always of three parts with the following hierarchy (from bottom to top):
- Level 1: Physical Volume (PV): baseline element of LVM
- Level 2: Volume Group (VG): kind of a virtual drive / can reside on multiple partitions, disks, name should be unique
- Level 3: Logical Volume (LV): there are your “usable” volumes, where our filesystem resides
Example Installation
For showing you all details we use a default Ubuntu 24.04 installation with encryped LVM on a 50 GB drive. All of those 50 GB are used for LVM by default; as you can see in GParted:
Let’s assume we just booted the system up and want to see some facts about it. We use lsblk and df for this purpose.
lsblk
>>>
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
...
sda 8:0 0 50G 0 disk
├─sda1 8:1 0 1G 0 part /boot/efi
├─sda2 8:2 0 2G 0 part /boot
└─sda3 8:3 0 46.9G 0 part
└─dm_crypt-0 252:0 0 46.9G 0 crypt
└─ubuntu--vg-ubuntu--lv 252:1 0 46.9G 0 lvm /
df -Th
>>>
Filesystem Type Size Used Avail Use% Mounted on
...
/dev/mapper/ubuntu--vg-ubuntu--lv ext4 46G 9.5G 35G 22% /
...
In addition to this there are specific commands to show more information about PV, VG and LV:
PV-Level | VG-Level | LV-Level |
pvscan | vgscan | lvscan |
pvs | vgs | lvs |
pvdisplay | vgdisplay | lvdisplay |
We will run all of them now to get more details about the system we are in.
# we want some info about the PV (physical volume):
# 1. sudo pvscan
PV /dev/mapper/dm_crypt-0 VG ubuntu-vg lvm2 [<46.93 GiB / 0 free]
Total: 1 [<46.93 GiB] / in use: 1 [<46.93 GiB] / in no VG: 0 [0 ]
# 2. sudo pvs
PV VG Fmt Attr PSize PFree
/dev/mapper/dm_crypt-0 ubuntu-vg lvm2 a-- <46.93g 0
# 3. sudo pvdisplay
--- Physical volume ---
PV Name /dev/mapper/dm_crypt-0
VG Name ubuntu-vg
PV Size 46.93 GiB / not usable 3.00 MiB
Allocatable yes (but full)
PE Size 4.00 MiB
Total PE 12014
Free PE 0
Allocated PE 12014
PV UUID zofURa-qyMQ-1hza-DRax-8nvs-mhUR-zZhKgo
What do we learn about the PV? (Reminder: LVM base level 1 out of 3)
- There is an encrypted partition /dev/sda3 (size 49,95 GiB) and this partition has been opened and accessible at /dev/mapper/dm_crypt-0 (size 46,93 GiB).
# now we want info about the VG (volume group):
# 1. sudo vgscan
Found volume group "ubuntu-vg" using metadata type lvm2
# 2. sudo vgs
VG #PV #LV #SN Attr VSize VFree
ubuntu-vg 1 1 0 wz--n- <46.93g 0
# 3. sudo vgdisplay
--- Volume group ---
VG Name ubuntu-vg
System ID
Format lvm2
Metadata Areas 1
Metadata Sequence No 2
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 1
Open LV 1
Max PV 0
Cur PV 1
Act PV 1
VG Size <46.93 GiB
PE Size 4.00 MiB
Total PE 12014
Alloc PE / Size 12014 / <46.93 GiB
Free PE / Size 0 / 0
VG UUID 55tDXa-6TTg-ccDx-UCCV-UaQX-mnSl-FyP1hi
What do we learn about the VG? (Reminder: LVM level 2 out of 3)
- Inside the PV there is a VG named ubuntu-vg (size 49,93 GiB).
# now we want info about the LV (logical volumes)
# 1. sudo lvscan
ACTIVE '/dev/ubuntu-vg/ubuntu-lv' [<46.93 GiB] inherit
# 2. sudo lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
ubuntu-lv ubuntu-vg -wi-ao---- <46.93g
# 3. sudo lvdisplay
--- Logical volume ---
LV Path /dev/ubuntu-vg/ubuntu-lv
LV Name ubuntu-lv
VG Name ubuntu-vg
LV UUID 0RjrOz-HkVm-03XG-GKc7-6YUD-bejn-5kUB54
LV Write Access read/write
LV Creation host, time ubuntu, 2024-11-26 22:11:39 +0100
LV Status available
# open 1
LV Size <46.93 GiB
Current LE 12014
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 252:1
What do we learn about the LV? (Reminder: LVM level 3 out of 3)
- There is a logical volume (“usable partition”) named ubuntu-lv (size 46,93 GiB).
- We keep in mind that the filesystem of /dev/ubuntu-vg/ubuntu-lv is ext4.
As you can see the Ubuntu installer really used all disk space of our 50 GB disk. Argh! Let’s say I wanted to use just 30 GB of the disk. We need to change that somehow!
Example scenario: We shrink the whole stuff from 50 to 30 GiB.
For the purpose of showing how that works, we will try – as mentioned – to shrink the 50GiB filesystem to 30GiB. For this we need to boot up a live Linux like Ubuntu from a pendrive. Be conscious of what you type: 1G = 1.000.000.000 Bytes; while 1g = 1.073.741.824 Bytes.
As we found out in the part before we have the following LVM situation:
ext4 | filesystem type within LV where our data is stored |
/dev/ubuntu-vg/ubuntu-lv | level 3 logical volume (LV) |
ubuntu-vg | level 2 volume group (VG) |
/dev/mapper/dm_crypt-0 | level 1 physical volume (PV) |
The steps we need to do now must be carried out in the correct order of the LVM: first on filesystem, then on level 3 (LV), then on level 2 (VG) and finally on level 1 (PV).
Step 0: Boot up a Linux from USB which are you familiar with.
Ensure that packages lvm2 and cryptsetup are installed.
Step 1: Opening the /dev/sda3 partition holding the LVM data
# opening the partition
sudo cryptsetup open /dev/sda3 cryptedpartition
# we will find it opened now
ls /dev/mapper
>>>
... cryptedpartition ubuntu--vg-ubuntu--lv
# lets check it again if it is really open
sudo fdisk -l /dev/mapper/ubuntu--vg-ubuntu--lv
>>>
Disk /dev/mapper/ubuntu--vg-ubuntu--lv: 46.93 GiB, ...
Step 2: Shrinking the ext4 filesystem within ubuntu-lv
# run the mandatory check first
sudo e2fsck -f /dev/mapper/ubuntu--vg-ubuntu--lv
>>>
e2fsck 1.47.1 (20-May-2024)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/mapper/ubuntu--vg-ubuntu--lv: 172200/3080192 files (0.2% non-contiguous), 2724943/12302336 blocks
# shrink it, -p stands for showing a progress bar
sudo resize2fs -p /dev/mapper/ubuntu--vg-ubuntu--lv 30g
>>>
resize2fs 1.47.1 (20-May-2024)
Resizing the filesystem on /dev/mapper/ubuntu--vg-ubuntu--lv to 7864320 (4k) blocks.
Begin pass 2 (max = 1720747)
Relocating blocks XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Begin pass 3 (max = 376)
Scanning inode table XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Begin pass 4 (max = 16510)
Updating inode references XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
The filesystem on /dev/mapper/ubuntu--vg-ubuntu--lv is now 7864320 (4k) blocks long.
# as you can see now the filesystem ext4 has a size of 30G (7864320 * 4096 Bytes = 32212254720 Bytes = 30 GiB)
Step 3: Shrinking the LV: ubuntu-lv
# now we reduce the size of the LV to fixed 30GiB
sudo lvreduce -L 30g /dev/mapper/ubuntu--vg-ubuntu--lv
>>>
File system ext4 found on ubuntu-vg/ubuntu-lv.
File system size (30.00 GiB) is equal to the requested size (30.00 GiB).
File system reduce is not needed, skipping.
Size of logical volume ubuntu-vg/ubuntu-lv changed from <46.93 GiB (12014 extents) to 30.00 GiB (7680 extents).
Logical volume ubuntu-vg/ubuntu-lv successfully resized.
# if you look on gparted now, then you ll notice that /dev/sda3 is not filled 100% anymore but shows only 30GiB of usage.
Shortcut available for step 4! Typically we would have to shink the VG, shink the PV and to shrink the LUKS partition now. You can use a shortcut now: You can let the tool do the work for you. Just open it up with sudo and manually shrink the partition to the size you need, here: 30 GiB. If you click on apply, you are done with all three remaining steps at once.
In case you prefer “the hard way”, you can continue with those commands instead:
Step 4 “the hard way”: Shrinking the VG: ubuntu-vg, Shrinking the PV: /dev/mapper/dm_crypt-0, Shrinking the LUKS holding partition: /dev/sda3.
# find out how many free space we have within the VG
sudo pvs
>>>
PV VG Fmt Attr PSize PFree
/dev/mapper/cryptedpartition ubuntu-vg lvm2 a-- <46.93g <16.93g
# here we have 16.93g free space. we want to remove that.
# first we need some math for preparation
sudo fdisk -l /dev/sda
>>>
Device Start End Sectors Size Type
...
/dev/sda3 6397952 104855551 98457600 46.9G Linux filesystem
# now we know that the crypted partition starts at sector 6397952 and ends with 104855551. the size is 98457600 sectors. if you use a calculator it will show you that 98457600 blocks are equal to 46.9482421875 Gibibyte (GiB).
# usually we would have have to calculate 46.93g - 16.93g, but keep in mind that the LVM tells us <16.93g. that means there is some overhead and we have to consider that during calculation.
# so we count 49.93g - 16.90g = 33.03g
# we use this value for shrinking the filesystem
sudo lvm pvresize -v --yes --setphysicalvolumesize 33.05g '/dev/mapper/cryptedpartition'
>>>
WARNING: /dev/mapper/cryptedpartition: Pretending size is 69310873 not 98424832 sectors.
Resizing volume "/dev/mapper/cryptedpartition" to 69310873 sectors.
Resizing physical volume /dev/mapper/cryptedpartition from 12014 to 8460 extents.
Updating physical volume "/dev/mapper/cryptedpartition"
Archiving volume group "ubuntu-vg" metadata (seqno 3).
Physical volume "/dev/mapper/cryptedpartition" changed
Creating volume group backup "/etc/lvm/backup/ubuntu-vg" (seqno 4).
1 physical volume(s) resized or updated / 0 physical volume(s) not resized
# as we can see above the filesystem has been changed to 69310873 blocks. we need this value to shinkthe encryption volume now
sudo cryptsetup -v --size 69310873 resize 'cryptedpartition'
>>>
No usable token is available.
Enter passphrase for /dev/sda3:
Key slot 0 unlocked.
Command successful.
Caution: Do not use the following unless you know what you are doing!
## DONT USE THIS - ITS JUST FOR MY REFERENCE ##
######## THIS IS WHAT GPARTED DID ############
# calibrating
# path: /dev/sda3 (partition)
# start: 6397952
# end: 104855551
# size: 98457600 (46.95 GiB)
# encryption path: /dev/mapper/cryptedpartition
# shrink filesystem
sudo lvm pvresize -v --yes --setphysicalvolumesize 31460352K '/dev/mapper/cryptedpartition'
# shrink encryption volume
sudo cryptsetup -v --size 62920704 resize 'cryptedpartition'
# shrink partition from 46.95 GiB to 30.02 GiB
# old start: 6397952
# old end: 104855551
# old size: 98457600 (46.95 GiB)
# new start: 6397952
# new end: 69351423
# new size: 62953472 (30.02 GiB)