From a013737fbf6836fff5c5ff631f222f7ec0043802 Mon Sep 17 00:00:00 2001 From: ahmza Date: Wed, 5 Aug 2026 22:17:53 +0100 Subject: [PATCH] mount the games drive eagerly instead of on demand sdb (GAMES) is an ssd - samsung 870 qvo, rotational=0 - so unlike the two wd spinners there is no spin-down to gain from automounting it, and a steam library is better off never sitting behind a trigger. keeps nofail. dump and bak stay lazy. splits the old dataDrive helper into spinningDrive and eagerDrive and documents why each drive gets which. also records the steam gotcha found while debugging "steam library folder not writable": it was never a permissions problem - the drives are owned by uid 1000 mode 755 and were writable throughout. steam's fhs sandbox builds its bind list at launch by iterating /*, and /mnt does not exist on nixos until these fileSystems entries are activated, so a steam started before that has no /mnt for its entire lifetime. restarting steam is the fix. --- modules/hosts/shadow/disks.nix | 47 +++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/modules/hosts/shadow/disks.nix b/modules/hosts/shadow/disks.nix index cdd2207..3c44698 100644 --- a/modules/hosts/shadow/disks.nix +++ b/modules/hosts/shadow/disks.nix @@ -7,19 +7,23 @@ # definitions, nor produce duplicates for whichever data drives happened to # be mounted at the time it ran. flake.nixosModules.shadowDisks = {...}: let - # Secondary data drive, addressed by filesystem label. + # Secondary data drives, addressed by filesystem label. # - # noauto + x-systemd.automount makes systemd generate an .automount unit and - # mount on first access to the path rather than at boot — the two 2.7T - # spinners stay parked until something actually touches them. idle-timeout - # unmounts them again once quiet so they can spin back down. - # - # nofail matters even with automount: it stops a missing or dying disk from - # becoming a failed dependency that drops the boot into emergency mode. + # nofail on all of them: it stops a missing or dying disk from becoming a + # failed boot dependency that drops the machine into emergency mode. # # On-disk ownership is already ahmza mode 755 on all three, so no uid mapping # is needed — ext4 stores ownership in the filesystem and ignores uid=/gid=. - dataDrive = label: { + + # Spinning disks (sda/sdc, both WD, rotational=1). noauto + + # x-systemd.automount makes systemd generate an .automount unit and mount on + # first access to the path rather than at boot, so they stay parked until + # something actually touches them; idle-timeout unmounts them again once + # quiet so they can spin back down. + # + # Note the idle unmount fails with "target is busy" while any shell has its + # cwd inside the mount. That is harmless — it simply stays mounted and retries. + spinningDrive = label: { device = "/dev/disk/by-label/${label}"; fsType = "ext4"; options = [ @@ -30,6 +34,25 @@ "x-systemd.device-timeout=10" ]; }; + + # Always-on drive. Used for the games library: it is an SSD (Samsung 870 QVO, + # rotational=0) so there is no spin-down to gain, and a Steam library is + # better off never sitting behind an automount trigger. + # + # Unrelated but worth knowing, since it looks like a mount problem: Steam's + # FHS sandbox builds its bind list at launch by iterating /*, so a top-level + # directory that does not exist when Steam starts is invisible to that + # instance for its whole lifetime, and Steam reports it as "not writable". + # /mnt only comes into existence when these entries are activated, so Steam + # must be restarted after a fresh boot-time change here. + eagerDrive = label: { + device = "/dev/disk/by-label/${label}"; + fsType = "ext4"; + options = [ + "nofail" + "x-systemd.device-timeout=10" + ]; + }; in { fileSystems = { # Boot essentials, by UUID. UUIDs rather than labels here on purpose: @@ -46,9 +69,9 @@ options = ["fmask=0077" "dmask=0077"]; }; - "/mnt/dump" = dataDrive "DUMP"; - "/mnt/games" = dataDrive "GAMES"; - "/mnt/bak" = dataDrive "BAK"; + "/mnt/dump" = spinningDrive "DUMP"; + "/mnt/bak" = spinningDrive "BAK"; + "/mnt/games" = eagerDrive "GAMES"; }; swapDevices = [];