天天看點

Linux核心測試現狀揭秘核心測試的現狀核心測試的困境企業是如何做的企業例子之一(紅帽)企業例子之二(SUSE和Ubuntu)企業例子之三(Linaro)測試的不斷改善核心測試的一些其他聲音結語

本文大部分内容由 https://lwn.net/Articles/734016/ 翻譯改編而來。

核心測試的現狀

新的核心總是會定期釋出出來,但是其實大家并不是十分了解核心是如何被深入測試的。那麼這裡可以提前告訴大家,核心主幹有可能并沒有做過充分的測試,而穩定核心可能會更少。。。 So what is going on there? Is stable kernel really stable? 剛好今年9月在洛杉矶舉辦的《Linux Plumbers Conference》有一個BOF(birds of a feather)會議,Dhaval Ginal和Sasha Levin組織了一個關于核心測試的相關讨論,讓我們一起去看看。

由于大部分BoF的參會人員來自各個主要的Linux發行商,是以Giani開場的時候提了一個問題:“大家對于穩定核心(stable kernels)都做過了多少測試呢?大家是不是都是僅僅測試自己發行的核心然後再從穩定核心中backport一些安全以及其他相關的修複呢?對于穩定核心的測試從來都是置之不理呢?“ 對于這個問題的答案麼,他自己半開玩笑的建議:可以将測試留給了使用者。除了上面這個半開玩笑的建議以外,大多數人都一緻認為:目前對于穩定核心,除了簡單的建構-啟動測試以外,幾乎很少有其他方面的測試。那麼這個現象是如何造成的呢?

核心測試的困境

第一點:開發者很難知道該去選擇什麼樣的上遊核心(upstream kernel)來測試。linux-next tree和穩定核心以及核心主線(mainline)都是在不斷地變化着,要想做到穩定測試是一件很難的事情。但是大家又都一緻同意,能在代碼釋出出來之前,發現其中的BUG還是很有價值的,是以一些發行版的研發人員就嘗試測試-rc1的核心。這樣做的話,如果bug被發現,它們将在釋出前就被修正,這樣看起來是不錯的,但是這樣需要非常多的時間和機器去做好這件事。另外,測試時使用的哪個版本的核心配置,也會使這個問題的複雜度翻倍。

第二點:核心測試消耗大量的人力物力。有人舉了一個生動的例子,紅帽(RedHat)需要花費一年的時間去穩定RHEL標明的核心版本。而粗略估計有300個工程師去做這個事情,這也就是意味着一個公司需要花費了300個人年去測試和穩固一個核心(譯者在此處還是要感謝一下REDHAT)。此外,在驅動程式中,通常驅動的自檢程式是應該由核心開發人員編寫,但将個人的測試變成可以更廣泛使用的東西需要很多時間和精力,而驅動的作者根本沒有時間去添加一個自檢程式,是以驅動大多數是沒有自檢程式的。在許多情況下,正是由于這個原因,導緻代碼品質很差。是以,現有的大部分自檢程式可能都是在子系統中并已經做了很好測試,這些測試用例還能發現的大部分的錯誤主要發生在與開發者自己運作的硬體架構不同有關,比如ARM相關的錯誤就是這樣被發現的。

第三點:啟動測試(boot testing)占了上遊核心測試的大頭,占據了開發者更多的精力,是以最新釋出的核心肯定可以啟動起來的。擁有特殊硬體的人會測試他們的驅動,是以通過這一測試也可以發現大部分驅動的bug。像Ftrace、排程器和記憶體管理由于使用的很廣泛,是以他們的測試也比較充分。除了以上這些元件以外,核心中其他的一些非核心或者不是被普遍使用的功能就可能沒有那麼多的功能測試了。

第四點:核心測試門檻較高,如環境裝置和知識儲備。對于一些想要測試驅動程式的人來說,他可能沒法獲得相應的硬體,即使有硬體,他還需要深入了解裝置是如何工作的。理想情況下,驅動程式的作者應該測試這些裝置,而大部分情況下也确實是這樣。不過這個解決方案仍然不是完美的。

第五點:測試覆寫不全面,測試方面單一。因為雖然驅動作者試圖確定在他的測試用例下驅動程式是正确工作的,但是他們有着不同的動機,如果他被雇傭做這個事情那麼可能測試會比較全面,而如果他僅僅是為了讓他自己的硬體可以正常工作,那麼可能測試不會太全面,同時相應的文檔也基本沒有。

第六點:需要制定測試指南和幫助文檔。例如,在核心測試中我們還需要發現一些可能引入的性能退化(performance regressions),但是如果僅僅是做一些”随機性能測試“(random performance testing),這是很難發現性能退化的,是以我們需要制定一些性能測試指南,以便可以進行一些蘋果對蘋果(apples-to-apples,譯為同類型的比較)的對比測試。再如,就像Mel Gorman的MMTests作為“kbench”這一性能測試套件的基礎,貌似有些與會者對這個測試套件不熟悉,是以MMTests需要有更好的文檔來幫助使用者去了解它。

第七點:進行核心測試的另一個困難是要核心配置的數量非常龐大。當穩定的核心被釋出的時候,它可能有100個更新檔,但任何測試套件都不可能執行許多次去測試這些更新檔,那麼測試穩定版本的意義到底是什麼呢?

總結一下,在所有的這些測試工作中,最大問題就是資源,我們需要更多的人和更多的機器,進而可以更早地發現和修複錯誤。

企業是如何做的

我們再把話題切回到穩定核心。如果我們可以阻止所有可能的bug引入到核心,那麼主線核心(mainline)無疑是完美的,我們也就不需要什麼穩定分支了(stable trees)。當然現實是殘酷的,完美也是不可能的,是以我們仍然需要穩定分支,但是發行版真的會使用穩定分支麼?讓我們一個一個看過去。

企業例子之一(紅帽)

紅帽有一個大型測試實驗室,有6000多台各種各樣的機器分布在世界各地。實驗室使用Beaker并測試了大量不同的核心配置,目前核心測試主要集中在三個RHEL核心和兩個Fedora核心上,未來他們會計劃添加一些主線版本的核心。在紅帽内部,不同的團隊專注于他們感興趣的驅動,比如存儲團隊在測試各種儲存設備,而RDMA團隊在測試RDMA類型的硬體。是以,對于紅帽而言,他們隻從穩定的樹上去挑選(cherry-pick)一些修複的更新檔。 RHEL的每個小版本核心都有8-10萬個更新檔,但是所有的這些更新檔都來自上遊而不是穩定分支。RHEL核心團隊會檢視穩定的分支和最新的主線核心,然後尋找有必要使用的更新檔。至于對應的測試則取決于這些更新檔是應用于哪一個子系統; 一些子系統在更新檔追溯方面做得很好,而其他子系統則較差。對于穩定核心的使用,一般Red Hat隻是編譯了一下并用它來和RHEL核心做對比測試,以确定這些錯誤是來自上遊還是在RHEL中引入的。

企業例子之二(SUSE和Ubuntu)

再看看SUSE,他們确實在建構穩定核心,但他們僅僅是為了挑選(cherry-pick)更新檔。他們有考慮将穩定的核心測試添加到SUSE的測試網格(testing grid)中,但大家還不清楚它會對公司帶來什麼樣的價值。Ubuntu面對的情況也是類似的:他們除了建立穩定的核心以外,并沒有對它們進行正式的測試。

企業例子之三(Linaro)

Linaro目前正在為谷歌開發一個使用核心自檢(kernel self-tests,縮寫kselftest)和Linux測試項目(Linux Test Project,縮寫LTP)來測試穩定的核心項目,這些測試會針對每個穩定的釋出版本來進行。自檢測試的确能發現bug,但編寫這些自檢測試的人可能并不是引入大多數錯誤的人。是以自檢測試還隻是一個開始,顯然Linaro還需要增加更多的測試。

是以綜合來看,版本釋出者一般都隻是關心,合并到穩定版本裡的修複(fix)是否是正确的,但是他們隻是從穩定版本中摘出修複(fix)然後放到自己的核心中做測試,對穩定核心本身的測試是非常有限的。于是有人建議可以由Linux基金會與Canonical,SUSE,Red Hat等公司一起組建一個合作項目,大家一起貢獻一部分機器同時形成一套測試套件來進行穩定核心的測試。

測試的不斷改善

例一:0天核心測試服務(0-Day kernel test service)。這個服務也不僅僅是建構和引導測試(build-and-boot tests),還包括一些性能測試。 kernelci.org項目也正在對許多不同的硬體進行建構和引導測試(build-and-boot tests),這些都是非常有價值的,但他們沒有做任何真正的功能性的測試。當然事情肯定會變得越來越好,大家不都是說“有比沒有好麼”。

例二:LTP(Linux Test Project)。它可以測試很多東西,但也有很多地方它并不會去測試。它會被一些發行版使用,然後也肯定能在裡面發現一些bug,但很明顯我們需要更多更好的測試套件。

例三:性能測試(benchmark)和模糊測試(fuzzing)。會上還讨論了穩定核心的模糊測試。模糊測試上遊核心是一種最好的選擇,因為所有問題的修補都在那裡,但它仍然可以在發行版的核心中發現問題。目前syzkaller fuzzer已經可以針對它發現的問題自動生成小的測試用例,大家也覺得這些應該被加入自檢測試集。雖然有人提到一些BUG隻在Kernel Address Sanitizer(縮寫KASAN)下才會出現,但這些測試在那些沒有被配置KASAN的核心上運作的時候是可以簡單地被跳過的。除了找BUG的測試之外,核心還需要更多的性能測試來發現性能退化(performance regressions),有人提到可以用Mel Gorman的MMTests作為“kbench”這一性能測試套件的基礎,隻是這個套件對應的文檔很少了,是以我們需要在核心文檔目錄中建立一個測試套件目錄作為一個開始,但任何複雜的性能測試顯然需要更加深入的文檔。

例四:基準數字(single number)。有人提議說,如果我們有一個性能測試然後給出一個基準數字,而我們可以基于這個數字來判斷性能是否有退化就完美了(比如BogoMips背後的想法),當然有另外一些人會質疑是否真的存在這樣的測試系統。

例五:自我測試(self-tests)。越來越多的自我測試,正在被添加到核心主線中,但是穩定的核心卻不會從中受益。有些人正在使用較老的核心進行最新的自我檢測,于是有人提議也許自我測試本身應該被移植到穩定的核心樹中。

例六:神經網絡訓練。随着BoF的結束,Levin要求發行版的維護者将他們正在使用的更新檔推向穩定的分支中去。一般發行版中的問題在穩定核心中也一定存在。他最近一直在努力訓練一個神經網絡來識别适用于穩定核心的更新檔,這引起了一些笑聲,但他說結果是“出人意料的好”。

核心測試的一些其他聲音

Greg Kroah-Hartman是穩定核心的維護者,他沒有參加BoF但是其實對BoF的讨論内容也有興趣。于是第二天當Levin在一個小型會議中概括總結BoF的讨論結果的時候,Greg給出了他的一些意見。

首先正如Levin所說,在BoF中大家提出了很多的觀點,但是并沒有什麼相應的解決措施。有人建議應該向kernelci.org項目提供更多的硬體,Kroah-Hartman同時希望能看到更多的功能測試。另外還有一些人提議應該讓Linaro和kernelci.org一起努力合作這樣更好。

關于移植自我檢測(self-tests),Kroah-Hartman并不反對這個想法,隻要它們能在出問題的核心上運作就可以。他也同意如果發行版能将它們的修補更新檔打在穩定的分支(tree)上,那将是一件很好的事情,而且他提到Fedora和Debian已經在該領域做得很好。另一位與會者表示,發行版經常會盡快為使用者快速解決問題,然後才會做好上遊核心的工作。 Kroah-Hartman表示,如果有BUG在上遊核心中沒有被修複的話,他也不會在穩定核心中修複,這樣一方面上遊核心和穩定核心做到了“bug相容”,另一方面也給了那些廠商一些壓力來修複它。

結語

我們需要進行更多的核心測試,這是毋庸置疑的,但是它究竟應該采用什麼樣的形式以及由誰來做仍然不清晰。如果幸運的話,在不久的将來這塊會有一些進展,同時也意味着我們有可能會更早地發現BUG。當然,完美是不可能的,但是我們大家都希望能夠減少核心裡的錯誤,對麼?另外一點,大家對于上遊核心(upstream)的熱情是遠遠高于穩定核心(stable)的,是以對于穩定核心的測試肯定仍然會比較少,是以穩定核心的“穩定性”是大打折扣的。

繼續閱讀