Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

0007 — Boot-environment rollback model (three rungs, pre-boot)

Status: accepted (2026-06-22) — ratified by maintainer; proposed 2026-06-04

Context

System rollbacks happen pre-boot, inside keyboot — the one place the datasets are idle (so zfs rollback/clone can’t fail on a busy mount) and a half-running system can’t fight you or be corrupted. This is why ZFSBootMenu rolls back from its own environment, not the booted OS.

zfs rollback is per-dataset and in-place, and its -r/-R flags only destroy newer snapshots/clones of the same dataset — they do not recurse into children (a common trap; zfs snapshot -r is recursive, rollback is not). So any whole-system operation must iterate the recursive snapshot set (ADR 0006 names), and rollback is not a single atomic command.

Decision

keyboot’s BE menu offers an escalating ladder, all operating on the recursive snapshot set (root + BE-scoped /var + BE-scoped /home at the same name; persistent rpool/data/* untouched):

  1. Boot read-only — boot the snapshot RO; zero side effects. Inspect.
  2. Rollback-clone (default, recommended) — clone the recursive snapshot set into a new BE and boot it. The original BE + timeline are untouched; reversible (destroy the clone). Adopt with keyboot-install be promote.
  3. Rollback-destroyzfs rollback -r each dataset in the set; discards all newer snapshots. Irreversible; explicit, unmistakable confirmation.
  • Default system-rollback = consistent point-in-time across the BE-scoped set (ADR 0005). Mixing versions (e.g. old /var, current /home) is a deliberate recovery-shell, manual action — and is always safe because the only separately-rollbackable datasets are binary-independent (ADR 0005 keeps the package DB inside the BE).

Guards (the “many checks”)

  • Rollback-destroy must detect dependent clones and REFUSE. zfs rollback -r fails if a newer snapshot has a clone; the only force-past is -R -f, which destroys those clones — which may be other boot environments. The script must never auto-escalate to -R -f; it refuses with a clear message (“snapshot X is the origin of BE gentoo-test; promote or destroy it first”).
  • Clone → promote lifecycle. A clone is tethered to its origin snapshot; you can’t reclaim the old timeline until be promote flips the origin. Keep the clone if good (be promote), destroy it if not (original pristine).
  • Visual unmistakability. The menu marks rung 3 as irreversible and separates it from the safe rungs.

Alternatives considered

  • Only zfs rollback (destructive): loses the forward timeline and footguns on dependent clones. Kept as rung 3 only, guarded.
  • Only clone-and-boot: can’t “just undo” or reclaim space immediately. Kept as rung 2 (default).
  • In-OS rollback (from the booted system): dataset busy, can corrupt a running system. Rejected — pre-boot only.
  • Recurse children automatically via some rollback -r magic: does not exist in ZFS. Rejected (script iterates the set).

Consequences

  • The rollback engine is a checks-heavy script in keyboot’s recovery/menu stage (stage-8), using the full ZFS toolkit keyboot already ships.
  • keyboot-install be {clone, promote, destroy} (SPEC §14) are the clone lifecycle primitives this builds on.
  • Depends on ADR 0006’s recursive, consistently-named snapshot set.
  • The BE-scoped-/home default (ADR 0005) is safe because rung 2 is the default — clone-and-boot never destroys current /home; only the explicit rung 3 could, and only with confirmation.