Hibernation with disk encryption

Hello all.

I’m trying to understand the workings of hibernation on encrypted swap in Linux in general and NixOS in particular, and would greatly appreciate if someone could clarify my understanding on a few points. I am terribly sorry in advance if I have completely misunderstood the whole thing and none of my questions make sense.

  1. Kernel documentation on the topic warns against mounting any filesystems between hibernation and resuming. At the same time, documentation for fileSystems.<name>.neededForBoot NixOS option indicates that at least /nix/store is mounted in the initial ramdisk. Am I to understand that this doesn’t happen when resuming?

  2. If so, how does that interact with swapDevices.*.encrypted.keyFile NixOS option? Its documentation suggests that all of the neededForBoot filesystems are mounted prior to consulting this file; am I to understand that this, too, doesn’t happen when resuming from hibernation, and so the swap partition used for hibernation cannot be encrypted with a key file?

  3. But it can be encrypted with a password, right? As in, if I just set swapDevices.*.encrypted.enable, .blkDev and .label, and set up encrypted partition accordingly, hibernation should (at least in theory) work and not leave me at a risk of data loss implied in p.1? Arch wiki article on the topic suggests adding custom mkinitcpio hook — is that relevant for NixOS?

  4. On a somewhat tangential note, boot.resumeDevice option documentation seems to indicate that swap devices should be tried automatically, but on my (normally booted) system there are no resume= parameters in /proc/cmdline, and /sys/power/resume is 0:0, which are the two ways the aforementioned kernel documentation page suggests for specifying resume device (I do have swap enabled, as verified by lsblk). Is this done through some separate mechanism, or should I disregard the documentation and specify boot.resumeDevice manually? Or the relevant kernel options are somehow provided only if there is a hibernation image?

I suppose some of these questions are answerable with a bit of experimentation on my end, but after seeing stern warnings about data loss in kernel docs I am a bit anxious about blindly trying things without checking my understanding first.

1 Like

So I did what I should have done from the beginning and poked around the source, and I think I have found all the answers; I would still be grateful if someone with actual knowledge about the relevant parts of the boot process could double-check my conclusions.

  1. Devices encrypted with and without a key file are treated very differently. Devices that do not require a key file (and use a password) are added to LUKS devices, whereas those that use a key file are unlocked separately in postMountCommands.

  2. Commands to unlock configured LUKS devices are added either to preLVMCommands or postDeviceCommands, depending on their configuration; either way, they are unlocked fairly early in stage 1 init.

  3. After that stage 1 init iterates over all configured swap devices, and checks each of them in turn for hibernation image. Notably, at that point, encrypted-with-a-password swap devices are already unlocked and therefore eligible.

  4. If a hibernation image is found, stage 1 init script then tells the kernel to resume from it by writing to /sys/power/resume. Writing to it apparently restores system from hibernation immediately, and skips the rest of the script. (Am I understanding this right? Pending actual experiment, I am basing my understanding on this 15 year old e-mail.)

  5. Only if the system did not resume from hibernation for some reason are neededForBoot filesystems mounted, and only after that are postMountCommands executed, including unlocking encrypted partitions that use a key file.

So, to answer my own questions

  1. Yes, neededForBoot filesystems are not mounted when resuming, because resuming logic comes before mounting them in the init sequence.
  2. Swap partitions locked with a key file are simply never searched for hibernation images, because they are unlocked too late for that.
  3. I will need to actually try that when I have the time again, but it seems that it should just work, without any additional hooks.
  4. The last option; hibernation images are detected independently of the kernel resume= option, and the kernel is made aware of them only if/when they are found.