【缺陷描述】 进程rpcbind未隔离导致文件加锁/解锁异常,导致用例ltp>nfslock3_01/nfslock3_ipv6_01失败 【重现环境】 [root@iZbp12g4yx7pfedh6jyu3sZ ltp]# uname -r 5.10.84-3.git.40cf96978439.an8.x86_64 Tone job:https://tone.openanolis.cn/ws/jfupduzb/test_result/187 【重现步骤】 git clone https://gitee.com/mirrors_linux-test-project/ltp.git cd ltp make autotools ./configure make make intall cd /opt/ltp ./runltp -f net.nfs -s nfslock3t_01 ./runltp -f net.nfs -s nfslock3t_ipv6_01 【重现概率】 必现 【期望结果】 case pass 【实际结果】 <<<test_output>>> incrementing stop nfslock01 1 TINFO: initialize 'lhost' 'ltp_ns_veth2' interface nfslock01 1 TINFO: add local addr 10.0.0.2/24 nfslock01 1 TINFO: add local addr fd00:1:1:1::2/64 nfslock01 1 TINFO: initialize 'rhost' 'ltp_ns_veth1' interface nfslock01 1 TINFO: add remote addr 10.0.0.1/24 nfslock01 1 TINFO: add remote addr fd00:1:1:1::1/64 nfslock01 1 TINFO: Network config (local -- remote): nfslock01 1 TINFO: ltp_ns_veth2 -- ltp_ns_veth1 nfslock01 1 TINFO: 10.0.0.2/24 -- 10.0.0.1/24 nfslock01 1 TINFO: fd00:1:1:1::2/64 -- fd00:1:1:1::1/64 nfslock01 1 TINFO: timeout per run is 0h 5m 0s nfslock01 1 TINFO: setup NFSv3, socket type tcp nfslock01 1 TINFO: Mounting NFS: mount -v -t nfs -o proto=tcp,vers=3 10.0.0.2:/tmp/ltp-TTkfadgLy1/LTP_nfslock01.deTm2jdTHj/3/tcp /tmp/ltp-TTkfadgLy1/LTP_nfslock01.deTm2jdTHj/3/0 nfslock01 1 TINFO: creating test files nfslock01 1 TINFO: Testing locking nfslock01 1 TINFO: locking 'flock_idata' file and writing data nfslock01 1 TINFO: waiting for pids: 1085142 1085143 Test timed out, sending SIGTERM! If you are running on slow machine, try exporting LTP_TIMEOUT_MUL > 1 nfslock01 1 TBROK: test terminated nfslock01 1 TINFO: Cleaning up testcase Summary: passed 0 failed 0 broken 1 skipped 0 warnings 0 <<<execution_status>>> initiation_status="ok" duration=301 termination_type=exited termination_id=2 corefile=no cutime=10 cstime=7 <<<test_end>>> 【原因定位】 一句话,net namespace隔离后,rpcbind未隔离导致的bug。 首先,这个bug不是死锁,单个进程执行nfs_flock也会触发bug。 其次,看hang住的进程是卡在解锁上的,但是在加锁的时候就已经失败了。 然后,bug成因有点复杂,需要先讲清楚nfs v3及以下的版本的实现机制: nfs的有以下后台进程: nfsd是负责nfs文件读写的后台进程,mountd是与挂载有关的后台进程,lockd是负责文件加解锁的后台进程,另外还有一个sunrpc用来做rpc调用的后台进程,这些进程每个都监听一个端口,但是像lockd它自己是没有固定端口号的,为了能让远端知道这个lockd在哪个端口上监听,还要一个rpcbind后台进程。 以下要点和bug的成因有重要关系: - rpcbind后台进程监听111号端口,远端的机器在和lockd通信前,要先找rpcbind询问到lockd的端口号,然后才能和lockd通信。 - lockd、mountd这些进程,通过AF_LOCAL的socket与rpcbind通信,注册它们自己的端口号信息。 - 不论是nfs的挂载方还是被挂载方,都要一个lockd进程才能完成文件加解锁的操作,这两个进程相互通信 引发这个bug的测试用例,是想在同一台机器上开两个net namespace来模拟nfs的远程挂载和通信机制。步骤可以归纳如下: 1. 在当前net namespace(称之为nsA)中启动rpcbind和nfs-server服务 2. 创建一个新的net namespace(称之为nsB),二者通过ip link peer来通信,nsA的ip为10.0.0.4,nsB的ip为10.0.0.3 3. 在nsA中用exportfs来开放/tmp/lockfolder/3/udp这个目录给远端的nfs挂载 4. 在nsB中,将nsA开放的目录挂载到/tmp/lockTarget/3/0下 5. 在nsB中,用aone正文中所提到的nfs_flock来对/tmp/lockTarget/3/0这个文件加锁(fcntl, F_SETLK) 6. 死了 - 在第1步中lockd已经起来了,但是貌似没有监听端口,也没有向rpcbind注册端口信息(这里需要验证一下,不过在整体上对bug的出现没有影响) - 在第4步,lockd在nsB上监听了一个端口,比如36837,然后把这个端口的信息注册到rpcbind里面了。注意,这个端口只在nsB中监听。 - 在第5步,lockd要和远端的lockd通信,所以它去问rpcbind,nsA那边的lockd监听的端口是多少 - 但是rpcbind里面注册的是nsB自己的端口,rpcbind把这个端口号返回了 - nsB的lockd拿着以为是对端的端口(其实是自己的端口),去连接对端的lockd - nsA这边收到nsB lockd的SYN报文,然后回复RST报文 - nsB lockd重试,继续发SYN报文,然后又被RST - 网络这边就这么循环下去,而进行加解锁的用户态进程就一直在等解锁成功,但是等不到,hang住了 问题就是出现rpcbind没有被隔离上,没有隔离的原因,是nsA和nsB都使用AF_LOCAL的socket进行通信,这种通信方式依赖于一个socket文件:/var/run/rpcbind.sock,这个文件没有被隔离开。 在同样的机器上,用docker起了两个容器,进行试验就没有这种问题,因为var/run/rpcbind.sock被隔离,从而rpcbind被隔离了。
@ylsong 确认是异常吗? log 看没有报错, 是 case 超时中止了, 有试过按提示调大一点超时时间吗?
这个问题之前已经讨论过,详情看下原因定位,之前是一直fail的,结论是先不做修改,记录在社区作为测试基线依据
这个问题在an8 5.10 x86 nightly内核仍然存在,在此做个记录,这条用例nfslock3t_ipv6_01也是因为同样的原因fail。 <<<test_start>>> tag=nfslock3t_01 stime=1684751542 cmdline="nfslock01.sh -v 3 -t tcp" contacts="" analysis=exit <<<test_output>>> nfslock01 1 TINFO: initialize 'lhost' 'ltp_ns_veth2' interface nfslock01 1 TINFO: add local addr 10.0.0.2/24 nfslock01 1 TINFO: add local addr fd00:1:1:1::2/64 nfslock01 1 TINFO: initialize 'rhost' 'ltp_ns_veth1' interface nfslock01 1 TINFO: add remote addr 10.0.0.1/24 nfslock01 1 TINFO: add remote addr fd00:1:1:1::1/64 nfslock01 1 TINFO: Network config (local -- remote): nfslock01 1 TINFO: ltp_ns_veth2 -- ltp_ns_veth1 nfslock01 1 TINFO: 10.0.0.2/24 -- 10.0.0.1/24 nfslock01 1 TINFO: fd00:1:1:1::2/64 -- fd00:1:1:1::1/64 nfslock01 1 TINFO: timeout per run is 0h 5m 0s nfslock01 1 TINFO: mount.nfs: (linux nfs-utils 2.3.3) nfslock01 1 TINFO: setup NFSv3, socket type tcp nfslock01 1 TINFO: Mounting NFS: mount -v -t nfs -o proto=tcp,vers=3 10.0.0.2:/tmp/ltp-XddFjil9Do/LTP_nfslock01.RXYEPPYFbg/3/tcp /tmp/ltp-XddFjil9Do/LTP_nfslock01.RXYEPPYFbg/3/0 nfslock01 1 TINFO: creating test files nfslock01 1 TINFO: Testing locking nfslock01 1 TINFO: locking 'flock_idata' file and writing data nfslock01 1 TINFO: waiting for pids: 523089 523090 Test timed out, sending SIGTERM! If you are running on slow machine, try exporting LTP_TIMEOUT_MUL > 1 nfslock01 1 TBROK: test terminated nfslock01 1 TINFO: Cleaning up testcase Summary: passed 0 failed 0 broken 1 skipped 0 warnings 0 <<<execution_status>>> initiation_status="ok" duration=300 termination_type=exited termination_id=2 corefile=no cutime=10 cstime=8 <<<test_end>>>