ipconntrack中的一個BUG

好不容易搞個週六,被總監叫回去救火,鬱悶啊!

說是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的優先級顯得比較重要。因爲這當中的層次結構還是比較明顯的。每一層是對上一層的一個補充。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章