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.
This commit is contained in:
2026-08-05 22:17:53 +01:00
parent 4535616799
commit a013737fbf
+35 -12
View File
@@ -7,19 +7,23 @@
# definitions, nor produce duplicates for whichever data drives happened to # definitions, nor produce duplicates for whichever data drives happened to
# be mounted at the time it ran. # be mounted at the time it ran.
flake.nixosModules.shadowDisks = {...}: let 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 # nofail on all of them: it stops a missing or dying disk from becoming a
# mount on first access to the path rather than at boot — the two 2.7T # failed boot dependency that drops the machine into emergency mode.
# 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.
# #
# On-disk ownership is already ahmza mode 755 on all three, so no uid mapping # 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=. # 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}"; device = "/dev/disk/by-label/${label}";
fsType = "ext4"; fsType = "ext4";
options = [ options = [
@@ -30,6 +34,25 @@
"x-systemd.device-timeout=10" "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 { in {
fileSystems = { fileSystems = {
# Boot essentials, by UUID. UUIDs rather than labels here on purpose: # Boot essentials, by UUID. UUIDs rather than labels here on purpose:
@@ -46,9 +69,9 @@
options = ["fmask=0077" "dmask=0077"]; options = ["fmask=0077" "dmask=0077"];
}; };
"/mnt/dump" = dataDrive "DUMP"; "/mnt/dump" = spinningDrive "DUMP";
"/mnt/games" = dataDrive "GAMES"; "/mnt/bak" = spinningDrive "BAK";
"/mnt/bak" = dataDrive "BAK"; "/mnt/games" = eagerDrive "GAMES";
}; };
swapDevices = []; swapDevices = [];