← notes

A laptop that died asleep, and a grep that found nothing

Sep 21, 2026

Suspended at 30%, found flat 82 hours later. Three things had to be true at once, and none were visible.

The laptop suspended on a lid close at 30% and was found flat 82 hours later. Three things had to be true at once for that to happen, and none of them were visible without reading the journal after the fact.

Suspend was using s2idle, not deep sleep, at about 1.3% an hour. The kernel flag that selects deep had been added the day before, but the machine had not rebooted since, so no suspend ever saw it. The fix was already written. It just was not running.

The power daemon did nothing at 2%. Its stock critical action is Auto, which tries hybrid sleep, then hibernate, then power off, and power off is refused unless a separate setting marked risky allows it. With hibernate unavailable, Auto had nowhere to land. It now names power off and allows it.

Hibernate was unavailable because the password manager’s desktop app holds a memfd_secret region, and the kernel will not hibernate while one exists. The kernel lists these as /secretmem rather than memfd:secret, so the obvious grep finds nothing and the obvious conclusion is that nothing is holding it.

The lid now asks for the generic sleep operation, which walks a list in order: suspend then hibernate when hibernate works, plain suspend when it does not. The drop-in for that is copied into /etc rather than symlinked like everything else in the repo, because the login daemon runs with its home directory hidden, so a symlink into /home is invisible from inside its sandbox and the file is skipped in silence.

The verification had its own bug. It parsed the daemon’s output with tr -d 's "' to strip the type prefix, which also strips every lowercase s from the value, so “sleep” came back as “leep”. It had passed on the first check only because “PowerOff” contains no lowercase s.

A hook now writes one line per suspend and flags any that ended within two minutes. On a normal day there are 1 to 6. On 2026-09-16, charging over USB-C, there were 113.