3. 早期规划

在考虑一个 Linux 内核开发项目时,人们可能会禁不住诱惑,立即着手编写代码。然而,与任何重要项目一样,成功的大部分基础最好在编写第一行代码之前就奠定好。早期规划和沟通所花费的一些时间可以在后期节省更多时间。

3.1. 明确问题

与任何工程项目一样,成功的内核增强始于对要解决的问题的清晰描述。在某些情况下,这一步很简单:例如,当需要特定硬件的驱动程序时。但在其他情况下,人们往往会混淆实际问题与建议的解决方案,这可能导致困难。

举个例子:几年前,从事 Linux 音频开发的开发者们寻求一种方法,使应用程序能够运行,而不会出现由系统过度延迟引起的卡顿或其他伪影。他们找到的解决方案是一个旨在挂接到 Linux 安全模块(LSM)框架的内核模块;该模块可以配置为允许特定应用程序访问实时调度程序。该模块被实现并发送到 linux-kernel 邮件列表,但立即遇到了问题。

对于音频开发者来说,这个安全模块足以解决他们的燃眉之急。然而,对于更广泛的内核社区而言,它被视为滥用 LSM 框架(LSM 的目的并非赋予进程额外的特权),并且对系统稳定性构成风险。他们首选的解决方案是短期内通过 rlimit 机制访问实时调度,以及长期持续进行延迟降低工作。

然而,音频社区无法跳出他们已实现的特定解决方案;他们不愿接受其他替代方案。由此产生的意见分歧让这些开发者对整个内核开发过程感到幻灭;其中一人回到音频邮件列表并发布了这条消息:

有很多非常优秀的 Linux 内核开发者,但他们往往被一大群傲慢的蠢货盖过风头。试图向这些人传达用户需求简直是浪费时间。他们太“聪明”了,不屑于倾听凡夫俗子的意见。

(https://lwn.net/Articles/131776/)。

实际情况并非如此;内核开发者更关心系统稳定性、长期维护以及找到正确的解决方案,而不是某个特定的模块。这个故事的寓意是,要专注于问题——而不是某个具体的解决方案——并在投入大量代码编写之前,与开发社区进行讨论。

因此,在考虑一个内核开发项目时,应该回答以下几个简短的问题:

  • 究竟需要解决什么问题?

  • 哪些用户受到这个问题的影响?解决方案应该解决哪些用例?

  • 目前内核在解决这个问题上有什么不足?

只有这样,才开始考虑可能的解决方案。

3.2. 早期讨论

在规划内核开发项目时,在开始实施之前与社区进行讨论非常有意义。早期沟通可以通过多种方式节省时间和麻烦:

  • 很可能这个问题已经被内核以你尚未理解的方式解决了。Linux 内核庞大,拥有许多并非显而易见的功能和能力。并非所有内核功能都得到了人们所希望的良好文档记录,因此很容易遗漏。本文作者曾见过一份完整的驱动程序发布,它复制了一个现有驱动程序,而新作者对此一无所知。重复造轮子的代码不仅浪费,也不会被主线内核接受。

  • 提议的解决方案中可能存在一些不适合主线合并的元素。最好在编写代码之前发现此类问题。

  • 完全有可能其他开发者也考虑过这个问题;他们可能有更好的解决方案,并可能愿意协助创建该解决方案。

多年与内核开发社区打交道的经验清楚地表明了一个教训:闭门设计和开发的内核代码总是存在问题,这些问题只有在代码发布到社区后才会暴露出来。有时这些问题非常严重,需要数月甚至数年的努力才能使代码达到内核社区的标准。一些例子包括:

  • Devicescape 网络栈是为单处理器系统设计和实现的。它直到被改造为适用于多处理器系统后才能合并到主线。将锁定等功能改造到代码中是一项艰巨的任务;因此,该代码(现在称为 mac80211)的合并被推迟了一年多。

  • Reiser4 文件系统包含了一些功能,核心内核开发者认为这些功能应该在虚拟文件系统层实现。它还包含了一些功能,如果实现不当,很容易导致用户引起的死锁。这些问题被迟迟发现——以及拒绝解决其中一些问题——导致 Reiser4 一直未能进入主线内核。

  • AppArmor 安全模块以被认为不安全和不可靠的方式使用了内部虚拟文件系统数据结构。这一担忧(以及其他担忧)使 AppArmor 多年来未能进入主线。

在所有这些案例中,如果能与内核开发者进行一些早期讨论,就可以避免大量的痛苦和额外工作。

3.3. 和谁交谈?

当开发者决定公开他们的计划时,下一个问题是:我们从何开始?答案是找到正确的邮件列表和正确的维护者。对于邮件列表,最好的方法是在 MAINTAINERS 文件中查找一个相关的发布地点。如果有合适的子系统列表,在那里发布通常比在 linux-kernel 上发布更好;你更有可能接触到在相关子系统方面有专长的开发者,而且环境可能更具支持性。

找到维护者可能有点困难。同样,MAINTAINERS 文件是起点。然而,该文件往往并非总是最新的,而且并非所有子系统都在其中有所体现。MAINTAINERS 文件中列出的人,实际上可能并非当前担任该角色的人。因此,当不确定联系谁时,一个有用的技巧是使用 git(特别是“git log”)来查看感兴趣的子系统中有谁是活跃的。查看谁在编写补丁,以及谁(如果有的话)在这些补丁上附有 Signed-off-by 行。这些人将最适合协助新的开发项目。

找到合适的维护者有时具有相当大的挑战性,以至于内核开发者添加了一个脚本来简化这个过程:

.../scripts/get_maintainer.pl

当给定“-f”选项时,此脚本将返回给定文件或目录的当前维护者。如果通过命令行传递补丁,它将列出应该接收补丁副本的维护者。这是获取你的补丁需要抄送的人员列表的首选方法(与“-f”选项不同)。有许多选项可以调节 get_maintainer.pl 搜索维护者的难度;请注意不要使用更激进的选项,因为你最终可能会包含那些对你正在修改的代码没有实际兴趣的开发者。

如果所有其他方法都失败了,与 Andrew Morton 交谈是找到特定代码维护者的有效方法。

3.4. 何时发布?

如果可能,在早期阶段发布你的计划只会带来帮助。描述要解决的问题以及为实现方式所做的任何计划。你提供的任何信息都可以帮助开发社区为项目提供有用的意见。

在此阶段可能发生的一件令人沮丧的事情并非敌意反应,而是几乎没有或根本没有反应。令人遗憾的事实是:(1) 内核开发者通常很忙,(2) 拥有宏伟计划但代码很少(甚至没有代码前景)的人不在少数,以及 (3) 没人有义务审查或评论他人提出的想法。除此之外,高层设计常常隐藏着只有当有人真正尝试实现这些设计时才会暴露出来的问题;因此,内核开发者宁愿看到代码。

如果征求意见的帖子几乎没有得到评论,不要以为这意味着对项目不感兴趣。不幸的是,你也不能假设你的想法没有问题。在这种情况下,最好的做法是继续推进,并随时向社区通报进展。

3.5. 获得官方认可

如果你的工作是在企业环境中完成的——就像大多数 Linux 内核工作一样——那么显然,你必须获得拥有适当权限的经理的许可,才能将你公司的计划或代码发布到公共邮件列表。发布未经许可在 GPL 兼容许可下发布的代码可能尤其成问题;公司管理层和法务人员越早同意发布内核开发项目,所有相关人员的情况就越好。

有些读者此时可能在想,他们的内核工作旨在支持一个尚未得到官方承认存在的产品。在公共邮件列表上透露雇主的计划可能不是一个可行的选择。在这种情况下,值得考虑这种保密是否真的必要;通常没有真正的必要将开发计划秘而不宣。

话虽如此,也有一些情况是公司在开发过程早期合法地不能披露其计划。拥有经验丰富的内核开发者的公司可能会选择以开放式循环的方式进行,假设他们将来能够避免严重的集成问题。对于没有这种内部专业知识的公司,最好的选择通常是聘请外部开发者在保密协议下审查计划。Linux 基金会运营一个 NDA 项目,旨在帮助处理此类情况;更多信息可在以下网址找到:

这种审查通常足以避免后期出现严重问题,而无需公开披露项目。