如何参与Linux主线内核开发
无论您的工作是否与Linux内核开发有关,您一定听说过这一世界上非常著名的开源项目。它是由Linus Torvalds于1991年在Usenet的comp.os.minix新闻组上发布的操作系统内核经过社区不断演进而成,兼容POSIX标准,被广泛运用于服务器、移动终端(Android操作系统生态)和桌面PC等领域。
Linux内核社区是一个开放包容的开源社区,正是由于这份开放与包容和一群极具geek精神的专家及开源公司持续不断地投入,Linux生态才能持续健康发展。众人拾柴火焰高,因此请相信,有益于codebase的补丁修改提交到主线内核并非难事。
本文假定读者了解git的使用方式,且仅讨论一般流程不展开技术细节。
一、开发流程
当前Linux主线由Linus Torvalds大神维护,主线开发就是将自己创作的补丁提交到Linus大神的主线分支里。
每个新内核版本的发布前都会经历数个-rc小版本的公开测试和修复,这些-rc[1]和最终版本[2]的发布也都由Linus大神亲力亲为。容易理解,对于像Linux这么庞大的代码规模,Linus大神本人是无法亲自完成整个内核维护的。因此Linux内核开发按代码拓扑划分为各个子系统管理,绝大多数子系统都有maintainer(或maintainer团队)义务负责维护。
一般来说,新特性都需要在-rc1前合入,-rc1发布前一般有两周合入期,这个时间段Linus大神会处理各个子系统maintainer提交的pull requests,并反馈是否接受这些子系统的修改(可能还会有些有意思的讨论。。图片),因此这一时期被称为merge window。一旦merge window关闭,从-rc2到-final(每个rc一周)不再允许新特性合入,而专注于该版本质量的提升,Linus大神仍然会处理各个子系统maintainer提交的pull requests,不过这些pull request只会专注于bugfix上。一个新版本的发布周期大概为2个月左右,周而复始。
如上图所示(作者Greg KH),每个maintainer负责它所属维护范围的补丁收集和测试工作,然后交给更高一级maintainer,直到最终被Linus拉入自己的分支中。各级maintainer在-rc1 ~ -final间拉取重要的修复并及时提交给上级,而新特性则会pending直到下个版本的-final ~ -rc1的merge window中进行。至于某些不明归属的补丁可能会进入Andrew Morton的queue中,所以对于这些补丁,你需要吸引akpm大神的注意 :) (当然akpm大神主要负责-mm tree)
另外需要留意上图中的-next仓库,它是由Stephen Rothwell大神维护的快照分支,目的是体现已合入各maintainers分支但没有合入Linux主线的提交,一般来说这个分支负责合入主线前的冲突处理和整体系统测试。作为开发者您也需要关注这个-next分支来了解最新开发全景动态!
顺带提一下stable和LTS内核。新的Linux版本发布后,它就会被纳入stable内核管理,直到下一个新版本内核发布为止。这个期间所有被标记了Fixes和Cc stable的稳定性和安全主线补丁会被回合到老的stable内核中。比较老旧的内核书籍可能会介绍奇偶版本规则(例如2.4、2.6稳定,2.3、2.5不稳定),但这一规则早已过时。LTS版本为长期演进版本,它可以被社区支持长达数年,一般每年下半年会产生一个LTS版本,通常每5个版本产生一个LTS版本(例如4.4、4.9、4.14、4.19,5.4好像除外图片)
二、下载Linux源码
大家一定访问过kernel.org,它是由Linux基金会运营的内核代码托管网站,用于存放Linux主线、stable、LTS和各个子系统分支及内核周边工具源码。
作为用户,大家可能平日关注的是此网站里发布的stable或者LTS内核源码包。而作为内核开发者,如上文所言,Linux主线分支就是Linus大神的分支,因此克隆一份最新主线git仓可以了解下当前已合入主线的既定事实提交。
Linux主线git仓地址为:
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
当您想修复某一个子系统的bug时,由上文所述,克隆该子系统的独立git树是十分必要的,这些信息记录在源码的MAINTAINERS里。您可以通过scripts/get_maintainer.pl来查询,例如查看fs/erofs的信息,可以输入:
scripts/get_maintainer.pl --scm -f fs/erofs
当您需要开发独立特性(尤其是跨模块特性)或者需要了解下您的补丁对全系统开发动态的影响时,-next也是需要关注的一个仓库。
-next仓库的git地址为:
git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
三、制作补丁
大家可能尝试过github开发的fork+pull模式,是的,Linux内核演进本质上也是一种基于邮件列表的fork+pull模式。只是由于信任链的问题,Linus或者大maintainers可能不太会直接接受未经社区测试的pull request。所以通常情况下是各开发者自行制作补丁(集)再通过电子邮件发送到可能接受补丁的maintainers、邮件列表和潜在可能帮助您review的内核开发者们。
正规的内核提交流程在发送前需要检查末尾Signed-off-by标志来标明您(或者您的组织)的所有权并允许将其体现到内核中(更正规的描述见[3]),注意一般来说该提交的原作者需要跟Signed-off-by标志对应。通过git commit --amend --signoff命令可以很方便地附加该标志。
我个人习惯在整理补丁前checkout到一个临时开发分支,apply并确认各补丁基本正常后,使用git format-patch -M -o patches origin/dev等此类命令生成补丁文件。这些补丁文件使用一种canonical patch format,它其实是一种便于邮件发送的格式。您可以通过vim等文本编辑工具进一步后处理补丁,例如增加changelog。通过scripts/checkpatch.pl检查补丁中的代码和提交风格问题。
通过scripts/get_maintainer.pl来查询maintainers和需要发送的邮件列表。最后通过git send-email来发出补丁(集)。更详细的说明可以看内核源码中的ReST中文文档:Documentation/translations/zh_CN/process/submitting-patches.rst [3]
四、订阅社区邮件列表
因为开发者们会在各大内核邮件列表公布他们最新的开发成果,这往往会伴随十分有意义的技术讨论,另外自动化测试工具也会把测试结果及时发送到相关邮件列表中,这可以作为问题输入,所以订阅社区邮件列表是十分有必要的。
大家可以通过上文提到的scripts/get_maintainer.pl来查询这些邮件列表,一般来说大部分邮件列表都托管在vger.kernel.org上,通过发送内容为subscribe xxx (xxx为邮件列表名,例如linux-fsdevel)的纯文本邮件到majordomo@vger.kernel.org来完成列表订阅。
顺带提一句,主流邮件列表归档都可以在lore.kernel.org中查阅,非常方便。
五、准备讨论,修订补丁
除了那些很明确的补丁,多模块间的修改或者涉及critical path等影响面比较大的补丁(集)往往是具有较大争议性的。这类补丁往往需要进行多轮社区讨论和修订。
社区讨论邮件也都是纯文本的邮件(HTML邮件可能会被邮件列表服务器拒收或丢弃掉),且为inline-posting风格,注意尽量不要top-posting。
建议使用mutt或者配置过的thunderbird客户端来发送社区邮件,不要使用outlook或者内置web客户端来参与讨论。因为这些客户端可能会破坏原邮件格式并可能给内核开发者们留下不好的印象。
通过在PATCH后增加v2、v3等标识来区分新的补丁(集),即便实际只修改了commit message,此类补丁标题一般为:
[PATCH] fs/ext4(模块名): fix memory leak(修改简述)
[PATCH v2] fs/ext4: fix memory leak
[PATCH v3] fs/ext4: fix memory leak
…
这样开发者可以很容易区分哪些补丁是开发者认为的更新的版本(有时邮件发送时间戳并不靠谱)。
六、引用资料
[1] Linux 5.6-rc7
https://lore.kernel.org/r/CAHk-=wipv1y2Z7=CDQ5ajb2OvSyq-0BL9yLRPm1YqW+sjcSDzQ@mail.gmail.com
[2] Linux 5.6
https://lore.kernel.org/r/CAHk-=wi9ZT7Stg-uSpX0UWQzam6OP9Jzz6Xu1CkYu1cicpD5OA@mail.gmail.com
[3] Submitting patches: the essential guide to getting your code into the kernel
https://www.kernel.org/doc/html/latest/process/submitting-patches.html
中文翻译:
https://www.kernel.org/doc/html/latest/translations/zh_CN/process/submitting-patches.html
本文转自公众号:猴子的自我修养