NFS mounts cause slow system startup

I’m moving from Gentoo on NixOS on my HTPC. I have things functionally working for the most part, but there are a still few loose ends I’m trying to figure out.

MY HTPC runs Kodi and plays media off a NAS, which I mount via NFS. Without the NFS mounts configured NixOS bots straight into an LXQt desktop running Kodi very quickly. However, when I enable the NFS mounts, there’s a ~30s delay right before loading the desktop. I’m trying to eliminate this delay (or at least shorten it as much as possible) as a short boot time is important for this use case.

Here’s how I have my NFS mounts defined:

  fileSystems."/home/media/data/videos" =
    { device = "nas:/data/videos";
      fsType = "nfs4";
      options = [ "sec=sys" "x-systemd.automount" ];
    };

dmesg shows this:

[    5.789011] amdgpu 0000:0b:00.0: [drm] fb0: amdgpudrmfb frame buffer device
[    6.403814] systemd-journald[600]: /var/log/journal/3f3740c629e741d68b35563971e25413/user-2000.journal: Journal file uses a different sequence number ID, rotating.
[    6.855630] r8169 0000:08:00.0 enp8s0: Link is Up - 1Gbps/Full - flow control off
[    7.380351] amdgpu 0000:0b:00.0: [drm] REG_WAIT timeout 1us * 100000 tries - optc1_wait_for_state line:839
[   33.584138] netfs: FS-Cache loaded
[   33.620828] Key type dns_resolver registered
[   33.720606] NFS: Registering the id_resolver key type
[   33.720612] Key type id_resolver registered
[   33.720614] Key type id_legacy registered

while Xorg.0.log shows this:

[     7.088] (--) AMDGPU(0): HDMI max TMDS frequency 300000KHz
[    33.890] (II) AMDGPU(0): EDID vendor "DON", prod id 107

X starts loading approximately 6 seconds into the boot, and gets to the point where it displays a a mouse cursor, then just hangs for ~30 seconds. Right after that “netfs: FS-Cache loaded” is printed in dmesg, X finishes loading into LXQt.

Any suggestions on how I can reduce this delay?

Aside from being new to NixOS I’m also pretty new to systemd, so I’m struggling to narrow this down further. I’m guessing there’s a dependency on the NFS mount that’s blocking the desktop from loading until it complete, but I don’t know how or where that’s being enforced. Is there some way to disable that? The NFS mounts need to exist before I play media, but not before LXQt and Kodi loads. I tried adding “noauto” to the NFS options thinking that may have it perform the amount upon first access, but it didn’t make a difference.

Alternatively, I compared this to one of my other systems still running Gentoo. That netfs: FS-Cache line doesn’t appear in my started, and it seems I don’t even have that feature enabled in the kernel, so it’s not necessary for my use case. Is there some way to disable that in NixOS? I tried searching for info about this but came up empty.

Would appreciate any help. Thanks!

1 Like

The delays are probably caused by unit ordering. My guess is that the nas mount tries to start before the network, fails and systemd retries it after a backoff. Try adding _netdev to the mount options – this should order the mount to start after the network starts. Also consider using nofail so that you don’t end up in the recovery shell if the nas decides that it’s not in the mood to allow mounts.

You should also take a look at systemd-analyze output and check journalctl -b to see what’s taking up the startup time.

3 Likes

@VTimofeenko - thanks so much for the pointers. _netdev didn’t make a difference, but systemd-analyze (first I’ve heard of that) revealed something very interesting:

# systemd-analyze blame
30.018s dhcpcd.service
<SNIP>

# systemd-analyze critical-chain
graphical.target @30.731s
└─multi-user.target @30.731s
  └─network-online.target @30.731s
    └─dhcpcd.service @711ms +30.018s
<SNIP>

dhcpcd is in the critical chain and taking 30s to complete. So that definitely looks like the culprit. I have my network interface configured for a static IP, but this system does have a wireless interface that I don’t use. Odd that’s not an issue without NFS, but once NFS is in the picture systemd decides it needs to try assigning an IP to all discovered interfaces, I guess?

Explicitly disable dhcp with networking.useDHCP = false; did the trick. Thank you!

I got curious and checked out why this happens. According to systemd.mount(5), network file systems are ordered after network-online.target. According to systemctl show -p Before,Type dhcpcd.service, the dhcpcd service is ordered before network-online.target and is considered started once it forks. Finally, according to dhcpcd(8), it forks after it acquires DHCP leases.

So yea, I’m guessing it just times out after 30 seconds on the unused interface, which it was configured to use because of networking.useDHCP. Then it finally forks and is considered started, which finally reaches network-online.target, which finally allows network file systems to mount.

systemd.network.wait-online.anyInterface might also help – the system is considered “online” when any interface is online rather than waiting all of them.

that’s for systemd-networkd, which is not in use here.

Not exactly. It affects the online target regardless of systemd-networkd: src

Again, that only affects systemd-networkd-wait-online.service. This is only a systemd-networkd thing. Those options are not interpreted by any other network implementation in NixOS. Nor could it be; the definition you linked is setting command line arguments specifically for use with the systemd-networkd-wait-online CLI

Huh, go figure. Yeah, I was wrong.