fix(snapshots): un-break the GUI — polkit agent + launcher, not an override
All checks were successful
Check / eval (push) Successful in 3m4s

Re-diagnosis of the "btrfs-assistant 2.2 segfaults on launch" bug, and
the fix is not the planned nixpkgs override:

1. gdb: the crash is btrfs_util_subvolume_iterator_next() —
   libbtrfsutil's UNPRIVILEGED subvolume-iteration path in btrfs-progs
   6.17.1 (upstream-fixed after 6.17.1, kdave/btrfs-progs 886571653).
   Symbol versions were checked and match: not ABI/link drift.
2. VM A/B on real btrfs: as root it works (exit 0); as a user it
   segfaults (139). The pkexec launcher runs it as root — so the GUI
   path was fine all along, except…
3. …the distro shipped NO polkit authentication agent: every pkexec
   prompt in the session failed silently. That is the actual root
   cause of "the GUI doesn't open".

Shipped: hyprpolkitagent (Hyprland's Qt agent — the prompt is
Stylix-themed) via exec-once in hyprland.nix; `nomarchy-menu snapshot`
prefers btrfs-assistant-launcher again, with the nomarchy-snapshots
fzf flow kept as fallback (and for SSH); checks.snapshot-gui guards
the root path + offscreen GUI event loop on a real btrfs volume so a
lock bump can't silently regress it. No btrfs-progs patch: all our
flows are root-side; the unprivileged fix arrives with a lock bump.

Verified: V0 (flake check) + V2 (snapshot-gui check, executed green) +
V1 (HM generation builds; hyprland.conf carries the agent exec-once;
generated menu passes bash -n with the launcher wiring). Remaining V3
queued: first on-hardware themed polkit prompt.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Bernardo Magri
2026-07-04 10:07:40 +01:00
parent baab2d3b88
commit a47aa3aff5
9 changed files with 107 additions and 34 deletions

View File

@@ -200,6 +200,12 @@ in
# Paint the wallpaper as soon as the session is up (waits for
# the daemon internally).
"nomarchy-theme-sync wallpaper"
# Polkit authentication agent — without one, EVERY pkexec/polkit
# prompt in the session fails silently (btrfs-assistant-launcher
# was the discovery case). hyprpolkitagent is Hyprland's own Qt
# agent, so the prompt is Stylix-themed like every other Qt
# surface. Its binary lives in libexec (not bin), hence the path.
"${pkgs.hyprpolkitagent}/libexec/hyprpolkitagent"
# Waybar is launched here rather than as a systemd user service: bound
# to graphical-session.target the unit raced Hyprland's IPC on relogin
# and landed in `failed`; exec-once only fires once the compositor is

View File

@@ -404,11 +404,17 @@ ${themeRows}
exit 0 ;;
snapshot)
# btrfs-assistant 2.2 segfaults on 26.05 (libbtrfsutil ABI), so launch
# the keyboard-driven snapper browser instead: a terminal running it
# via sudo (snapper is root-only here one password prompt), with
# browse/diff, restore (undochange) and rollback, each confirmed.
# Snapshot browse/restore the btrfs-assistant GUI via its pkexec
# launcher. The "2.2 segfaults on 26.05" diagnosis was HALF right:
# only UNPRIVILEGED runs crash (libbtrfsutil unprivileged subvolume
# iteration, btrfs-progs 6.17.1; fixed upstream after) as root it
# runs fine, and the launcher runs it as root. The prompt needs the
# session polkit agent (hyprpolkitagent, exec-once in hyprland.nix).
# Fallback: nomarchy-snapshots, the keyboard-driven fzf browser in a
# terminal (kept installed also nice over SSH).
# Self-gated to nomarchy.system.snapper, so it no-ops elsewhere.
command -v btrfs-assistant-launcher >/dev/null 2>&1 \
&& exec btrfs-assistant-launcher
command -v nomarchy-snapshots >/dev/null 2>&1 \
|| { notify-send "Snapshots" "Snapshot tools unavailable (nomarchy.system.snapper off?)."; exit 0; }
exec ${cfg.terminal} -e sudo nomarchy-snapshots ;;

View File

@@ -344,13 +344,17 @@ in
nixos-rebuild switch --flake /etc/nixos#default "$@"
'')
# The desktop snapshot manager (browse / diff / restore / rollback over
# snapper, elevating via polkit). Kept for when nixpkgs fixes its crash.
# snapper, elevating via polkit) — the primary `nomarchy-menu snapshot`
# target. The "2.2 segfault" is unprivileged-only (libbtrfsutil
# unprivileged subvolume iteration, btrfs-progs 6.17.1, fixed upstream
# after); the pkexec launcher runs it as root, where it works —
# VM-proven, guarded by checks.snapshot-gui.
++ lib.optional cfg.snapper.enable pkgs.btrfs-assistant
# Keyboard-driven snapper browser/restore — the fallback `nomarchy-menu
# snapshot` actually launches while btrfs-assistant 2.2 segfaults on 26.05
# (libbtrfsutil ABI). Runs as root (snapper is root-only here; the menu
# opens it in a terminal via sudo, one password prompt), fzf to pick, with
# browse/diff (read-only) and typed-`yes` confirmation before any write.
# Keyboard-driven snapper browser/restore — the menu's fallback when the
# GUI is absent, and handy over SSH. Runs as root (snapper is root-only
# here; the menu opens it in a terminal via sudo, one password prompt),
# fzf to pick, with browse/diff (read-only) and typed-`yes` confirmation
# before any write.
++ lib.optional cfg.snapper.enable (pkgs.writeShellApplication {
name = "nomarchy-snapshots";
runtimeInputs = with pkgs; [ snapper fzf gawk gnugrep less coreutils systemd ];