转载自: https://blog.csdn.net/onwer3/article/details/43378431
转载原因: 准备实验下dropwatch定位丢包原因的思路.

背景

网工面对业务反馈数据中心内部2台Server之间丢包,首先会查端到端之间所有链路有无拥塞、端口CRC问题;确认没有异常后,会开始怀疑是Server本身丢包,但我们知道,物理服务器一般会查下物理网卡有无丢包,但一般网卡丢包的可能性很小,但如果包是丢在内核网络层怎么办呢?通过抓包分析会因为场景的不同,数据的多少造成分析困难重重。Linux从2.6.30开始支持Network Drop Watch(dropwatch)功能,可以准确定位内核网络层数据包的丢弃;

dropwatch使用前提

1、首先内核必须大于等于2.6.30;
2、编译内核时应该加上“NET_DROP_MONITOR=y”;
3、由于dropwatch是依赖Kernel Tracepoint API的,其原理是各个协议层释放skb时收集信息来判断有无丢包,用的不多,难免存在一些BUG导致内核crash,因此具备一定危险性,建议troubleshooting时,最好先切走业务;

使用方法

1、笔者使用的系统是CentOS 6.3,首先需要通过yum安装dropwatch:”yum install dropwatch -y”
2、带参数运行dropwatch:”dropwatch -l kas”,不带参数运行,默认输出的是各个函数的地址信息,不便于观察;
补充一下,使用 -l kas后,会通过“/proc/kallsysms”去映射地址和符号表的对应关系,实测会出各种问题甚至死机,建议不要这么做;可以自己通过/boot/System.Map去查询。

3、开始抓取内核丢包数据:”start”:

[siwen@Sven ~]$sudo dropwatch -l kasInitalizing kallsyms db
dropwatch>startEnabling monitoring…
Kernel monitoring activated.
Issue Ctrl-C to stop monitoring
1 drops at netlink_unicast+251 (0xffffffff814639c1)
1 drops at init_dummy_netdev+50 (0xffffffff81438a10)
2 drops at init_dummy_netdev+50 (0xffffffff81438a10)
2 drops at init_dummy_netdev+50 (0xffffffff81438a10)
1 drops at udp_queue_rcv_skb+953 (0xffffffff8149b113)2 drops at init_dummy_netdev+50 (0xffffffff81438a10)
1 drops at init_dummy_netdev+50 (0xffffffff81438a10)
1 drops at icmp_sk_init+317 (0xffffffff8149e557)
^CGot a stop messagedropwatch>

4、“Ctrl+C”可以退出信息获取,通过stop或者exti可以退出dropwatch程序;
5、Step 3抓取的结果最右边一列表示丢包数量,以标红一行为例,表示udp_queue_rcv_skb函数偏移953的位置有一个包被丢弃;通过SystemMap来定位是谁丢弃;我们先通过uname -a获取当前内核版本:

[siwen@Sven ~]$uname -aLinux Sven 2.6.32-279.el6.x86_64 #1 SMP Fri Jun 22 12:19:21 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux

通过uname发现内核版本为“2.6.32-279.el6.x86_64”,在“/boot”目录下搜索对应的SystemMap文件:

[siwen@Sven ~]$grep -w “udp_queue_rcv_skb” /boot/System.map-2.6.32-279.el6.x86_64 -A2ffffffff8149a7c0 T udp_queue_rcv_skb
ffffffff8149ab60 T __udp4_lib_rcv
ffffffff8149b530 T udp_rcv

可以看到“udp_queue_rcv_skb”加953的偏移量位置在“udp4_lib_rcv”和“udp_rcv”之间,那么也就是说包丢在udp4_lib_rcv这个函数了,这个函数的功能是完成udp报文接受,并初始化udp的校验和,但不校验其正确性;

6、当然我们也可以通过“cat /proc/net/snmp”来查看udp丢包信息,虽然不能准确定位到哪里丢包,至少可以判断系统是有问题的。

总结

通过dropwatch可以明确定位到Linux主机网络层丢包点在哪,对网络来讲可以自证清白,对业务方来讲,可以发现系统瓶颈和问题所在,从而去优化改进。

参考资料:《Linux内核精髓》dropwatch一章节