开始新对话

未解决

此帖子已超过 5 年

J

4269

2013年1月24日 01:00

【转发提问】请教各位大神关于nfs client的奇怪现象

转发来自论坛用户 leecoool 的提问:

最近碰到一个很奇怪的事情,一个linux客户端,kernel是2.6.18的,挂载的时候用“mount -t nfs -o noatime,soft,retry=1,intr"无法挂载,timeout后退出。

 

抓包的结果发现发了一堆UDP包,timeout就是hang在此了。

  

问题来了,这些UDP包是哪里来的?

  

看了下fs/nfs/client.c的源码,默认是tcp的,且没有tcp失败切换到udp的逻辑。

   

然后我在参数中加入协议控制tcp参数,然后就华丽丽的挂载上了,但是,但是,默认的参数它就是tcp啊!!

  

这,到底是为什么呢?

leecoool,你看到本贴后,可以继续回复本来跟进这个问题。以后如果是询问技术问题的话,请以讨论帖子的形式创建(点操作栏里的“展开讨论”而不是“创建文档”,文档一般只用于分享一些整理好的资料)。谢谢!

107 消息

2013年1月24日 01:00

1. 在mount一个export之前,client会给server发portmap request来查询mount所要用的port。这个portmap request很可能是用udp的。这解释了你为什么看到一堆udp包。

2. 一般udp和tcp都可以用的。但是有各种可能会导致失败,比如firewall或NFS server不支持,或者一种很特殊的情况:NFS server是Celerra/VNX,并且没有配置默认网关,或者vlan配置出问题。原因很复杂,如果大家有兴趣我可以写篇博客介绍一下。

89 消息

2013年1月24日 02:00

防火墙确实是很有可能造成这个问题的原因,但是排查过程中还有些疑惑的:

1:在相同内核的其他节点,或者是加入tcp参数之后,抓包的结果都不存在任何UDP的包。这个比较难以解释,既然默认就是tcp的,理论上加不加是一致的,但是为什么不加tcp参数会产生udp包,且无法挂载呢?

2:在抓包的时候,udp的包端口都是1024一下的固定协议,这些协议都是侦测网络健康状况和防火墙的,这也是我后来转向查询acl防火墙策略的起源

但是奇怪的是,nfs.client的源代码中并没有出现如果tcp连接遇到防火墙,转而使用udp的代码,这是我最终疑惑的。代码相关的内容都是case开关

89 消息

2013年1月24日 17:00

在不配置的情况下,默认是tcp。

以下是抓包的结果,大部分是诸如此类的循环,一到udp就没响应然后retry了:

tos 0x0, ttl  64, id 47185, offset 0, flags [DF], proto: TCP (6), length: 52) crm-db-bak2.hst.dsl.crm.alidc.net.46610 > 172.23.142.8.nfs: F, cksum 0x1ae0 (correct), 44:44(0) ack 29 win 46                                             

tos 0x0, ttl  64, id 0, offset 0, flags [DF], proto: UDP (17), length: 84) crm-db-bak2.hst.dsl.crm.alidc.net.63957 > 172.23.142.8.sunrpc: UDP, length 56                                                                                                                       

tos 0x0, ttl  60, id 61830, offset 0, flags [DF], proto: TCP (6), length: 52) 172.23.142.8.nfs > crm-db-bak2.hst.dsl.crm.alidc.net.46610: F, cksum 0x1adf (correct), 29:29(0) ack 45 win 46                                             

tos 0x0, ttl  64, id 47186, offset 0, flags [DF], proto: TCP (6), length: 52) crm-db-bak2.hst.dsl.crm.alidc.net.46610 > 172.23.142.8.nfs: ., cksum 0x1adf (correct), 45:45(0) ack 30 win 46                                             

tos 0x0, ttl  60, id 0, offset 0, flags [DF], proto: UDP (17), length: 56) 172.23.142.8.sunrpc > crm-db-bak2.hst.dsl.crm.alidc.net.63957: [udp sum ok] UDP, length 28                                                                                                          

tos 0x0, ttl  64, id 0, offset 0, flags [DF], proto: UDP (17), length: 68) crm-db-bak2.hst.dsl.crm.alidc.net.6980 > 172.23.142.8.41096: [bad udp cksum 646f!] UDP, length 40                                                                                                   

tos 0x0, ttl  60, id 0, offset 0, flags [DF], proto: UDP (17), length: 52) 172.23.142.8.41096 > crm-db-bak2.hst.dsl.crm.alidc.net.6980: [udp sum ok] UDP, length 24                                                                                                            

tos 0x0, ttl  64, id 0, offset 0, flags [DF], proto: UDP (17), length: 172) crm-db-bak2.hst.dsl.crm.alidc.net.728 > 172.23.142.8.41096: UDP, length 144                                                                                                                        

tos 0x0, ttl  64, id 0, offset 0, flags [DF], proto: UDP (17), length: 172) crm-db-bak2.hst.dsl.crm.alidc.net.728 > 172.23.142.8.41096: UDP, length 144                                                                                                                        

tos 0x0, ttl  64, id 0, offset 0, flags [DF], proto: UDP (17), length: 172) crm-db-bak2.hst.dsl.crm.alidc.net.728 > 172.23.142.8.41096: UDP, length 144                                                                                                                        

tos 0x0, ttl  64, id 0, offset 0, flags [DF], proto: UDP (17), length: 172) crm-db-bak2.hst.dsl.crm.alidc.net.728 > 172.23.142.8.41096: UDP, length 144                                                                                                                        

tos 0x0, ttl  64, id 0, offset 0, flags [DF], proto: UDP (17), length: 172) crm-db-bak2.hst.dsl.crm.alidc.net.728 > 172.23.142.8.41096: UDP, length 144                                                                                                                        

tos 0x0, ttl  64, id 0, offset 0, flags [DF], proto: UDP (17), length: 172) crm-db-bak2.hst.dsl.crm.alidc.net.728 > 172.23.142.8.41096: UDP, length 144                                                                                                                        

tos 0x0, ttl  64, id 0, offset 0, flags [DF], proto: UDP (17), length: 172) crm-db-bak2.hst.dsl.crm.alidc.net.728 > 172.23.142.8.41096: UDP, length 144                                                                                                                        

tos 0x0, ttl  64, id 2957, offset 0, flags [DF], proto: TCP (6), length: 60) crm-db-bak2.hst.dsl.crm.alidc.net.30471 > 172.23.142.8.sunrpc: S, cksum 0xed05 (correct), 2337476361:2337476361(0) win 5840                    

tos 0x0, ttl  60, id 0, offset 0, flags [DF], proto: TCP (6), length: 60) 172.23.142.8.sunrpc > crm-db-bak2.hst.dsl.crm.alidc.net.30471: S, cksum 0xf82a (correct), 350834161:350834161(0) ack 2337476362 win 5792

tos 0x0, ttl  64, id 2958, offset 0, flags [DF], proto: TCP (6), length: 52) crm-db-bak2.hst.dsl.crm.alidc.net.30471 > 172.23.142.8.sunrpc: ., cksum 0x3d69 (correct), 1:1(0) ack 1 win 46                                              

tos 0x0, ttl  64, id 2959, offset 0, flags [DF], proto: TCP (6), length: 112) crm-db-bak2.hst.dsl.crm.alidc.net.30471 > 172.23.142.8.sunrpc: P 1:61(60) ack 1 win 46                                                                    

tos 0x0, ttl  60, id 1154, offset 0, flags [DF], proto: TCP (6), length: 52) 172.23.142.8.sunrpc > crm-db-bak2.hst.dsl.crm.alidc.net.30471: ., cksum 0x3d2d (correct), 1:1(0) ack 61 win 46                                             

tos 0x0, ttl  60, id 1155, offset 0, flags [DF], proto: TCP (6), length: 84) 172.23.142.8.sunrpc > crm-db-bak2.hst.dsl.crm.alidc.net.30471: P 1:33(32) ack 61 win 46                                                                    

tos 0x0, ttl  64, id 2960, offset 0, flags [DF], proto: TCP (6), length: 52) crm-db-bak2.hst.dsl.crm.alidc.net.30471 > 172.23.142.8.sunrpc: ., cksum 0x3d0d (correct), 61:61(0) ack 33 win 46                                           

tos 0x0, ttl  64, id 2961, offset 0, flags [DF], proto: TCP (6), length: 52) crm-db-bak2.hst.dsl.crm.alidc.net.30471 > 172.23.142.8.sunrpc: F, cksum 0x3d0b (correct), 61:61(0) ack 33 win 46                                           

tos 0x0, ttl  64, id 25139, offset 0, flags [DF], proto: TCP (6), length: 60) crm-db-bak2.hst.dsl.crm.alidc.net.0 > 172.23.142.8.nfs: 0 null                                                                                                                                   

tos 0x0, ttl  60, id 1156, offset 0, flags [DF], proto: TCP (6), length: 52) 172.23.142.8.sunrpc > crm-db-bak2.hst.dsl.crm.alidc.net.30471: F, cksum 0x3d09 (correct), 33:33(0) ack 62 win 46                                           

605 消息

2013年1月24日 17:00

没有看过内核代码,不过Linux下面mount.nfs命令是应该有个配置文件etc/nfsmount.conf。这里面也可以配置默认协议。

UDP协议什么失败了?允许的话,可以把抓下来的包传上来看看。

2 Intern

 • 

2.8K 消息

2013年1月24日 19:00

leecoool,关于这个问题我想问几个问题:

1、在所有内核相同的Linux中,是否只有一台客户端出现这种现象?

2、在进行抓包的过程中,你是在Linux客户端对特定端口进行转包,还是对交换机的连接端口镜像后进行抓包呢?

3、如果使用三种不同mount形式:默认、添加UDP参数和添加TCP参数进行测试,结果是怎样的呢?可否把这三种场景分别进行抓包,传上来给大家看看呢?

605 消息

2013年1月24日 19:00

楼主最好是能够完整抓取数据包,这样方便wireshark看。从你的记录来看,应该是由于UDP通行失败了导致mount超时。


tos 0x0, ttl  64, id 0, offset 0, flags [DF], proto: UDP (17), length: 68) NFS-Client.6980 > NFS-Server.41096: [bad udp cksum 646f!] UDP, length 40                                                                                                   

tos 0x0, ttl  60, id 0, offset 0, flags [DF], proto: UDP (17), length: 52) NFS-Server.41096 > NFS-Client.6980: [udp sum ok] UDP, length 24                                                                                                            

tos 0x0, ttl  64, id 0, offset 0, flags [DF], proto: UDP (17), length: 172) NFS-Client.728 > NFS-Server.41096: UDP, length 144                                                                                                                        

tos 0x0, ttl  64, id 0, offset 0, flags [DF], proto: UDP (17), length: 172) NFS-Client.728 > NFS-Server.41096: UDP, length 144                                                                                                                        

tos 0x0, ttl  64, id 0, offset 0, flags [DF], proto: UDP (17), length: 172) NFS-Client.728 > NFS-Server.41096: UDP, length 144                                                                                                                        

tos 0x0, ttl  64, id 0, offset 0, flags [DF], proto: UDP (17), length: 172) NFS-Client.728 > NFS-Server.41096: UDP, length 144                                                                                                                        

tos 0x0, ttl  64, id 0, offset 0, flags [DF], proto: UDP (17), length: 172) NFS-Client.728 > NFS-Server.41096: UDP, length 144                                                                                                                        

tos 0x0, ttl  64, id 0, offset 0, flags [DF], proto: UDP (17), length: 172) NFS-Client.728 > NFS-Server.41096: UDP, length 144

另外我通过模拟得到了和你类似的记录,默认情况下客户端还是会使用UDP协议。主要是用于portmap和rpc.mountd。 portmap在TCP/UDP 111端口这个没有问题,但是rpc.mountd监听随机端口,这样客户端在和rpc.mountd.通行就容易受到防火墙限制。

上传5个附件:

1、tcpdump-log.txt是修改过的楼主的抓包记录,替换了主机名和端口号

2、mount-nfs3.cap NFSv3默认情况下抓包记录

3、mount-nfs-tcp.cap NFSv3加参数-o proto=tcp后抓包记录

4、mount.nfs4.cap NFSv4默认挂载

5、mount.nfs4-tcp.cap NFSv4加参数-o proto=tcp

注意:

我机器操作系统是Red Hat Enterprise Linux Server release 6.0 (Santiago),默认使用NFSv4,必须在/etc/nfsmount.conf指定Defaultvers参数为3;不然系统默认会以nfs4模式挂载,这种情况portmap和rpc.mountd还是UDP协议。加-o proto=tcp参数后,portmap和rpc.mountd都是使用TCP协议。

总的来看:

Linux NFS客户端行为模式如下:

1、NFSv2/3默认使用TCP协议,但是portmap和rpc.mountd还是使用UDP协议;添加mount参数"-o proto=tcp"之后,rpc.mountd使用TCP协议,portmap还是使用UDP协议。

2、NFSv4默认使用TCP协议挂载,但是portmap和rpc.mountd跟NFSv2/3一样使用UDP协议;添加mount参数"-o proto=tcp"之后,rpc.mountd和portmap都是使用TCP协议。

3、/etc/nfsmount.conf可以修改mount命令挂载NFS文件系统默认参数。

5个附件

1.6K 消息

2013年1月24日 19:00

有兴趣有兴趣的,快写啊,很久不见你出手了

89 消息

2013年1月24日 20:00

哎,年底事情多啊,纯人肉加扯淡。。。花时间找问题的机会不多。。。。

89 消息

2013年1月24日 21:00

非常感谢@Jeffey @ Yanhong @Jun_Tan @Peiman Lin 各位同学的关注,这个问题确实是近期遇到的一个很奇葩的问题,由于我之前对nfs本身的源码实现也没怎么看过,所以在发生问题的时候相当纠结。

这个问题的root cause很有可能是acl环境造成的。(发生问题的节点都是在一个具有一定的acl策略,但是这个策略已经避开了nfs常用的tcp端口,而没有策略的网络上的节点就没有这个问题)。

我觉得的这个情况,很有可能在其他类似具有安全策略的网络上重现,拿到论坛上来讨论,也是希望能够给其他人遇到此类问题时提供一个答案和解决方法。

89 消息

2013年1月24日 21:00

我的想法和你类似,不过奇怪的是:

1、NFSv2/3默认使用TCP协议,但是portmap和rpc.mountd还是使用UDP协议;添加mount参数"-o proto=tcp"之后,rpc.mountd使用TCP协议,portmap还是使用UDP协议。

但抓包的结果是,加入“-o proto=tcp”,所有的包均为tcp的。版本是v3。

也就是说,portmap应该也是tcp发的。

2:v4版本没研究过。。。

89 消息

2013年1月24日 21:00

1:是的,所有的测试结果均为2.6.18内核,rhel5环境。

2:在linux client抓的包。

3:以下环境我自己有抓过,如下:(具体的结果我得收集下,这个是可以复现的,但是要点时间)

     A:默认:此抓包过程发现UDP包,产生timeout,无法挂载

     B:加入tcp参数:无UDP包,顺利挂载。

     C:另一个网段,无防火墙acl各种策略,无UDP包,顺利挂载。

加入udp参数的我在复现的时候抓下看看

605 消息

2013年1月24日 22:00

我这边服务器测试版本是V4。

portmap是可以同时支持TCP和UDP,都是111端口。有个需要注意的是portmap在RHEL 6以后被rpcbind软件替换了。

总体来看,NFSv2/v3虽然说默认都是基于TCP实现,实际上并不那么彻底,估计这也是为什么很多讨论NFSv2/v3都会说基于UDP吧。

89 消息

2013年1月24日 22:00

v2是,v3其实应该是tcp了。

这个问题的关键在于 -o proto=tcp究竟和不加这个参数有什么区别。。。。。一直纠结在这里。。。

89 消息

2013年1月25日 01:00

下午找了环境复现了各种情况:

1:在2.6.18内核下,即rhel5,默认参数,确实有扑捉到udp包。挂载版本为v3

2:在2.6.32内核下,即rhel6,默认参数,确实没有扑捉到到udp包。挂载版本为v4

3:在2.6.32内核下,即rhel6,指定v3版本,确实有扑捉到到udp包。

4:在2.6.32内核下,即rhel6,指定v3版本,指定tcp挂载,确实没有扑捉到到udp包。

原因分析:

1:@Jun_Tan 提到的,v3版本和v4确实是有不同,v4没有使用udp。

2:v3版本的tcp参数非常关键,如果加上这个参数,则没有udp包,默认即使使用tcp,也依然有udp

3:是否使用UDP与portmap切换到rpcbind无关

此问题的核心在2:tcp这个参数到底改变了什么?  是否如@Jun_Tan 提到的,如果使用这个参数,将会强制portmap使用tcp。那么为何不在”默认“中就把portmap强制进去呢?

2 Intern

 • 

2.8K 消息

2013年1月25日 01:00

现在问题看起来是防火墙把部分端口block导致的问题。另外你有提到,在无防火墙策略的网段,有使用mount默认参数进行配置并抓包,在抓包中没有发现UDP包,这点似乎又推翻了防火墙block端口的结论。因为内核相同,NFS版本相同的设备,挂载的原理应该相同,产生的数据包也应该一样,不会出现一个使用UDP包一个不使用UDP包的情况。

对于VNX for File和Celerra来说,文档有明确提到rpcbind使用TCP/UDP的111端口,但是具体参数和使用端口的关系并没有提及,建议把之前有防火墙网段和无防火墙网段使用mount命令的抓包情况share一下。

找不到事件!

Top