From b65736c0dc2d9f8050480b7f20d67c49a8354516 Mon Sep 17 00:00:00 2001 From: beatzaplenty Date: Mon, 27 Jul 2026 04:14:18 +1000 Subject: [PATCH] =?UTF-8?q?fix(pxe-boot):=20fix=20NFS=20mount=20in=20LXC?= =?UTF-8?q?=20=E2=80=94=20NFSv3+nolock=20and=20skip=20rpc=5Fpipefs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Proxmox LXC containers block the sunrpc filesystem (rpc_pipefs) via AppArmor unless the container has `features: mount=nfs` set. NFSv4 requires rpc_pipefs for client state management, so the mount fails outright in a default LXC. Two fixes for the LXC case (config.boot.isContainer): - Switch from nfsvers=4.2 to nfsvers=3,proto=tcp,nolock,nofail: NFSv3 doesn't need rpc_pipefs at the protocol level, and nofail keeps boot clean if the NFS server is unreachable. - Add ConditionVirtualization=!container to var-lib-nfs-rpc_pipefs.mount via systemd drop-in: NixOS pulls this unit into nfs-client.target for any NFS fileSystems entry. With the condition, systemd skips (not fails) the unit in containers, keeping nfs-client.target green and activation reporting clean. Proxmox VM hosts (not isContainer) continue to use nfsvers=4.2 with x-systemd.automount unchanged. Co-Authored-By: Claude Sonnet 4.6 --- modules/pxe-boot/mount-pxe-images.nix | 34 ++++++++++++++++++++------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/modules/pxe-boot/mount-pxe-images.nix b/modules/pxe-boot/mount-pxe-images.nix index 853ab08..656562f 100644 --- a/modules/pxe-boot/mount-pxe-images.nix +++ b/modules/pxe-boot/mount-pxe-images.nix @@ -1,24 +1,42 @@ -{ config, vars, ... }: +{ config, lib, vars, ... }: let # Use the same FQDN approach as docker/mount-data.nix — a bare hostname is # unreliable: systemd-resolved only tries LLMNR for single-label names, and # a global search domain causes it to skip the interface-scoped LAN DNS. nfsServer = "${vars.nfsServerHost}.${vars.homeDomain}"; - - # x-systemd.automount is unsupported inside LXC containers (systemd logs - # "Starting of .automount unsupported" and never mounts). Use nofail - # there so a boot with the NFS server unreachable doesn't hang instead. - automountOpts = if config.boot.isContainer then [ "nofail" ] else [ "x-systemd.automount" ]; in { fileSystems.${vars.nfsShares.proxmoxPxeImages.mountpoint} = { device = "${nfsServer}:${vars.storageRoot}/${vars.nfsShares.proxmoxPxeImages.subpath}"; fsType = "nfs"; options = [ - "nfsvers=4.2" "_netdev" "noatime" - ] ++ automountOpts; + ] ++ (if config.boot.isContainer + # NFSv4 requires rpc_pipefs (sunrpc filesystem), which Proxmox LXC + # containers block unless `features: mount=nfs` is set. Use NFSv3+nolock + # instead: no rpc_pipefs dependency at the protocol level, and rpcbind + # on the server handles port resolution without needing client-side + # sunrpc infrastructure. nofail keeps boot clean if server is unreachable. + then [ "nfsvers=3" "proto=tcp" "nolock" "nofail" ] + else [ "nfsvers=4.2" "x-systemd.automount" ]); + }; + + # NixOS pulls var-lib-nfs-rpc_pipefs.mount (the sunrpc filesystem) into + # nfs-client.target for any nfs fileSystems entry. In LXC containers the + # sunrpc mount is blocked by Proxmox's AppArmor profile, causing it to fail + # and the activation to report an error even though our mount uses nofail. + # Add ConditionVirtualization=!container via drop-in so systemd skips the + # unit entirely in containers (skip = inactive, not failed), which keeps + # nfs-client.target green and activation clean. + systemd.units = lib.mkIf config.boot.isContainer { + "var-lib-nfs-rpc_pipefs.mount" = { + overrideStrategy = "asDropin"; + text = '' + [Unit] + ConditionVirtualization=!container + ''; + }; }; }