Enabling discard/TRIM in LVM-on-LUKS

Hi all! I’m trying to enable passthrough of discard commands to my NVMe drive with an LVM-on-LUKS setup. Currently I have one VG with a simple linear mapping over two PVs, like so:

NAME                     MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
nvme0n1                  259:0    0 465.8G  0 disk  
├─nvme0n1p1              259:1    0   650M  0 part  /boot/efi
├─nvme0n1p2              259:2    0   128M  0 part  
├─nvme0n1p3              259:3    0    80G  0 part  
├─nvme0n1p4              259:4    0   225G  0 part  
│ └─lvm                  253:0    0   225G  0 crypt 
│   ├─linux-fedora--root 253:1    0    50G  0 lvm   /
│   ├─linux-swap         253:2    0    20G  0 lvm   [SWAP]
│   └─linux-home         253:4    0   243G  0 lvm   /home
├─nvme0n1p5              259:5    0   128G  0 part  
│ └─lvm2                 253:3    0   128G  0 crypt 
│   └─linux-home         253:4    0   243G  0 lvm   /home
└─nvme0n1p6              259:6    0   383M  0 part  /boot

From my understanding, LVM will pass through discards automatically and I shouldn’t have to touch it.

For LUKS, I need to make sure the option is enabled when the partitions are opened. systemd’s crypttab(5) says I can specify discard in the volume’s options field. So I do that, and make sure the values end up in the initrd like so:

# lsinitrd -f /etc/crypttab
lvm /dev/disk/by-uuid/<xxxx> discard
lvm2 /dev/disk/by-uuid/<xxxx> discard

However, this doesn’t seem to work, since fstrim on the relevant filesystems fails, and the output of lsblk --discard looks like this:

NAME                     DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
nvme0n1                         0      512B       2T         0
├─nvme0n1p1                     0      512B       2T         0
├─nvme0n1p2                     0      512B       2T         0
├─nvme0n1p3                     0      512B       2T         0
├─nvme0n1p4                     0      512B       2T         0
│ └─lvm                         0        0B       0B         0
│   ├─linux-fedora--root        0        0B       0B         0
│   ├─linux-swap                0        0B       0B         0
│   └─linux-home                0        0B       0B         0
├─nvme0n1p5                     0      512B       2T         0
│ └─lvm2                        0        0B       0B         0
│   └─linux-home                0        0B       0B         0
└─nvme0n1p6                     0      512B       2T         0

I’ve tried several other things, including:

  • adding rd.luks.allow-discards on the kernel command line as shown in dracut.cmdline(7) (as well as rd.luks.options=discard as seen elsewhere)
  • adding x-initrd.attach to crypttab options
  • trying all of the above with and without rd.luks.uuid=<xxxx> entries on the kernel command line

…all with the same result.

Needless to say, I’m pretty confused about this, and am wondering if there’s a gotcha I don’t know about here. Thanks in advance for any help!

Did you take a look at /etc/lvm/lvm.conf?
As far as I remember, but it has been a long time since I set this up, you need a issue_discards = 1 there:

# [...]
devices  {
      # [ ... ]
      issue_discards = 1
      # [ ... ]
   }
# [...]

Other than that, I think just the modification of /etc/crypttab is needed (appending a discard as option, which you already did).

Normally you have to rebuild your initramfs (dracut -f) and reboot after changing the LVM configuration. Did you do that?

Ah, I almost brought this up in my post. issue_discards has nothing to do with passing through discards from higher layers:

# Configuration option devices/issue_discards.
# Issue discards to PVs that are no longer used by an LV.
# Discards are sent to an LV's underlying physical volumes when the LV
# is no longer using the physical volumes' space, e.g. lvremove,
# lvreduce.

This is equivalent to issuing discards to a partition on a disk when the partition is deleted, which is not helpful here.

Yes, this is why I include the output of lsinitrd -f /etc/crypttab.

After setting up a new install of Fedora on a different machine, I finally caught my issue: in crypttab, I had the fields wrong, and discard was being interpreted as a keyfile instead of a flag. Since I had neither keyfile nor flags before, those fields were empty, and I skimmed the man page for the correct flag to use, not noticing my mistake adding it in the wrong place. Just needed to add none for the keyfile field and I’m good to go. Pays to note these details when reading your config files (:

1 Like