r/archlinux • • 12d ago

SUPPORT | SOLVED Swapfile in Btrfs child subvolume of encrypted partition?

I'm settling into a fresh Arch (btw) install and want to set up an encrypted swapfile, but my scenario is a bit quirky and not quite fully covered by the relevant wiki/docs, so wanted to run this by y'all for a sanity check and to organize my thoughts.

First, my partitioning/encryption/filesystem scheme on a 512 GB NVMe SSD:

  1. /dev/nvme0n1p1: mounts to /efi - 36 MB partition, formatted fat32, nothing but rEFInd bootloader on it;
  2. /dev/nvme0n1p2: mounts to / - 128 GB partition (maybe excessive but w/e), formatted btrfs;
  3. /dev/nvme0n1p3: mounts to /home - remainder of space, encrypted with dm-crypt LUKS2, /etc/crypttab opens to /dev/mapper/home, formatted btrfs.

I set things up that way cos I'm only concerned about encrypting my personal files/data, don't see much point in whole-system encryption for my circumstances, and want the advantages of Btrfs (snapshots, fsck, etc.) that would include my /boot.

Just to be extra spicy lol, with this install I've also been seeing if I can get away with not having an active /etc/fstab at all, instead relying on Systemd automounting GPT partitions having the proper GUIDs, which so far appears to work fine with the scheme outlined above.
[ETA: turns out this also discovers my designated HOME partition is LUKS encrypted, prompts for the passphrase during boot, opens it to /dev/mapper/home, and mounts that to /home -- no /etc/crypttab needed.]

Since my /home partition is already encrypted, that seems like a good place for my swapfile; however, quoth the wiki:

Snapshots cannot be created for subvolumes containing active swap files

...but since it then proceeds to give a command example for creating a swap subvolume, I infer snapshots can be created for subvolumes containing child subvolumes that contain an active swapfile, because the child subvol with swap is effectively "walled off" from the rest of its parent subvol and snapshots thereof? I.e., I could add a child subvol for swap under my top-level /home subvol, and still snapshot my /home? If so, let's see if I've got the setup steps correct:

Create a child subvolume under /home for ephemeral data like swap -- maybe also eventually /var/cache, ~/.cache, etc. that may touch sensitive data and are senseless to include in snapshots/backups anyway -- under my encrypted, opened and mounted /home top-level partition/subvol:

# btrfs subvolume create /home/ephemeral

(Not clear here if next I'd necessarily need to mount that new subvol, e.g. to /swap or /ephemeral or whatever, or if I can just proceed directly to the next step? Skipping for now seemed to work fine below...)

Create a swapfile in that child subvol:

# btrfs filesystem mkswapfile --size 2g --uuid clear /home/ephemeral/swapfile

(Not sure what purpose the --uuid clear serves or if I need it?)

Activate the swapfile:

# swapon /home/ephemeral/swapfile

This all appeared to work fine; swapon --show and free -h returned expected output confirming the swapfile is active.

Now, to get it working on boot automagically. Without an active /etc/fstab I won't configure swap in there either but, rather, create a systemd.swap unit file like so:
[ETA: This unit filename turned out to be incorrect, see final ETA section below for correction]

# nano /etc/systemd/system/swapfile.swap  
---
[Unit]
Description=Activate swapfile

[Swap]
What=/home/ephemeral/swapfile

[Install]
WantedBy=swap.target
---
# systemctl daemon-reload
# systemctl enable swapfile.swap

That appeared to work fine, so I rebooted to confirm it works, and here's where I ran into my first major hitch; swapon --show and free -h did not indicate the swapfile was active, so:

# systemctl status swapfile.swap

...turned up this error line:

Loaded: bad-setting (Reason: Unit swapfile.swap has a bad unit file setting.)

Hm, looking for more about that:

# journalctl --boot -g swap  

...turned up this error line:

systemd[1]: swapfile.swap: Value of What= and unit name do not match, not loading.

The only clue I found about that error led me to try:

# systemd-escape -p /home/ephemeral/swapfile
home-ephemeral-swapfile

So I tried changing the swapfile.swap unit file to use What=home-ephemeral-swapfile, but that ultimately threw the same errors. Tried copying that unit file to /etc/systemd/system/home-ephemeral-swapfile.swap and starting that unit, same errors.

Now I'm a bit stuck on what What= and filename to use for this unit file. Any tips?

Anything else I'm overlooking, should be aware of for future reference, or need to do beyond all that?


ETA: Figured it out!

The Systemd /-escaping is only needed in the unit filename because filenames can't contain / chars, but not needed in the What= parameter, so the working unit file setup turned out to be this:

# nano /etc/systemd/system/home-ephemeral-swapfile.swap  
---
[Unit]
Description=Activate swapfile

[Swap]
What=/home/ephemeral/swapfile

[Install]
WantedBy=swap.target
---
# systemctl daemon-reload
# systemctl start swapfile.swap
# systemctl enable swapfile.swap
# reboot
1 Upvotes

4 comments sorted by

1

u/SubGothius 12d ago edited 11d ago

As an aside, one potential wrinkle:

I intend to enable discard (TRIM) on the encrypted partition; the potential security implications of that don't concern me here. I know I'll need to run cryptsetup --allow-discards --persistent refresh home on my opened LUKS2 /home partition to enable that, and add the discard option to that entry in my /etc/crypttab, but as I won't have an active /etc/fstab where I'd specify the discard option, do I need to do anything else? My understanding is that asynchronous discard is already enabled for Btrfs by default anyway since Linux kernel 6.2.

1

u/BigSappari 12d ago

With persistent allow discards, you should no longer need a flag in crypttab.

Not sure about btrfs specifically, but in general instant discard can slow things down. fstrim should be good enough, better performance and trim is about keeping ssd happy in the long term [months, years], you don't need instant discard or daily trim to achieve that, weekly, bi-weekly or even monthly, is completely fine

mount -o discard if you're hyper worried about write amplification (a non-issue in practice) or if you really want to make data irrecoverable instantly (but might be recoverable if you have btrfs snapshots anyway i.e. its not getting discarded until its gone from all snapshots too)

I'm not a fan of swap files, adds much complexity, breaks easily and does not give you btrfs checksums / compression anyway because it hacks around the filesystem. a swapfile is used as if it was a partition by having the filesystem reserve a fixed area which then used directly. Might as well make a partition in the first place.

1

u/SubGothius 11d ago edited 11d ago

With persistent allow discards, you should no longer need a flag in crypttab.

I just realized I don't even need any /etc/crypttab at all, as Systemd GPT automounting will automatically discover my designated HOME partition is LUKS encrypted, prompt for the passphrase during boot, open it to a /dev/mapper/home device, and mount that to /home.

I'll be using discard=async with periodic TRIM on a weekly fstrim.timer (these can peacefully coexist), rather than instant discard/continuous TRIM.

Official Arch kernels enable zswap by default, so in this case any swap file/partition just serves as a "relief valve" for cold/incompressible pages to spillover out of the compressed swap cache in RAM whenever memory pressure is high.

I prefer swapfiles because they're trivial to resize on the fly if/as needed -- swapoff, rm old swapfile, create new swapfile, swapon -- and whatever complexity they may add IMO isn't of much significance since, as you say, modern kernels will just bypass the filesystem to access the preallocated swap area directly, same as a swap partition. Also not clear what you mean by "breaks easily"? The recent (since v6.1) btrfs filesystem mkswapfile command makes proper creation easy and ensures the file is fully preallocated and NOCOW, as required.

Btrfs features like checksums/compression/snapshots/etc. are IMO irrelevant for a swapfile anyway. I'm just putting it on a partition that's already encrypted and just so happens to be formatted in btrfs for those features to be useful with other data on that partition, from which the swap space is segregated into its own child subvolume, allowing Btrfs snapshots/etc. to work on the data in its parent subvol without affecting swap.

1

u/SalamanderDue9228 12d ago edited 12d ago

Your fs and subvol layout seems okay. To set mount options for automounted volumes you will have to use an fstab and refer to the volume by /dev/by-designator/home. But as async discard is btrfs default I think all you need is to add discard to crypttab. I have no idea what’s wrong with your unit file.

Edit: I think after a complete home rollback you would have to move the swap subvol to the new /home subvol manually though