4.19 ltp nfs测试失败问题

1 问题描述

Kylin-Server-V10-SP3-General-Release-2303-X86_64.iso执行systemctl start nfs-server; cd /opt/ltp/testcases/bin; PATH=$PATH:$PWD ./nfs01.sh -v 4 -t tcp成功:

nfs01 1 TINFO: initialize 'lhost' 'ltp_ns_veth2' interface
nfs01 1 TINFO: add local addr 10.0.0.2/24
nfs01 1 TINFO: add local addr fd00:1:1:1::2/64
nfs01 1 TINFO: initialize 'rhost' 'ltp_ns_veth1' interface
nfs01 1 TINFO: add remote addr 10.0.0.1/24
nfs01 1 TINFO: add remote addr fd00:1:1:1::1/64
nfs01 1 TINFO: Network config (local -- remote):
nfs01 1 TINFO: ltp_ns_veth2 -- ltp_ns_veth1
nfs01 1 TINFO: 10.0.0.2/24 -- 10.0.0.1/24
nfs01 1 TINFO: fd00:1:1:1::2/64 -- fd00:1:1:1::1/64
nfs01 1 TINFO: timeout per run is 0h 5m 0s
nfs01 1 TINFO: mount.nfs: (linux nfs-utils 2.5.1)
nfs01 1 TINFO: setup NFSv4, socket type tcp
nfs01 1 TINFO: Mounting NFS: mount -v -t nfs -o proto=tcp,vers=4 10.0.0.2:/tmp/LTP_nfs01.T8ifnS128N/4/tcp /tmp/LTP_nfs01.T8ifnS128N/4/0
mount.nfs: mount(2): No such file or directory
mount.nfs: mounting 10.0.0.2:/tmp/LTP_nfs01.T8ifnS128N/4/tcp failed, reason given by server: No such file or directory
mount.nfs: timeout set for Mon Apr 22 17:00:23 2024
mount.nfs: trying text-based options 'proto=tcp,vers=4.2,addr=10.0.0.2,clientaddr=10.0.0.1'
nfs01 1 TBROK: mount command failed
nfs01 1 TINFO: Cleaning up testcase

Summary:
passed   0
failed   0
broken   1
skipped  0
warnings 0

配置文件/etc/exports修改成如下内容:

/tmp/ *(rw,no_root_squash,fsid=0)
/tmp/s_test/ *(rw,no_root_squash,fsid=1)

但在debian bullseye上测试成功。

Kylin-Server-V10-SP3-General-Release-2303-X86_64.iso上,重启服务systemctl restart nfs-server,手动挂载mount -v -t nfs -o proto=tcp,vers=4 10.0.0.2:/s_test /mnt,挂载成功,说明nfs功能正常。

2 定位

单步执行测试用例:

systemctl restart nfs-server
mkdir /tmp/s_test -p
exportfs -u *:/tmp/s_test
echo 3 > /proc/sys/vm/drop_caches # 也可以不清缓存
exportfs -i -o fsid=148252,no_root_squash,rw *:/tmp/s_test
mount -v -t nfs -o proto=tcp,vers=4 localhost:/tmp/s_test /mnt

同时满足以下几个条件挂载失败:

以下几种组合,都能挂载成功:

3 代码分析

tcpdump抓包看到lookup请求nfs server返回错误NFS4ERR_NOENT

麒麟系统挂载报错,server返回错误的流程:

kthread
  nfsd
    svc_process
      svc_process_common
        nfsd_dispatch
          nfsd4_proc_compound
            nfsd4_lookup
              nfsd_lookup
                err = nfsd_lookup_dentry = -NFS4ERR_NOENT
                  host_err = nfsd_cross_mnt = -2
                    exp2 = rqst_exp_get_by_name = -2
                      if (rqstp->rq_client == NULL) // 条件不满足
                      exp_get_by_name
                        err = cache_check = -2
                          rv = cache_is_valid = -2
                            if (test_bit(CACHE_NEGATIVE, &h->flags)) // 条件成立
                            return -ENOENT

麒麟系统server:

// (gdb) p $lx_current().comm exportfs
write
  ksys_write(fd=<optimized out>, buf="-test-client- /tmp/s_test  3 9248 65534 65534 0\n", count=48)
    vfs_write
      __vfs_write
        proc_reg_write
          cache_write_procfs
            cache_write
              cache_downcall
                cache_do_downcall
                  svc_export_parse
                    if (err == -ENOENT) // 条件不满足

// (gdb) p $lx_current().comm rpc.mountd
write
  ksys_write (fd=<optimized out>, buf=0x7ffe06cef970 "* / 1715158097 74753 65534 65534 0 secinfo 4 390003 74753 390004 74753 390005 74753 1 74753 uuid \\x35a888ad211b41ad9103996db1e3dd2c \n", count=133)
    vfs_write
      __vfs_write
        proc_reg_write
          cache_write_procfs
            cache_write
              cache_downcall
                cache_do_downcall
                  svc_export_parse
                    if (err == -ENOENT) // 条件不满足

// (gdb) p $lx_current().comm rpc.mountd
write
  ksys_write (fd=<optimized out>, buf=0x7ffe06cef970 "* /tmp 1715158103 66561 65534 65534 0 secinfo 4 390003 66561 390004 66561 390005 66561 1 66561 \n \\x35a888ad211b41ad9103996db1e3dd2c \n", count=96)
    vfs_write
      __vfs_write
        proc_reg_write
          cache_write_procfs
            cache_write
              cache_downcall
                cache_do_downcall
                  svc_export_parse
                    if (err == -ENOENT) // 条件不满足

// (gdb) p $lx_current().comm rpc.mountd
write
  ksys_write (fd=<optimized out>, buf=0x7ffe06cef970 "* /tmp 1715158106 \n6561 65534 65534 0 secinfo 4 390003 66561 390004 66561 390005 66561 1 66561 \n \\x35a888ad211b41ad9103996db1e3dd2c \n", count=19)
    vfs_write
      __vfs_write
        proc_reg_write
          cache_write_procfs
            cache_write
              cache_downcall
                cache_do_downcall
                  svc_export_parse
                    if (err == -ENOENT) // 条件满足
                    set_bit(CACHE_NEGATIVE, &exp.h.flags);

debian系统server: