2021-03-08 08:07:21

by Donald Buczek

[permalink] [raw]
Subject: [BUG] nfs-utils: mountd doesn't work with elder glibc versions

Hi,

we noticed that our exports don't work with nfs-utils 2.5.3.

The reason is, that 76c21e3f ("mountd: Check the stat() return values in match_fsid()") added a new error handling. It sets errno to 0 and assumes that it is stable when there are no errors. However, this conflicts with the logic in support/misc/xstat.c, which sets errno to ENOSYS if glibc doesn't support statx() or has an incomplete emulation.

We have glibc 2.27 which doesn't support statx().

root@dose:~# findmnt /amd/dose/0
TARGET SOURCE FSTYPE OPTIONS
/amd/dose/0 /dev/vda2 xfs rw,relatime,attr2,inode64,logbufs=8,logbsize=32k,noquota
root@dose:~# /usr/sbin/rpc.mountd --foreground --manage-gids -d all &
[1] 26777
root@dose:~# rpc.mountd: Version 2.5.3 starting
root@dose:~# exportfs dose:/amd/dose/0
root@dose:~# mount dose:/amd/dose/0 /mnt
rpc.mountd: auth_unix_ip: inbuf 'nfsd 141.14.17.51'
rpc.mountd: auth_unix_ip: inbuf 'nfsd 141.14.17.51'
rpc.mountd: auth_unix_ip: client 0x459850 'dose.molgen.mpg.de'
rpc.mountd: v4root_create: path '/' flags 0x12403
rpc.mountd: auth_unix_ip: inbuf 'nfsd 141.14.17.51'
rpc.mountd: auth_unix_ip: client 0x459850 'dose.molgen.mpg.de'
rpc.mountd: v4root_create: path '/amd' flags 0x10403
rpc.mountd: v4root_create: path '/amd/dose' flags 0x10403
rpc.mountd: auth_unix_ip: client 0x451010 'dose.molgen.mpg.de'
rpc.mountd: rpc.mountd: nfsd_fh: inbuf 'dose.molgen.mpg.de 1 \x00000000'nfsd_fh: inbuf 'dose.molgen.mpg.de 1 \x00000000'

rpc.mountd: nfsd_fh: found 0x45b1c0 path /
rpc.mountd: nfsd_fh: found 0x45c070 path /
rpc.mountd: nfsd_export: inbuf 'dose.molgen.mpg.de /amd'rpc.mountd:
nfsd_export: inbuf 'dose.molgen.mpg.de /amd'
rpc.mountd: nfsd_export: found 0x442eb0 path /amdrpc.mountd:
nfsd_export: found 0x45b6d0 path /amd
rpc.mountd: rpc.mountd: nfsd_fh: inbuf 'dose.molgen.mpg.de 7 \x83000000000000005e2eaee859174457bcd564e9512178dc'nfsd_fh: inbuf 'dose.molgen.mpg.de 7 \x83000000000000005e2eaee859174457bcd564e9512178dc'

rpc.mountd: nfsd_fh: found 0x442ec0 path /amdrpc.mountd:
nfsd_fh: found 0x45b6e0 path /amd
rpc.mountd: nfsd_export: inbuf 'dose.molgen.mpg.de /amd/dose'
rpc.mountd: nfsd_export: inbuf 'dose.molgen.mpg.de /amd/dose'
rpc.mountd: rpc.mountd: nfsd_export: found 0x4433d0 path /amd/dosenfsd_export: found 0x45bbf0 path /amd/dose

rpc.mountd: nfsd_fh: inbuf 'dose.molgen.mpg.de 7 \x81000820000000005e2eaee859174457bcd564e9512178dc'rpc.mountd:
nfsd_fh: inbuf 'dose.molgen.mpg.de 7 \x81000820000000005e2eaee859174457bcd564e9512178dc'
rpc.mountd: nfsd_fh: found 0x4433e0 path /amd/dose
rpc.mountd: nfsd_fh: found 0x45bc00 path /amd/dose
rpc.mountd: nfsd_export: inbuf 'dose.molgen.mpg.de /amd/dose/0'
rpc.mountd: nfsd_export: inbuf 'dose.molgen.mpg.de /amd/dose/0'
rpc.mountd: nfsd_export: found 0x443550 path /amd/dose/0
rpc.mountd: nfsd_fh: inbuf 'dose.molgen.mpg.de 6 \xa7287020bece44b09df5b577a4b82823'
rpc.mountd: nfsd_export: found 0x45bb40 path /amd/dose/0
rpc.mountd: nfsd_fh: found (nil) path (null)rpc.mountd:
nfsd_fh: inbuf 'dose.molgen.mpg.de 6 \xa7287020bece44b09df5b577a4b82823'
rpc.mountd: nfsd_fh: found (nil) path (null)

( mount hangs until interrupted )

With the following workaround, things works again:

diff --git a/support/export/cache.c b/support/export/cache.c
index f1569afb..1b671c32 100644
--- a/support/export/cache.c
+++ b/support/export/cache.c
@@ -722,7 +722,7 @@ match:
path_error:
if (path_lookup_error(errno))
goto nomatch;
- return -1;
+ return 0;
}

static struct addrinfo *lookup_client_addr(char *dom)

Another minor one, I noticed when searching for the above:

diff --git a/support/misc/mountpoint.c b/support/misc/mountpoint.c
index 14d6731d..ae664d6a 100644
--- a/support/misc/mountpoint.c
+++ b/support/misc/mountpoint.c
@@ -37,7 +37,7 @@ check_is_mountpoint(const char *path, int (mystat)(const char *, struct stat *))
rv = 0;
else
if (stb.st_dev != pstb.st_dev ||
- stb.st_ino == pstb.st_ino)
+ stb.st_ino != pstb.st_ino)
rv = 1;
else
rv = 0;

I just assume, this would be right and might be relevant to exported bind mounts. But I didn't try to trigger the assumed bug here.

Best
Donald