linux kernel測試初探

 
前言
 
Linux基金會在4月3日公佈了Linux開發年報,向咱們展現了linux kernel做爲世上最大開源合做項目之一的魅力。自2005年以來,共有800家公司7800名開發人員參與Linux kernel開發,最近一年也有200家公司共1000名開發人員參與。目前在Linus Torvalds的監督之下,Linux核心約2到3個月發佈一個新的穩定版本,每次更新大約包含8000到12000項修改,平均每小時有提交6.88次修改。內核全部文件代碼已超過1500萬行,大約以每一年10%的代碼量在增加。
規模組織如此巨大,開發又活躍,且對質量有很是高要求的項目,不由好奇它是如何作好質量保證的,因而查閱了網上較多資料,探索Linux kernel的質量保證之道。
 
名詞解釋

 
Linux Kernel和GNU/Linux。Linux kernel做爲系統的最底層,是負責管理硬件、執行任務調度、維護總體安全和完整性的系統軟件。一個內核不是一套完整的操做系統,人們將 Linux 內核和 GNU 系統組成完整的自由系統:基於 Linux 的 GNU 系統(或簡稱爲 GNU/Linux 系統)。我們平時所說的Linux系統可能是指GNU/Linux。
Patch。升級內核時,沒必要要每次都下載或提交整個的源碼文件,而是使用patch,或者叫作補丁或升級包。不少不一樣版本的內核源代碼是以一組補丁(補丁集)甚至是若干獨立補丁的形式存在的。這些補丁應該應用在特定版本的內核樹上。
內核樹。樹的意思是「包含內核源代碼的目錄的內容」。另一層意思是「內核源碼的開發分支」。不一樣的分支命名也不同,比較流行的分支(樹)有-next樹(前身是Andrew Morton維護的-mm樹),-rt 樹(實時樹,包含把linux轉換爲實時系統的補丁)。
-next 樹,由Stephen Rothwell維護,是一些其餘樹以及各類獨立的實驗性補丁,它集合了主線和多種內核子系統(子系統樹)維護人所使用的樹,子系統樹中含有被認爲是實驗性的和還沒準備好合併到主線中的各類補丁。換句話說,-next樹的每一個版本都是帶有額外修改和一些bug的主線的將來快照。Bug儘量在這些補丁合併到主線以前獲得修正。
 
開發流程
 
要了解測試,先得看看整個項目的開發過程。
Linux kernel開發流程是基於一個鬆散的、定時發佈的滾動模型,每2-3個月發佈一個新穩定版本。2-3個月被認爲是一個合適的時間週期,能加快開發速度的同時,也減小發行商須要處理的外部修改,更短則致使測試時間太少,新內核測試不充分;更長則致使發佈版本之間會堆積太多工做。此模型從2005年正式確認,儘早將新功能融入內核主線,將發佈給用戶的延期降至最低。
在準備提交Linux kernel代碼前,開發者將升級拆分爲一個個小的互相獨立的單元,叫作補丁(patch)。每一個補丁一般只作一件事情,而且應當保證系統在打上此補丁以後是依然能正常編譯和工做的。這致使每一個補丁均可以作代碼質量和正確性評審,同時也致使每一個版本提交的補丁數較大。
提交的補丁並非直接進入到內核主線,參考圖一的代碼流動過程,只有一我的能將補丁放入到內核主線:Linus Torvalds。可是隨着愈來愈多的補丁加入到內核,大約只有2%的補丁是Linux直接選入的。內核代碼從邏輯上是拆分紅一系列的子系統集合。每一個子系統負責內核的一部分(好比網絡、SCSI驅動、特定架構支持、內存管理、視頻設備等),而且擁有指定的維護者,維護者對該子系統的代碼整體負責。當前有過超過100個子系統。補丁先是進入到一個子系統樹,子系統維護者接受修改時,補丁就會附加「由誰簽收經過」 的一行簽字。該信息代表此補丁能夠合入到內核。php

圖一 代碼流動過程
Linux-next樹本意是在Linus合併代碼前將各子系統的代碼整合到一塊兒,並進行測試,挑選出可能存在的衝突和跨子系統問題。html

 
實際例子
 
一個新版本2.6.20的發佈過程以下圖二。在每個版本開始時,Linus會打開合併窗口(merge window),從那時起,被認爲是可靠穩定的代碼會被合併到內核主線,新的功能或驅動等得以加入進來,合併窗口會開啓兩週,而後Linus會宣佈窗口關閉,併發布第一個rc版本,以下圖2.6.20-rc1。此-rc1版本的發佈意味着新功能的加入已經完成,之後再加入的補丁只能是修復問題,以確保此版本的穩定,但也有即少數包含新功能的補丁會被認爲是不友好的。問題修復的代碼不斷進入主線,Linus接下來大約每週發佈一個新的rc版本,一般會在6-9個rc版本後認爲此版本已經穩定而且最終發佈2.6.20版本,再進入下一個三位版本的迭代。發佈以後,此2.6.x版本就移交給穩定組(stable team),穩定組時而會再發布2.6.x.y版本,每一個四位版本的發佈會有兩個條件:(1)修復重大的bug;(2)該補丁也已被融入到下個三位版本開發的主線中了。穩定組一般維護一個穩定版本6個月左右,以後就由使用該版內核的發行版發行商負責。

圖二 一個版本的發佈過程
 
測試
 python

對Linux kernel測試面臨的挑戰巨大:如前面的數據所顯示,(1)其快速活躍的開發;(2)常常性的版本發佈,每次發佈都包含大量修改,以及內核自己支持配置的靈活性、可擴展性,待測點太多(3)須要覆蓋各類平臺,Linux已支持二十多種平臺體系,是支持平臺最廣的系統;(4)過期的case須要維護以及大量遺留代碼。
與鬆散的開發流程相對應,沒有看到正式的測試流程,開源軟件很大一部分的測試執行是依靠用戶實際運行使用。以下圖三所示。

圖三 開源測試的大致流程
 
測試項目簡介
 linux

Linux kernel與測試相關較出名的開源項目有:
LTP:Linux Test Project http://ltp.sourceforge.net/。
Autotest:http://autotest.github.com/
CrackerJack Project:http://ossipedia.ipa.go.jp/crackerjack/index.html。
LTP是一個聯合項目主要驗證Linux系統的可靠性、健壯性和穩定性,最早由SGI™啓動,並由IBM®負責維護。2012年4月發佈的最新穩定版本已擁有3000+的case(case增加並很少,06年時就有2900+的case),用於測試Linux kernel以及相關功能。使用的編程語言主要是ANSI-C(佔94%),以及Bash腳本(佔5%),還有Perl(佔0.62%)。它也有一套使用ANSI-C和Bash寫case的模板。
Autotest是後啓之秀,最先被用於Linux kernel自動化測試的框架,使用python語言,如今也被多個其它項目所應用。新case能較容易添加,ANSI-C或者Bash寫的case也能較方便地融入此框架。針對Linux kernel的測試項目地址是http://test.kernel.org,用於交流、共享和分析測試數據。Autotest框架分服務端和客戶端,在監聽到有新版本發佈(三位版本、四位版本、-rc版本、-git版本)時,會自動觸發執行自動化,執行過程見下圖四。

圖四 Autotest自動化執行流程
CrackerJack 是一個主要負責linux kernel兼容性測試的項目,找出不一樣內核版本系統調用的diff狀況,已支持317個系統調用。它也是使用Autotest框架執行,diff結果是個矩陣可見下圖五或者網址http://ossipedia.ipa.go.jp/crackerjack/compare_results.html。Diff比較是智能的,並不是單獨地比較輸出結果,好比time時間調用每次系統返回都是不同的,比較時就是檢查兩次調用之間的時間差。

圖五 CrackerJack diff結果
 
測試方式
 
測試手段是多樣的:單測、集成測試、功能測試、性能測試、壓力測試、迴歸測試等,但沒有一種手段在任意時候都合適。質量保證是多方面的,除了要求開發者寫出高質量代碼外,靜態代碼檢查、還要有頻繁且嚴格的code review,下面列舉一些針對Linux kernel特色的測試。
1. 開發者測試。鼓勵開發者寫單元測試,但不少時候有太多的依賴假設,單測等是很難的,好比要測試U盤在讀寫過程當中被拔掉,再插上的狀況,只有實際運行執行才能驗證程序是否正確。不管開發人員使用何種方式,都須要保證負責的代碼是通過測試了的。不須要在全部版本上運行,但須要確保代碼質量,不能假定的字節序、字節長度,都應該使用標準接口。有些時候是修復別人報的bug,而開發人員又沒有復現該bug的環境,此時修改也須要由bug提交者確認在其環境測試經過或者在其它能復現該bug的環境驗證經過。對修改代碼的質量保證方法還包括交由其它人評審經過或測試經過。編譯器的報警也是須要修復的。
2. 社區測試。社區開發模式,也強調社區測試,鼓勵你們在作好數據備份前提下使用最新發布的版本,相似軟件正式發佈前的試用版本,以確保在不一樣的機器不一樣的平臺上能實際正常運行。對此類版本的使用是有風險的,有可能致使系統崩潰。一般在系統安裝後,啓動時也會比較當心,逐項加載啓動,以檢查每步都是正常的。還會作一些很是規的操做,也就是異常測試。
3. 配置測試。Linux kernel的配置也較複雜,以支持較好的靈活性和可擴展性,測試須要儘可能地覆蓋不一樣的配置組合條件。有的作法是隨機配置,再編譯運行啓動,7*24小時重複不間斷地作,以找出可能存在的問題。作的過程當中也有優化,好比關閉一些沒必要要的選項,減小編譯的時間。
有些配置項是有助於測試執行時監控問題和分析問題的,好比打印出debug日誌,或者在出錯時打印儘量多的信息,kernel在某些設置下自身也會作一些運行過程當中的檢查,如CONFIG_DETECT_SOFTLOCKUP能檢查出內核部分是否在內核模式中循環超過60秒的bug,這類配置一般會在測試時打開。
4. 硬件測試。驗證kernel對不一樣平臺的支持時,會使用些不經常使用的硬件,以及不經常使用的硬件組合,不一樣的體系架構。
5. 對待變化。因爲Linux kernel常常變化,不可能每次變更都同等對待。針對-rc候選發佈版本,須要嚴格地測試,由於它們一旦被認爲是穩定的以後就會正式發佈,並極可能由發行商選中到發行版中。而針對-next樹或者之前的-mm樹,由於它們太容易變化了,沒有時間和資源運行全量測試,一般只執行最基本的測試。
6. 工具。Linux測試工具衆多,可見http://ltp.sourceforge.net/tooltable.php,覆蓋率、安全性、調試、網絡、性能等方方面面工具都應有盡有。
7. 性能測試。Linux kernel對性能要求也比較高,性能測試一般要注意的幾點:(1)最好是利用benchmark,以取得可信數據;(2)避免I/O緩存因素,緩存對性能影響較大;(3)確保測量環境的穩定性,特別是比較先後版本時。Autotest中也包含性能測試自動化,一次升級致使的性能問題和修復以下圖六所示,2.6.14-rc2-mm1版本與2.6.14-rc1-mm1版本相比執行時間由101增長到了111,性能下降了10%,直到2.6.16-rc1-mm4版本才修復。

圖六 Autotest性能測試執行結果圖
8. 可測性。Linux kernel在可測性方面也有較好支持。
(1)內核模塊化。啓動內核模塊支持後,內核的某些部分就能夠在須要的時候才裝載到內存中,使內核變得更小,運行更快。模塊化的內核部分能夠在系統運行期間裝載或者卸載。
(2)內核hacking 選項,編譯一個測試用的內核,有助有內核特定功能的調試,也須要注意有部分選項會致使性能下降。
(3)Magic SysRq鍵,神奇的鍵盤快捷鍵,能夠利用快捷鍵直接向內核傳遞特定的指定。
(4)多種信息收集方式,內核的bug不必定是致使系統崩潰,一些嚴重的錯誤經過日誌等表現出來,信息收集就變得猶爲重要了。能夠經過Syslog, console, dmesg等方式dump和顯示日誌,除此以外,還能夠經過串口和網絡控制檯遠程收集信息。
(5)kexec快速重啓系統,使用 kexec能夠直接從新啓動到另外一個內核,再也不必須經過固件和引導裝載程序階段,能爲測試節省大量時間。
(6)使用biselect追查問題,當發現一個bug殊不知道是由哪一個補丁引入時,使用二分查找,代碼管理系統git以及補丁管理工具quilt都支持二分查找。
9. 覆蓋率。關於Linux kernel的測試覆蓋率,沒有看到最新的統計,不過之前數據可能是在20%左右的分支覆蓋率。git

雖說自動化測試愈來愈重要,可是將內核部分測試自動化倒是很是困難的,自動化只涵蓋了一少部分功能,性能的自動化看起來作得更多些。質量更多仍是由開發人員以及社區測試來保證。另一方面看,Linux kernel自己的架構應該也有較高的容錯性和可擴展性,以支持如此大量又頻繁的修改。
說明
寫本文時,我還並無實際參與過Linux kernel的開發或測試,只是對其有興趣,因而在網上查閱了大量文檔,有些信息可能已通過時或者與實際狀況不符,僅供參考。
引用說明
 
網上連接
 
Crackerjack Project http://ossipedia.ipa.go.jp/crackerjack/index.html
Linux命名爭議 http://en.wikipedia.org/wiki/GNU/Linux_naming_controversy
Linux Test Project,測試Linux kernel以及相關功能 http://ltp.sourceforge.net/
Linux測試工具 http://ltp.sourceforge.net/tooltable.php
Linux 維基百科 http://en.wikipedia.org/wiki/Linux
Linux Kernel維基百科 http://en.wikipedia.org/wiki/Linux_kernel
開發流程 http://linuxwireless.org/en/developers/process
Autotest項目http://autotest.github.com/
Greg Kroah Hartman on the Linux Kernel視頻http://www.youtube.com/watch?v=L2SED6sewRwgithub

http://stackoverflow.com/questions/3177338/how-is-linux-kernel-tested編程

kernel官網 http://www.kernel.org/
Linux kernel郵件列表FQA http://ftp.osuosl.org/pub/linux/docs/lkml/
 
Pdf電子書
 
《Best Practices in Linux Kernel Testing》
《Linux Kernel Tester’s Guide》version 0.3,中文版《Linux 內核測試指南》
《How to Participate in the Linux Community》2008.8
《Linux Kernel Development:How Fast it is Going, Who is Doing It, What They are Doing, and Who is Sponsoring It》2012.3緩存