Short version: 1. nfsmount(8klibc) is still explicitly broken for NFSv4. 2. mount.nfs(8nfs-utils) works in the ramdisk. 3. A single mount(2) call also works!
Boring detailed version follows. John Goerzen wrote: > nfsmount is incapable of mounting NFSv4 filesystems. It seems to have > support for v3 and maybe v2, but not v4. This is still the case in Debian 11, klibc-utils=2.0.8-6.1. A workaround is to copy nfs-utils 1.3's mount.nfs into the initrd: /usr/share/initramfs-tools/hooks/zz-nfs4: #!/bin/sh [ prereqs = "$1" ] && exit . /usr/share/initramfs-tools/hook-functions copy_exec /sbin/mount.nfs /bin/nfsmount Here are some specific errors I saw, with an NFSv4-only server on 10.0.2.100 port 2049/tcp # Normal nfs-common=1:1.3.4-6 works fine root@main:~# mount.nfs 10.0.2.100:/srv/netboot/images /mnt root@main:~# umount /mnt root@main:~# /usr/lib/klibc/bin/nfsmount -o nfsvers=4.2,sec=sys 10.0.2.100:/srv/netboot/images /mnt 4.2: invalid value for nfsvers https://sources.debian.org/src/klibc/2.0.8-6.1/usr/kinit/nfsmount/main.c/#L145 root@main:~# /usr/lib/klibc/bin/nfsmount -o nfsvers=4,sec=sys 10.0.2.100:/srv/netboot/images /mnt /usr/lib/klibc/bin/nfsmount: bad option 'sec' # This hangs because NFSv3 ports (inc. portmap) are not allowed AT ALL by 10.0.2.100. # klibc-utils is hard-coded to *EXPLICITLY* ask for a NFSv3 mount. root@main:~# /usr/lib/klibc/bin/nfsmount 10.0.2.100:/srv/netboot/images /mnt connect: Connection timed out It is quite annoying that we need *anything* special in userland, because a nfsvers=4.2,sec=sys mount requires only 2049/tcp (no other ports/services), and the actual filesystem is in-kernel, so really all that should be needed is enough of a C program to issue a single mount(2)! As an experiment, I tried do compile in EXACTLY that, and it works for me: root@main:~# apt install build-essential strace root@main:~# strace -s99999 -emount mount.nfs 10.0.2.100:/srv/netboot /mnt mount("10.0.2.100:/srv/netboot", "/mnt", "nfs", 0, "vers=4.2,addr=10.0.2.100,clientaddr=10.0.2.15") = 0 root@main:~# umount /mnt root@main:~# journalctl -kfn0 & root@main:~# cc -x c - <<< 'int main() {exit(mount("10.0.2.100:/srv/netboot", "/mnt", "nfs", 0, "vers=4.2,addr=10.0.2.100,clientaddr=10.0.2.15"));}' && ./a.out; echo $? <stdin>: In function ‘main’: <stdin>:1:13: warning: implicit declaration of function ‘exit’ [-Wimplicit-function-declaration] <stdin>:1:13: warning: incompatible implicit declaration of built-in function ‘exit’ <stdin>:1: note: include ‘<stdlib.h>’ or provide a declaration of ‘exit’ <stdin>:1:18: warning: implicit declaration of function ‘mount’ [-Wimplicit-function-declaration] 0 root@main:~# umount /mnt Can I do the same thing with klibc instead of glibc? Well, the compiler wrapper is a bit confused... root@main:~# apt install libklibc-dev root@main:~# klcc -x c - <<< 'int main() {exit(mount("10.0.2.100:/srv/netboot", "/mnt", "nfs", 0, "vers=4.2,addr=10.0.2.100,clientaddr=10.0.2.15"));}' && ./a.out; echo $? <ot", "/mnt", "nfs", 0, "vers=4.2,addr=10.0.2.100,clientaddr=10.0.2.15"));}' && ./a.out; echo $? Died at /usr/bin/klcc line 294. 25 But if I write the C program to a file, it works perfectly: root@main:~# >nfsmount.c printf '#include <stdlib.h>\n#include <sys/mount.h>\nint main() {exit(mount("10.0.2.100:/srv/netboot", "/mnt", "nfs", 0, "vers=4.2,addr=10.0.2.100,clientaddr=10.0.2.15"));}' root@main:~# klcc -o nfsmount nfsmount.c root@main:~# ./nfsmount; echo $? ./nfsmount; echo $? Nov 17 10:11:31 main.lan kernel: process '/root/nfsmount' started with executable stack 0 So for current-generation NFS, without kerberos, all we *REALLY* need is something to getopts from nfsmount -t nfs -o nfsvers=4.2,sec=sys example.com:/srv /srv into mount("example.com:/srv", "/srv", 0, "nfsvers=4.2,sec=sys"); This is pretty narrow in scope and is probably achievable. It allows you to boot off NFSv4, without putting glibc into the initrd.