Commit Graph
7 Commits
Author SHA1 Message Date
ahmza 67bafd4f73 switch to open nvidia modules and make sleep transitions actually work
three related changes, all needed together to get this card through a
sleep cycle with its framebuffer intact.

open = true. mandatory to set explicitly on driver >= 560, where the
option defaults to null and nixpkgs asserts against null. true because
every card this module targets is turing or later, which is what upstream
recommends open modules for. mkDefault so a future pre-turing host can
override at host level - and note that without it, importing both
gpuNvidia and gpuNvidiaPrime would be an outright merge conflict rather
than something resolvable. this selects between two real builds of the
same release, nvidia-open vs the proprietary kernel modules; it has no
effect on driver version. confirmed after reboot:
/proc/driver/nvidia/version reports the open module.

kernelSuspendNotifier = false. nixpkgs defaults this to
`useOpenModules && version >= 595`, which is silently true here, and that
path wedges the gpu on resume - nv_pm_notifier warns, the card never
comes back, and an unrecoverable gsp rpc storm follows. pinning it false
selects the nvidia-{suspend,hibernate,resume}.service path instead.

installing upstream's system-sleep hook, because those units are wired
only to systemd-{suspend,hibernate}.service, while suspend-then-hibernate
runs as a single systemd-suspend-then-hibernate.service that performs
both transitions internally. no nvidia unit fires for it at all - the
units cannot express it, which is exactly why nvidia ships the hook.
nixpkgs sets systemd.packages from the driver package, but that only
collects lib/systemd/system/, never lib/systemd/system-sleep/, so the
hook is silently discarded.

it cannot be installed verbatim, for two separate reasons.

first, past its suspend-then-hibernate branch it ends in an
unconditional `case "$1" in post) nvidia-sleep.sh resume`. for plain
suspend that duplicates nvidia-resume.service, and destructively:
nvidia-sleep.sh's RestoreVT reads /run/nvidia-sleep/Xorg.vt_number,
deletes it, then chvt's back. chvt lives in pkgs.kbd, which nixpkgs puts
on nvidia-resume.service's path but which is absent from the stripped
path systemd-sleep gives its hooks. the hook would consume the vt file,
fail to chvt, and the real unit would then find nothing to restore.

second, its suspend-then-hibernate dispatch handles post:*,
pre:hibernate and pre:suspend-after-failed-hibernate - but there is no
pre:suspend, which is the *first* leg of suspend-then-hibernate. it
matched nothing, fell through, and the driver never got its vram-spool
handshake, so with NVreg_PreserveVideoMemoryAllocations=1 the gpu refused
to suspend and the whole operation aborted:

  nvidia 0000:2d:00.0: PM: failed to suspend async: error -5
  PM: Some devices failed to suspend, or early wake event detected
  systemd-sleep: Failed to put system to sleep. System resumed again:
    Input/output error

so the wrapper gates out everything except suspend-then-hibernate, fills
in pre:suspend the same way upstream fills in pre:hibernate, and hands
the rest to upstream unchanged. worth reporting upstream - as shipped
that hook cannot work for suspend-then-hibernate whenever
PreserveVideoMemoryAllocations is on.

verified on hardware: plain suspend and plain hibernate both clean with
no chvt failure and the vt file consumed by the right unit, and a full
suspend-then-hibernate cycle now runs all four transitions - suspend
entry (deep), rtc wake, hibernation entry, hibernation exit.
2026-08-06 17:08:55 +01:00
ahmza fc1772e5db pin the bootloader explicitly and bound the grub menu to 10 generations
grub.enable defaults to true, so adding a boot.loader block silently
switched this host from the systemd-boot it was installed with over to
grub. nixos removes neither the old bootloader's files nor its nvram
entry, so both lived on the esp and the firmware kept booting a frozen
systemd-boot menu. pinning both options means a conflicting definition
elsewhere now fails loudly instead of quietly winning. note the pins
delete nothing - stale EFI/systemd/, loader/ and the leftover nvram entry
still have to be cleared by hand. done on shadow, not verified on t480.

configurationLimit bounds esp usage for real, not just the menu:
install-grub.pl unlinks any $boot/kernels/* that no kept generation
references. sizing measured on shadow rather than assumed - 10 kept
generations referenced 1 bzImage and 3 initrds for 114mib total, about
11mib per generation, because generations share aggressively. the
worst case is higher, around 47mib each, since nixpkgs embeds
/etc/modprobe.d/nixos.conf inside the initrd and so every kernel module
parameter edit mints a fresh one. 10 therefore costs ~115mib typically
and ~470mib worst case against a 1gib esp that also carries the grub
modules, the catppuccin theme, and windows' own boot files.

keeping it conservative matters because overflow fails as `copy ... or
die` in install-grub.pl, which runs *after* the system profile has
already been switched - the result is an activated but unbootable
generation. t480 reaches this module too and its esp may be smaller.
2026-08-06 17:08:15 +01:00
ahmza e556cb31af enable quickshell in hyprland to eventually replace waybar. nix-ld also updated to enable qmlls in nvim 2026-08-06 14:02:26 +01:00
ahmza 4535616799 move hardware config in-repo per-host and mount the data drives
importing /etc/nixos/hardware-configuration.nix by absolute path from the
shared core module had two problems: it made the flake impure (every eval
needed --impure, since the file lives outside the store) and both hosts
resolved to whichever machine's file was on disk, so evaluating t480 on shadow
silently baked in shadow's disk uuids.

shadow now carries its own generated scan at modules/hosts/shadow/_hardware.nix.
the leading underscore keeps import-tree from picking it up as a flake-parts
module - its filter drops any path containing "/_" - so it is imported
explicitly from the host's default.nix.

it is generated with --no-filesystems and all of shadow's filesystems are
declared by hand in disks.nix instead. that split is what makes regeneration
safe: nixos-generate-config emits fileSystems for whatever is mounted at the
time, which would otherwise conflict with the entries below every time the data
drives happened to be mounted. `nix run .#sync-hardware` refreshes the file.

DUMP/GAMES/BAK are mounted by label at /mnt/{dump,games,bak} with
noauto + x-systemd.automount, so the two 2.7T spinners stay parked until
something touches the path and spin back down after 10 minutes idle. nofail
keeps a missing disk from dropping the boot into emergency mode.

/ and /boot are unchanged - still the same uuids, verified identical to the
previous evaluation. t480 keeps the absolute import for now with a TODO; its
scan can only be generated on the machine itself.
2026-08-05 22:06:01 +01:00
ahmza 56cf8f875f allow passwordless sudo for ahmza
adds security.sudo.extraRules with NOPASSWD: ALL. the rule is emitted after the default %wheel SETENV rule and sudoers is last-match-wins, so it takes precedence. lives in the shared user module, so it applies to both shadow and t480.
2026-08-05 21:51:26 +01:00
ahmza 9ded51c865 changes to move opencode to nixpkgs unstable - more up to date and fixes breaking bugs 2026-08-05 21:27:51 +01:00
ahmza dda5d14d63 initial commit 2026-08-05 18:57:23 +01:00