ipconntrack中的一个BUG

来源:互联网 发布:瓷砖展示软件 编辑:程序博客网 时间:2024/04/26 21:46

好不容易搞个周六,被总监叫回去救火,郁闷啊!

说是BT下载有内存泄露。跑两小时就内核挂了。乱杀进程。

又出现了传说中的内存泄露。哎。只好回公司。

首先进行问题定位。

先看是内核的还是应用的。经过对SLABINFO进行分析。发现是内核中一个数据结构在狂飚。这个数据结构就是ip_conntrack_expect。

基本可以定位是内核问题了。一看这玩意就知道是netfilter这一块的事。然后对SVN进行查找。发现最近将对称NAT改成了锥形NAT。这个地方非常可疑。因为这个是要通过IPTABLES来操作NETFILTER的。

通过CGI将锥形NAT改成对称NAT再挂BT两小时,内存占用量没有任何内存增加的绩像。再改回来,内存在不断上涨。

在内核里找了下。发现ipt_CONENAT.c是源头。继续分析。发现里面有个timeout值为:

.timeout = 60*60*24*365*10,   // never timeout

问题已经非常明朗了,做死的挂BT,大家都在挤,有的挤不过去,老化时间又是无限长,内存不暴涨才怪。

这时候已经晚上十一点了。找到原因后先规避。不让用户有设置全克隆NAT的配置接口。先发货。

等回过头再来改。要不然我明天的周日又要泡汤了。

本文档允许转载,但请注明出处。谢谢。

 

下面是对本文的一个补充。

上班后,花了将近三天时间对这个BUG进行修理。之前发现的超时值无限长不是问题的根源。而是申请的ip_conntrack_expect没有进行合理的释放。

其实这个BUG的解决其实很容易。就加了一行代码。但是在解这个BUG的过程中将整个ip_conntrack的过程给理了一遍。感觉还是有所收获的。其中比较有价值的地方就是tuple hash这个算法。tuple hash其实就一个正一个反,一个长度为二的数组,这当中根据IP和端口二元TUPLE得到一个哈希值。有兴趣的可以仔细看看代码,函数名我也记不起来了。也不想再去翻一遍再列出来了。另外ip_conntrack的架构其实也是依赖挂的几个HOOK。然后在这个过程中挂HOOK的优先级显得比较重要。因为这当中的层次结构还是比较明显的。每一层是对上一层的一个补充。

原创粉丝点击