期待已久的 2.6 內核終於到來了。IBM Linux Technology Center 的 Paul Larson 暗中關注那些讓 2.6 成為有史以來最好內核的工具、測試和技術 —— 從修正控制和回歸測試到缺陷追蹤和列表保持。 經過為期三年的積極開發,新 2.6 Linux 內核最近已經發布了,在這期間,Linux 內核的開發和測試方法發生了一些有趣的變化。當前,開發內核的方法在很多方面與三年前沒什麼不同。不過,一些關鍵變化已經使整體的穩定性和質量得到了提高。
源代碼管理 歷史上,從來沒有出現過用於 Linux 內核的正式的源代碼管理或修正控制系統。實際上,很多開發者實現了他們自己的修正控制器,但是並沒有官方的 Linux CVS 檔案庫,讓 Linus Torvalds 檢查加入代碼,並讓其他人可以由此獲得代碼。修正控制器的缺乏,常常會使發行版本之間存在“代溝”,沒有人真正知道加入了哪些改變,這些改變是否能很好地融合,或者在即將發行的版本中哪些新內容是值得期待的。通常,如果更多的開發者可以像了解他們自己所做的改變一樣了解到那些變化,某些問題就可以得到避免。 由於缺乏正式的修正控制器和源代碼管理工具,使得很多人提議使用一個名為 BitKeeper 的產品。BitKeeper 是一個源代碼控制管理系統,很多內核開發者已經成功地將其應用於他們自己的內核開發工作中。最初的 2.5 內核發布後不久,Linus Torvalds 開始試用 BitKeeper,以確定它是否能滿足他的需要。現在,主要的 2.4 和 2.5 內核的 Linux 內核源代碼都是用 BitKeeper 來管理的。對大部分可能很少或者根本不關心內核開發的用戶來說,這一點看起來可能無關緊要。不過,在一些情況下,用戶可以受益於那些由於使用 BitKeeper 而帶來的開發 Linux 內核的方法的改變。 使用 BitKeeper 的最大好處之一是補丁的融合。當多個補丁應用於同一基礎的代碼之上,並且其中一些補丁會對同一部分產生影響時,就可能會出現融合問題。一個好的源代碼管理系統可以自動地完成其中一些更為復雜的部分工作,這樣可以更快地融合補丁,並使更多的補丁加入到內核中。隨著 Linux 內核開發者社區的擴大,非常需要修正控制器來幫助保持對所有改變的追蹤。由於每個人都可以將這些改變集成到主要的 Linux 內核中,為保證補丁不會被遺忘並可以方便地融合和管理,BitKeeper 等工具是必不可少的。 非常有必要使用一個實時的、集中的檔案庫來保存對 Linux 內核的最新更新。每一個被內核接受的改變或者補丁都被作為一個改變集被追蹤。終端用戶和開發者可以保存他們自己的源文件檔案庫,並根據需要可以通過一個簡單的命令用最新的改變集進行更新。對開發者來說,這意味著可以始終使用最新的代碼拷貝。測試人員可以使用這些邏輯的改變集合來確定哪些變化導致了問題的產生,縮短調試所需要的時間。甚至那些希望使用最新內核的用戶也可以直接利用實時的、集中的檔案庫,因為現在一旦他們所需要的部件或缺陷修復加入到內核中,他們就可以馬上進行更新。當代碼融合到內核時,任何用戶都可以提供關於這些代碼的即時反饋和缺陷報告。
並行開發 隨著 Linux 內核的成長,變得更加復雜,而且吸引更多開發者將注意力集中到內核的特定方面的專門開發上來,出現了另一個開發 Linux 方法的有趣改變。在 2.3 內核版本的開發期間,除了由 Linus Torvalds 發行的主要的一個內核樹之外,還有一些其他的內核樹。 在 2.5 的開發期間,內核樹出現了爆炸式的增長。由於使用源代碼管理工具可以保持開發的同步並行進行,這樣就可能實現開發的部分並行化。為了讓其他人在他們所做的改變被接受之前可以進行測試,有一些開發需要並行化。那些保持自己的樹的內核維護者致力於特定的組件和目標,比如內存管理、NUMA 部件、改進擴展性和用於特定體系結構的代碼,還有一些樹收集並追蹤對許多小缺陷的糾正。 圖 1. Linux 2.5 開發樹 這種並行開發模型的優點是,它使得需要進行重大改變的開發者,或者針對一個特定的目標進行大量類似改變的那些開發者可以自由地在一個受控環境中開發,而並不影響其他人所用內核的穩定性。當開發者完成工作後,他們可以發布針對 Linux 內核當前版本的補丁,以實現到此為止他們所完成的改變。這樣,社區中的測試人員就可以方便地測試這些改變並提供反饋。當每一部分都被證明是穩定的之後,那些部分可以單獨地,或者甚至同時全部地,融合到主要 Linux 內核中。
在實際應用中測試 過去,Linux 內核測試方法圍繞開放源代碼開發模型進行。由於代碼一經發布後就公開給其他開發者進行審查,因此從來沒有出現過一個與其他形式的軟件開發類似的正式的驗證周期。這種方法背後的理論依據是“The Cathedral and the Bazaar”中所謂的“Linus 法則” ,這一法則的內容為“眾人的眼光是雪亮的”。換句話說,高力度的審查可以找出大部分真正的大問題。 然而實際上,內核有很多復雜的相互聯系。即使進行了足夠力度的審查,還是會漏過很多嚴重的缺陷。此外,最新的內核一經發布,終端用戶可以(也經常是) 下載並使用。2.4.0 發布時,社區中很多人都提議進行更有組織的測試,以保證特定測試和代碼審查的強度。有組織的測試包括運用測試計劃、測試過程中的可重復性等等。使用所有的三種方法比最初只使用兩種方法會帶來更高的代碼質量。
Linux 測試項目 最早對 Linux 開始進行有組織測試的貢獻者是 Linux 測試項目 (Linux Test Project,LTP)。這個項目的目的是通過更有組織的測試方法提高 Linux 的質量。這個測試項目的一部分是自動測試套件的開發。LTP 開發的主要測試套件也叫做 Linux 測試項目。2.4.0 內核發布時,LTP 測試套件只有大約 100 個測試。隨著 2.4 和 2.5 版本 Linux 的發展與成熟,LTP 測試套件也正在發展和成熟。當前,Linux 測試項目包括超過 2000 個測試,而且這個數字還在增長!
代碼覆蓋分析 現在所使用的新工具為內核提供了代碼覆蓋分析的功能。覆蓋分析告訴我們,在一個給定的測試運行時,內核中哪些行代碼被執行。更重要的是,覆蓋分析提示了內核的哪些部分還根本沒有被測試到。這個數據是重要的,因為它指出了需要再編寫哪些新測試來測試內核的那些部分,以使內核可以得到更完備的測試。
持續多日的內核回歸測試 在 2.5 的開發周期中,Linux 測試項目所采用的另一個項目是,用 LTP 測試套件對 Linux 內核執行持續多日的回歸測試。人們用 BitKeeper 創建了一個實時的、集中的檔案庫,以隨時可以獲得 Linux 內核的快照。在沒有使用 BitKeeper 和快照時,測試人員不得不等到內核發布後才可以開始測試。現在,內核只要發生了改變,測試人員就可以進行測試。 使用自動化工具來執行持續多日的回歸測試的另一個優點是,和上一次測試相比變化較小。如果發現了一個新的回歸缺陷,通常會容易地檢測出這個缺陷可能是哪個改變導致的。 同樣,由於是最新的改變,因此它在開發者的腦海中印象還比較深 —— 希望這能讓他們更容易地記起並修訂相應的代碼。或許 Linus 法則應該有這樣一個結論,有一些缺陷比其他缺陷更容易被發現,因為那些正是持續多日的內核回歸測試所發現並處理的那些。在開發周期中和實際發布之前能夠每天進行這些測試,這就使那些只關注完整發行版本的測試者可以將精力集中於更嚴重和耗時的缺陷。
可擴展測試平台 另外一個名為開放源代碼開發實驗室 (Open Source Development Labs, OSDL) 的團隊也為 Linux 測試做出了重要的貢獻。2.4 內核發布後不久,OSDL 創建了一個叫做可擴展測試平台 (Scalable Test Platform,STP) 的系統。STP 是一個自動化的測試平台,讓開發者和測試者可以運行 OSDL 硬件之上的系統所提供的測試。開發者甚至可以使用這個系統來測試他們自己的針對內核的補丁。可擴展測試平台簡化了測試的步驟,因為 STP 可以構建內核、設置測試、運行測試,並收集結果。然後得到結果以進行深入地比較。很多人無法接觸大型系統,比如具有 8 個處理器的 SMP 機器,而通過 STP,任何人都可以在像這樣的大型系統上運行測試,這個系統 (STP) 的另一個好處就在於此。
追蹤缺陷 自從 2.4 發布以來,對 Linux 內核的有組織測試最大的改進之一是缺陷追蹤。過去,在 Linux 內核中發現的缺陷會報告給 Linux 內核郵件列表,報告給特定組件或者特定體系的郵件列表,或者直接報告給維護發現缺陷的那部分代碼的個人。隨著開發和測試 Linux 的人數的增加,這個系統的不足之處很快就暴露了出來。在以前,除非人們對缺陷的報告可以驚人地維持下去,缺陷經常被遺漏、遺忘或者忽略。 現在,OSDL 安裝了一個缺陷追蹤系統,來報告和追蹤 Linux 內核的缺陷。系統經過了配置,這樣當某個組件的缺陷被報告時,那個組件的維護者就會得到通知。維護者既可以接受並修復那個缺陷,或重新指定缺陷 (如果最終確定實際上那是內核另外一部分的缺陷),也可以排除它(如果最終確定並不是真正的缺陷,比如錯誤配置的系統)。報告給郵件列表的缺陷還有丟失的危險,因為越來越多的電子郵件湧向那個列表。然而,在缺陷追蹤系統中,始終有對每一個缺陷及其當前狀態的記錄。
大量信息 在為將來的 2.6 Linux 內核進行開的過程中,除了這些自動化的信息管理方法之外,開放源代碼社區的不同成員還收集和追蹤了數量驚人的信息。 例如,在 Kernel Newbies 站點上創建了一個狀態列表,來保持對已經提出的內核新部件的追蹤。這個列表包含了以狀態排序的