6. 后续工作

至此,您已经遵循了到目前为止给出的指导方针,并凭借您自身的工程技能,发布了一系列完美的补丁。即使是经验丰富的内核开发者也可能犯的最大错误之一是认为他们的工作已经完成。事实上,发布补丁标志着进入流程的下一个阶段,可能还有相当多的工作要做。

很少有补丁在首次发布时就已尽善尽美,没有改进空间。内核开发流程认识到这一事实,因此,它高度重视对已发布代码的改进。作为代码的作者,您将被期望与内核社区合作,以确保您的代码符合内核的质量标准。未能参与此过程很可能会阻碍您的补丁被纳入主线。

6.1. 与审阅者合作

任何有重要性的补丁都会在其他开发者审阅代码时引出许多评论。对于许多开发者来说,与审阅者合作可能是内核开发流程中最令人生畏的部分。然而,如果您记住一些事情,事情就会变得容易得多。

  • 如果您很好地解释了您的补丁,审阅者将理解其价值以及您为什么费心编写它。但这种价值不会阻止他们提出一个根本性问题:五年或十年后,维护一个包含此代码的内核会是怎样的?您可能被要求进行的许多更改——从编码风格调整到实质性重写——都源于这样一种理解,即十年后 Linux 仍将存在并处于开发中。

  • 代码审阅是一项艰苦的工作,而且是一项相对吃力不讨好的职业;人们会记住谁编写了内核代码,但对那些审阅代码的人来说,却鲜有持久的声誉。因此,审阅者可能会变得暴躁,尤其是当他们看到同样的错误一再出现时。如果您收到的审阅看起来愤怒、侮辱性或完全冒犯,请抵制以牙还牙的冲动。代码审阅是关于代码,而不是关于人,代码审阅者并非在人身攻击您。

  • 同样,代码审阅者并非试图以牺牲您的利益为代价来推行其雇主的议程。内核开发者通常期望在未来几年内继续致力于内核开发,但他们明白他们的雇主可能会改变。他们几乎无一例外地真正致力于创建他们所能做到的最佳内核;他们不是为了给其雇主的竞争对手制造麻烦。

  • 请为看似愚蠢的编码风格更改请求以及将您部分代码提取到内核共享部分的请求做好准备。维护者的一项工作是保持事物的一致性。有时这意味着您驱动程序中解决问题的巧妙技巧实际上需要成为一个通用的内核功能,为下次使用做好准备。

所有这一切归结为,当审阅者给您发送评论时,您需要注意他们提出的技术观察结果。不要让他们的表达方式或您自己的自尊心阻碍这一点。当您收到补丁的审阅评论时,请花时间理解审阅者试图表达的内容。如果可能,请修复审阅者要求您修复的问题。并回复审阅者:感谢他们,并说明您将如何回答他们的问题。

请注意,您不必同意审阅者建议的每一项更改。如果您认为审阅者误解了您的代码,请解释实际情况。如果您对建议的更改有技术异议,请说明并论证您解决问题的方案。如果您的解释合理,审阅者会接受。然而,如果您的解释未能说服他人,特别是当其他人开始同意审阅者时,请花些时间重新考虑。您可能很容易被自己的解决方案蒙蔽,以至于没有意识到某些地方根本性地错了,或者,您甚至没有解决正确的问题。

Andrew Morton 建议,每一条未导致代码更改的审阅评论都应改为添加一条额外的代码评论;这可以帮助未来的审阅者避免首次出现的问题。

一个致命的错误是忽视审阅评论,希望能让它们自行消失。它们不会消失。如果您在没有回应上次收到的评论的情况下重新发布代码,您很可能会发现您的补丁无法被接受。

说到重新发布代码:请记住,审阅者不会记住您上次发布代码的所有细节。因此,提醒审阅者之前提出的问题以及您如何处理它们,总是一个好主意;补丁更改日志是放置此类信息的好地方。审阅者不应该通过搜索邮件列表存档来了解上次说了什么;如果您帮助他们快速开始,他们在重新审阅您的代码时心情会更好。

如果您已经尽力做到了一切,但事情仍然毫无进展怎么办?大多数技术分歧可以通过讨论解决,但有时就是有人必须做出决定。如果您真诚地认为这个决定对您不利是错误的,您总可以尝试向更高的权力求助。截至本文撰写之时,这种更高的权力通常是 Andrew Morton。Andrew 在内核开发社区中备受尊敬;他经常能解决看似无望的僵局。然而,向 Andrew 申诉不应轻率行事,并且必须在探索所有其他替代方案之后。当然,请记住,他也可能不同意您的观点。

6.2. 接下来会发生什么

如果一个补丁被认为是应该添加到内核的好东西,并且大多数审阅问题都已解决,那么下一步通常是进入子系统维护者的树中。其运作方式因子系统而异;每个维护者都有自己的行事方式。特别是,可能会有不止一个树——一个可能专用于计划在下一个合并窗口提交的补丁,另一个用于长期工作。

对于适用于没有明显子系统树的区域(例如内存管理补丁)的补丁,默认树通常最终是 -mm。影响多个子系统的补丁也可能最终通过 -mm 树。

被纳入子系统树可以提高补丁的可见性。现在,使用该树的其他开发者将默认获得此补丁。子系统树通常也会向 linux-next 提供内容,使其内容对整个开发社区可见。此时,您很有可能会收到来自一组新审阅者的更多评论;这些评论需要像上一轮一样得到回复。

此时,根据您的补丁性质,还可能出现与他人正在进行的工作发生冲突的情况。在最坏的情况下,严重的补丁冲突可能导致部分工作被搁置,以便剩余补丁能够被整理并合并。其他时候,冲突解决将涉及与其他开发者合作,并可能在不同树之间移动一些补丁,以确保所有内容都能干净地应用。这项工作可能很痛苦,但请心存感激:在 linux-next 树出现之前,这些冲突通常只在合并窗口期间出现,并且必须仓促解决。现在,它们可以在合并窗口打开之前,从容地得到解决。

有一天,如果一切顺利,您登录时会看到您的补丁已被合并到主线内核中。恭喜!然而,庆祝结束后(并且您已将自己添加到 MAINTAINERS 文件中),值得记住一个重要的小事实:工作仍然没有完成。合并到主线带来了它自己的挑战。

首先,您的补丁的可见性再次提高。可能会有来自之前不了解该补丁的开发者的新一轮评论。您可能会想忽略它们,因为您的代码是否会被合并已不再是问题。然而,请抵制这种诱惑;您仍然需要回应那些有问题或建议的开发者。

然而,更重要的是:纳入主线会将您的代码交到更大一群测试人员手中。即使您贡献了一个尚未可用硬件的驱动程序,您也会惊讶于有多少人会将您的代码构建到他们的内核中。当然,有测试人员的地方,就会有错误报告。

最糟糕的错误报告是回归错误(regressions)。如果您的补丁导致回归,您会发现有大量目光不适地落在您身上;回归错误需要尽快修复。如果您不愿意或无法修复回归(且没有人为您修复),您的补丁几乎肯定会在稳定期被移除。除了否定您为将补丁纳入主线所做的一切工作之外,因未能修复回归而导致补丁被撤回很可能会使您未来更难将工作合并。

处理完所有回归错误后,可能还有其他普通错误需要处理。稳定期是您修复这些错误并确保您的代码在主线内核发布中尽可能稳固的最佳机会。因此,请回应错误报告,并尽可能修复问题。这就是稳定期的目的;一旦旧补丁的任何问题都已处理完毕,您就可以开始创建很棒的新补丁了。

并且不要忘记还有其他可能产生错误报告的里程碑:下一个主线稳定版发布、知名发行商采用包含您的补丁的内核版本等。继续回应这些报告是您工作中的基本自豪感问题。然而,如果这不足以成为动力,那么也值得考虑的是,开发社区会记住那些在代码合并后对代码失去兴趣的开发者。下次您发布补丁时,他们会假设您之后不会继续维护它来评估您的补丁。

6.3. 其他可能发生的情况

有一天,您可能会打开您的邮件客户端,看到有人给您的代码发送了一个补丁。毕竟,这也是您的代码开源的一个优势。如果您同意该补丁,您可以将其转发给子系统维护者(请务必包含正确的 From: 行以确保归属正确,并添加您自己的签署),或者发送一个 Acked-by: 回复并让原始提交者向上发送。

如果您不同意该补丁,请发送礼貌的回复说明原因。如果可能,请告诉作者需要进行哪些更改才能让您接受该补丁。对于作者和代码维护者反对合并的补丁,存在一定的阻力,但这阻力并非绝对。如果您被认为是无故阻碍好的工作,那些补丁最终会绕过您并进入主线。在 Linux 内核中,没有人对任何代码拥有绝对的否决权。也许除了 Linus。

在极少数情况下,您可能会看到完全不同的情况:另一位开发者发布了您问题的不同解决方案。此时,很可能这两个补丁中只有一个会被合并,而“我的补丁先在这里”并不被认为是令人信服的技术论点。如果别人的补丁取代了您的并进入了主线,实际上只有一种回应方式:为您的问题得到解决而高兴,然后继续您的工作。以这种方式被搁置工作可能会令人受伤和沮丧,但社区会记住您的反应,远比他们记住哪个补丁最终被合并更长久。