LUKS & btrfs Patterns
Disk encryption and btrfs patterns I’ve actually used. Every entry has a date and context.
2026-04-02: Four-Partition Dual-LUKS Strategy
Problem: Need encrypted root + encrypted home on a single 2TB NVMe, with EFI and a separate /boot. The system must allow root reinstallation without touching /home.
Context: P16g deployment, 2TB Samsung NVMe, Arch Linux. Matching the Razer’s proven production layout.
The Fix:
# Wipe partition table
sgdisk -Z /dev/nvme0n1
# EFI System Partition (512M) — bootloader, kernels, initramfs
sgdisk -n 1:0:+512M -t 1:ef00 /dev/nvme0n1
# /boot (2G ext4) — OS-managed kernel staging, NOT read by systemd-boot
sgdisk -n 2:0:+2G -t 2:8300 /dev/nvme0n1
# Root (250G LUKS) — caps system bloat
sgdisk -n 3:0:+250G -t 3:8309 /dev/nvme0n1
# Home (remaining ~1.7T LUKS) — repos, models, data
sgdisk -n 4:0:0 -t 4:8309 /dev/nvme0n1
# Verify
sgdisk -p /dev/nvme0n1
Lesson learned: An ext4 XBOOTLDR partition (type ea00) did NOT work on the ThinkPad P16g Gen 3. The Boot Loader Specification requires XBOOTLDR to be VFAT-readable by firmware. Kernels and boot entries must ALL reside on the ESP (VFAT) where systemd-boot reads them. The ext4 /boot is for pacman kernel management only.
Rule: Dual-LUKS separation means root can be nuked and reinstalled without losing /home. 250G root cap prevents system bloat creeping into user space. Kernels live on the ESP (VFAT), not XBOOTLDR (ext4). Don’t over-engineer XBOOTLDR unless firmware explicitly supports ext4 boot.
Worklog: WRKLOG-2026-04-02
2026-04-02: LUKS Encryption and Mapper Devices
Problem: First time setting up dual-LUKS — need to understand the relationship between raw partitions, mapper devices, and filesystems.
Context: P16g deployment, encrypting root and home separately.
The Fix:
# Encrypt root — prompts for YES (uppercase) then passphrase (twice)
cryptsetup luksFormat /dev/nvme0n1p3
# Open (decrypt) — creates /dev/mapper/cryptroot
cryptsetup open /dev/nvme0n1p3 cryptroot
# Encrypt home — can use a different passphrase
cryptsetup luksFormat /dev/nvme0n1p4
# Open — creates /dev/mapper/crypthome
cryptsetup open /dev/nvme0n1p4 crypthome
# Format the MAPPER devices (not the raw partitions)
mkfs.btrfs -L archroot /dev/mapper/cryptroot
mkfs.btrfs -L archhome /dev/mapper/crypthome
Rule: Always format and mount the mapper devices (/dev/mapper/cryptroot), never the raw partitions (/dev/nvme0n1p3). The raw partition holds ciphertext. The mapper device exposes plaintext. Formatting the raw partition destroys the LUKS header.
Worklog: WRKLOG-2026-04-02
2026-04-02: UUID Variable Pattern for crypttab
Problem: Need to reference partition UUIDs in /etc/crypttab without hardcoding. Manual UUID copy-paste is error-prone and causes boot failures if wrong.
Context: P16g phase 3, setting up /etc/crypttab for the second LUKS volume (crypthome). The first volume (cryptroot) is handled by the kernel cmdline.
The Fix:
# Capture UUID into variable — no manual copy-paste, no typo risk
HOME_LUKS_UUID=$(blkid -s UUID -o value /dev/nvme0n1p4)
echo "Home LUKS UUID: $HOME_LUKS_UUID"
# Write crypttab using the variable
# NOTE: unquoted EOF so $HOME_LUKS_UUID expands
cat > /etc/crypttab << EOF
crypthome UUID=$HOME_LUKS_UUID none luks,timeout=90
EOF
# Verify — should show the actual UUID, not the variable name
cat /etc/crypttab
Rule: Never hardcode UUIDs. Capture with blkid -s UUID -o value into a variable, then use in config files. Use unquoted EOF for variable expansion, quoted 'EOF' for literal strings. Always verify the written file to catch expansion failures.
Worklog: WRKLOG-2026-04-02
2026-04-02: btrfs Subvolume Layout and Mount Options
Problem: Need a subvolume strategy that isolates snapshots, logs, and data — each independently mountable and excludable from backups.
Context: P16g deployment, btrfs on top of LUKS. Matching the Razer’s production mount options.
The Fix:
# Create root subvolumes
mount /dev/mapper/cryptroot /mnt
btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@snapshots
btrfs subvolume create /mnt/@var_log
btrfs subvolume list /mnt
umount /mnt
# Create home subvolume
mount /dev/mapper/crypthome /mnt
btrfs subvolume create /mnt/@home
btrfs subvolume list /mnt
umount /mnt
# Mount with production options — order matters: root first, then children
mount -o noatime,compress=zstd:3,ssd,discard=async,space_cache=v2,subvol=@ /dev/mapper/cryptroot /mnt
mkdir -p /mnt/{boot,home,.snapshots,var/log}
mount -o noatime,compress=zstd:3,ssd,discard=async,space_cache=v2,subvol=/@snapshots /dev/mapper/cryptroot /mnt/.snapshots
mount -o noatime,compress=zstd:3,ssd,discard=async,space_cache=v2,subvol=/@var_log /dev/mapper/cryptroot /mnt/var/log
mount -o noatime,compress=zstd:3,ssd,discard=async,space_cache=v2,subvol=/@home /dev/mapper/crypthome /mnt/home
Rule: The @ prefix is convention (snapper, timeshift recognize it). Mount order: root first, then subvolumes, then /boot, then /boot/efi. noatime reduces writes, compress=zstd:3 is balanced speed/ratio, discard=async batches TRIM. Create /boot/efi AFTER mounting /boot — otherwise the ext4 mount overlays the directory.
Worklog: WRKLOG-2026-04-02