Bug 227 - [anck-4.19]进程rpcbind未隔离导致文件加锁/解锁异常,导致用例ltp>nfslock3_01/nfslock3_ipv6_01失败
Summary: [anck-4.19]进程rpcbind未隔离导致文件加锁/解锁异常,导致用例ltp>nfslock3_01/nfslock3_ipv6_01失败
Status: CONFIRMED
Alias: None
Product: ANCK 4.19 Dev
Classification: ANCK
Component: net (show other bugs) net
Version: unspecified
Hardware: All Linux
: P3-Medium S5-enhancement
Target Milestone: ---
Assignee: maqiao_mq
QA Contact: 云霭
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-12-29 15:28 UTC by 云霭
Modified: 2023-05-23 15:35 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description 云霭 2021-12-29 15:28:25 UTC
【缺陷描述】 
进程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被隔离了。
Comment 1 Shiloong admin 2021-12-31 15:12:24 UTC
@ylsong
确认是异常吗? log 看没有报错, 是 case 超时中止了, 有试过按提示调大一点超时时间吗?
Comment 2 云霭 2022-01-06 17:47:43 UTC
这个问题之前已经讨论过,详情看下原因定位,之前是一直fail的,结论是先不做修改,记录在社区作为测试基线依据
Comment 3 shanxifanshi alibaba_cloud_group 2023-05-23 15:35:04 UTC
这个问题在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>>>