29 年過百萬次commit,Linux 內核何以發展至今?
1991 年,21 歲的芬蘭大學生Linus Torvalds 寫下第一行Linux 內核代碼時,多半沒有想到它會成長為今天這樣的龐然大物。當年8 月25 日,Torvalds 在Minix Usenet 新聞組裡發了一封帖子,稱自己正在做一個自由的操作系統,“就是個興趣愛好,不會搞得像GNU 那麼大那麼專業”。
事情的發展顯然遠超他的預期,如今小到傳感器,大到超級計算機,從智能手機、手錶、汽車等日常用品到航天器等設備,Linux內核的身影已無處不在。
隨著迄今為止最大版本 Linux Kernel 5.8 於今年8月初的發布,Linux內核已擁有超過2萬名貢獻者,歷史commit數超過100萬次,迎來一個新的里程碑。
上週恰逢Linux 29週年紀念日,Linux基金會發布了一份詳盡的Linux內核報告,涵蓋了自1991年9月17日首次發布以來,到2020年8月2日最新版本的Linux內核歷史。
版本控制:從 BitKeeper 到 Git
Linux基金會從2008年開始每年發布Linux內核報告,但此前一直難以將其發展過程完整串聯起來。今年,借助Daniel German博士的cregit工具,他們成功追溯到了第一個版本,Linux內核的發展時間線變得清晰。根據版本控制方式,可大致分為以下三個階段:
- pre-version control(前版本控制): 1991年9月- 2002年2月4日
- BitKeeper: 2002年2月4日- 2005年4月15日
- Git: 2005年4月16日至今
版本控制對社區協作能力影響重大,這在2000 年代初是一件令人頗為苦惱的事情。使用版本控制系統,也就是 BitKeeper 之前,貢獻者需要將補丁提交至郵件列表,待Torvalds 接受後放進源碼樹,再發布整個樹的新版本。在這種方式下,具體是誰在做貢獻、貢獻的數量和路徑都不夠透明。
2002 年2 月4 日,BitKeeper 的使用標誌著Linux 內核commit 歷史的開啟。然而 BitKeeper 為專有軟件,這一決定在社區中遭受了長期質疑。直到2005 年,BitKeeper 擁有者Larry McVoy 決定收回無償使用BitKeeper 的許可。Torvalds 本人當時又對現成的 CVS 和 Subversion 等集中式版本控制工具感到不滿,因此自己動手,用十天時間寫出了Git 的第一個版本。
Git目前已成為開發者們非常熟知且廣泛使用的分佈式版本控制系統。Linus Torvalds則表現得更多的是迫於無奈,他曾聲稱自己“ 根本不想做源代碼管理,覺得這是計算機世界中最無趣的事情”。
自從版本控制系統由BitKeeper 改為Git 後,Linux 內核每年的貢獻者和commit 數量都在穩步增長。歷年的內核報告數據顯示,2005 年5 月發布的2.6.12 版本平均每小時收到2 次commit。15 年後,2019 年的平均數是每小時9.4 次。而在最新的5.8 內核中,平均每小時commit 數達到了10.7 次。
繁雜且自成體系的內核代碼
首個內核版本 linux-0.01.tar.Z 由88 個文件和10,239 行代碼組成,運行在i386 這樣單一的硬件架構上。到了5.8 版本,這一數據擴張為69,325 個文件和28,442,673 行代碼,並能夠在30 多種主要的架構上運行。
數量上的龐大僅是Linux 內核代碼的表象,它自身更是形成了一套複雜的體系,不熟悉的人往往不知從何處下手,極有可能“牽一發而動全身”。這或許也是內核維護者難尋的原因之一。
Linux內核發布第一天起的某些代碼仍在當前版本中使用,例如Torvalds和大學好友Lars Wirzenius共同編寫的 vsprintf例程,它也是為數不多存在至今的首次commit中的源代碼。
今年的內核報告提到,有 2,964 個能被追溯至1991 年的token 如今在5.8 版本中也能找到。5.8 版本超過一半的代碼寫於近7 年內,但之前所有年份都對此版本有貢獻。過去的代碼不斷在後續的版本中留下痕跡。
持續膨脹的內核文件量和代碼行數未見得完全是一件好事,為了使系統不變得臃腫,內核維護者需要做一些修枝剪葉的工作。Linux內核中未使用的代碼和文件都會被視情況刪除,有一些版本還會進行大的清理,例如2018年的4.17版本,刪除了8個架構,淨減少代碼大約180,000行。
不僅僅是源碼,Linux 內核維護者還會關注空白行和代碼註釋,以確保源碼的可讀性。
開發者原創證書和標籤管理
2004年對開發者原創證書(Developer Certificate of Origin,簡稱DCO)的標準化是Linux內核史上的一個關鍵變化點。DCO的引入為開發者和用戶提供了法律保護,同時又不至於增加程序負擔。它極大地提高了跟踪補丁進入內核的路徑的能力,加上版本控制系統向Git的過渡,DCO有效地減輕了開發者做貢獻的開銷,因此變得很受歡迎,後來也被許多其他開源項目採用。
隨著DCO 的標準化使用,現在幾乎所有的commit 都有一個Signed-off-by 標籤。通常每個commit 平均會有兩個該標籤,能夠反映代碼在合併之前的維護者層次結構,有助於追溯補丁進入代碼的路徑。
Signed-off-by 之外,Linux 內核還增加了表示審查的標籤(Reviewed-by 和Acked-by)。審查對內核代碼的質量來說相當重要,標籤的加入令這個過程更加清晰,有越來越多的維護者選擇使用標籤來表示已審查。
在審查git 倉庫時,Linux 基金會發現了一些比較有趣的標籤,像是”Enithusiastically-ack’d by”、”Thanksto”、”Based-on-the-Original-screenplay-by”、”Catched-by -andrightfully-ranted-at-by” 等等。但這些標籤並沒有像上述兩類一樣被廣泛採用。
行之有效的發布模式
Linux內核的發布模式已漸趨成熟,現在基本固定為Prepatch(或”-rc”)、Mainline、Stable和Long Term Stable 四類版本。
社區曾對發布週期進行了大量的探討和實驗,並逐漸找到了行之有效的發布模式,發布週期也幾乎完全可預測——每個發布週期由時長兩週的“合併窗口”開始,這時,新功能經適當的review 後可被納入接下來要發布的git 倉庫。一旦它被標記為rc1,那麼集成測試、調試和穩定化的周期就開始了。然後每週對rc 候選版本進行標記,直到達到目標質量和穩定性。發布後,隨著下一個合併窗口的到來,這個週期又開始循環。
內核的主線樹由Linus Torvalds 維護,這棵樹引入了所有新功能。新的主線(Mainline)內核每2 到3 個月發布一次。但這樣的發布節奏較慢,難以滿足大多數用戶的需求。因此,從2005 年開始,每週發行一次穩定版(Stable)內核。
用戶還想要受維護時間更長的版本,於是2006年發布的2.6.16版本成為第一個長期支持(LTS)版本內核。此後每年都有一個新的LTS內核,該內核將由內核社區維護至少2年(從4.4版本開始延長至6年)。Linux內核官網公佈了所有現存LTS版本的發行日期、EOL日期及維護者(目前6個LTS版本都由Greg Kroah-Hartman和Sasha Levin這兩人維護)。
貢獻者:長尾的力量不可忽視
不少組織都在為Linux內核做貢獻,貢獻者排行榜前列幾乎都被Intel、Red Hat、IBM、SUSE、Google、Samsung、AMD、Oracle、華為和ARM這樣的大企業佔據。
從2007 年到2019 年,Linux 內核共接受了來自1,730 個組織的780,048 次commit。排在最前面的20 個組織佔了68% 的commit 量。
在過去十年中,每年有超過400 個組織為Linux 內核做出貢獻。其中相當一部分可能只有過一次commit。從每年的commit 比例來看,其中1/3 貢獻來自神秘的長尾。也就是圖中最上面淺灰色“Others” 的部分。
Linux 基金會指出,企業的貢獻會根據業務需求和戰略的不同而有所變化。前20 名貢獻者中,有些是2007 年之後才加入,有些在此前做過很多貢獻的公司,被收購後便不再繼續參與。貢獻者的多樣性為內核發展賦予了一些彈性。
除了組織貢獻者,Linux 內核社區成員也致力於增加個人貢獻者的多樣性,他們通常願意花費自己的時間來指導新的開發者。Linux 基金會有一個Kernel Mentorship(LKMP)項目,用來幫助新加入開源的開發者進行實驗、學習,並為開源社區做出貢獻。
內核社區的共同目標:高質量、可靠性
報告的最後,Linux 基金會指出,內核社區的重點是保持一個共同的目標,即擁有一個沒有回歸的高質量操作系統,願意根據需要創建新的流程和工具,以幫助提高效率,並繼續提升Linux內核的可靠性。
內核測試現在也引入了一些自動化測試工具:靜態分析工具如sparse(語義解析器)、smatch(源匹配器)和cocicheck(語義補丁,測試特定的bug),由0-day 和Hulk Robot 這樣的自動測試機器人在Linux 內核樹上運行。機器人在發現和跟踪bug 上起到不少作用。這些測試工具能夠幫助開發人員跟上上游內核的速率變化,並繼續改進內核版本,提升其穩定性。
Linux 內核如今被應用於諸多領域,基金會認為,改進基礎設施,進行正確的安全分析,是接下來要應對的重大挑戰之一。目前Linux 內核已擁有一個很好的基礎,它應當繼續引領創造最佳實踐,以促進整個開源軟件行業的發展。