test(hibernate): #76 checks.hibernate-swapfile — verify swapfile+offset in a VM
All checks were successful
Check / eval (push) Successful in 4m18s
All checks were successful
Check / eval (push) Successful in 4m18s
Push #76's swapfile-resume residual into a VM as far as headlessly possible. A full hibernate→resume from a RUNTIME swapfile turned out not to be headless-reachable: systemd reports CanHibernate=no for a swap that isn't declared in the boot config, and a runtime-computed resume_offset can't be fed into the boot cmdline (the genuine chicken-and-egg). So the check now verifies, bounded and deterministically, what the partition test (checks.hibernate) can't and what a VM CAN prove: the installer's btrfs @swap swapfile is built correctly and its offset is valid — NOCOW mkswapfile, file-type swapon, a good `map-swapfile -r` offset the kernel accepts (/sys/power/resume_offset), and zram (prio 100) above it. The literal encrypted-swapfile power-cycle + LUKS-initrd unlock stays a V3 laptop check (the dev box runs exactly this layout, /proc/cmdline verified). (First cut had an unbounded wait_for_shutdown that hung on the CanHibernate refusal; rewritten with a thread-bounded wait + a CanHibernate pre-check, which gave the clean verdict. Device is /dev/vdb without useNixStoreImage.) Verification: V2 PASS (nix build .#checks.x86_64-linux.hibernate-swapfile, fresh, exit 0); flake check --no-build green. #76 residual narrowed in BACKLOG/ROADMAP. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -39,12 +39,21 @@ not Nomarchy, so it can't close it). Steps in HARDWARE-QUEUE. Design record in
|
||||
`@swap` swapfile + `resume_offset` wiring; `swapSize=0` = no-swap opt-out.
|
||||
- `docs/MIGRATION.md` enable-hibernation runbook (existing machines).
|
||||
- `rofi.nix` Power → Hibernate: kept unconditional, **notifies on failure**.
|
||||
- `checks.hibernate` VM test (V2 PASS) — hibernate→resume→crash round-trip;
|
||||
zram (prio 100) doesn't swallow the image, disk swap carries it.
|
||||
- `checks.hibernate` VM test (V2 PASS) — hibernate→resume→crash round-trip
|
||||
(swap partition); zram (prio 100) doesn't swallow the image, disk carries it.
|
||||
- `checks.hibernate-swapfile` VM test (V2 PASS) — the installer's btrfs `@swap`
|
||||
**swapfile** setup: NOCOW `mkswapfile`, file-type swapon, a valid
|
||||
`map-swapfile -r` offset the kernel accepts (`/sys/power/resume_offset`),
|
||||
zram above it. (Bounded proof of the swapfile+offset the partition test
|
||||
can't reach; a full runtime-swapfile hibernate isn't headless-reachable —
|
||||
systemd `CanHibernate=no` for undeclared swap.)
|
||||
|
||||
**V3 remaining:** real hibernate→resume on the LUKS+@swap swapfile+offset
|
||||
layout (QEMU can't feed a boot-time offset / drive LUKS-initrd) + the no-swap
|
||||
notify in a real session. Steps queued in HARDWARE-QUEUE. Close #76 on PASS.
|
||||
**V3 remaining (narrowed):** the literal encrypted-swapfile power-cycle —
|
||||
`Hibernate → power off → unlock LUKS → resume session` on the LUKS+@swap
|
||||
layout — plus the no-swap notify in a real session. QEMU can't feed a
|
||||
runtime-computed `resume_offset` into the boot cmdline, and the dev box runs
|
||||
exactly this layout (`/proc/cmdline` verified) but isn't Nomarchy. Steps in
|
||||
HARDWARE-QUEUE. Close #76 on PASS.
|
||||
|
||||
## LATER
|
||||
|
||||
|
||||
@@ -17,6 +17,28 @@ Template:
|
||||
|
||||
---
|
||||
|
||||
## 2026-07-11 — #76 checks.hibernate-swapfile (VM-verify the swapfile+offset)
|
||||
- **Task:** Bernardo — push #76's swapfile-resume residual into a VM (like
|
||||
the auto-theme sunset trick).
|
||||
- **Did:** Tried a full runtime-swapfile hibernate→resume test; it hit a
|
||||
bounded, definitive **`CanHibernate=no`** — systemd won't hibernate to a
|
||||
swap that isn't declared in the boot config, and a runtime-computed
|
||||
`resume_offset` can't reach the boot cmdline (the genuine chicken-and-egg).
|
||||
First cut also had an **unbounded `wait_for_shutdown`** that hung → killed
|
||||
it, bounded the wait in a thread (180s) + a `CanHibernate` pre-check, which
|
||||
is what surfaced the clean verdict. Pivoted `checks.hibernate-swapfile` to
|
||||
what a VM *can* prove deterministically and the partition test can't: the
|
||||
installer swapfile **build + offset** — NOCOW `mkswapfile`, file-type
|
||||
swapon, valid `map-swapfile -r` offset accepted by `/sys/power/resume_offset`,
|
||||
zram above it. (Device fix: `/dev/vdb` once `useNixStoreImage` was dropped.)
|
||||
- **Verified:** **V2 PASS** (fresh build, exit 0). BACKLOG/ROADMAP updated;
|
||||
#76 residual narrowed to the literal encrypted power-cycle (dev box runs it).
|
||||
- **Lesson:** the sunset-trick spirit applies but not always the full cycle —
|
||||
when systemd/kernel gates the behaviour (CanHibernate), verify the
|
||||
*construction* deterministically and leave only the physical cycle to HW.
|
||||
Always bound `wait_for_shutdown` (no timeout param → thread + join).
|
||||
- **Next suggestion:** #76/#79 both `[blocked:hw]`; QA / PROPOSED otherwise.
|
||||
|
||||
## 2026-07-11 — Code-review fixes (parallel review of the session batch)
|
||||
- **Task:** Bernardo asked for parallel work; spawned a fresh-eyes opus
|
||||
review of `2055842..HEAD` (static). It found the batch sound — 2 real LOW
|
||||
|
||||
Reference in New Issue
Block a user