6. 后续跟进

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

很少有补丁在第一次发布时就足够好,以至于没有改进的空间。内核开发过程认识到这一事实,因此,它非常注重改进已发布的代码。您作为该代码的作者,将被期望与内核社区合作,以确保您的代码符合内核的质量标准。不参与此过程很可能会阻止您的补丁被纳入主线。

6.1. 与评审人员合作

任何重要的补丁都会导致其他开发人员在审查代码时提出一些意见。对于许多开发人员来说,与评审人员合作可能是内核开发过程中最令人畏惧的部分。但是,如果您记住以下几点,生活会变得轻松得多

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

  • 代码审查是一项艰苦的工作,而且是一项相对不讨好的工作;人们记得谁编写了内核代码,但那些审查它的人并没有什么持久的名声。因此,评审人员可能会变得脾气暴躁,尤其是当他们看到同样的错误一遍又一遍地发生时。如果您收到似乎愤怒、侮辱或完全冒犯的评论,请抑制以牙还牙的冲动。代码审查是关于代码的,而不是关于人,代码评审人员并不是在人身攻击您。

  • 同样,代码评审人员也不是试图以牺牲您自己的利益为代价来推销他们雇主的议程。内核开发人员通常希望在几年后继续在内核上工作,但他们知道他们的雇主可能会改变。他们几乎毫无例外地真正致力于创建他们所能创建的最佳内核;他们不是在试图为他们雇主的竞争对手制造不适。

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

所有这一切都归结为,当评审人员向您发送评论时,您需要关注他们提出的技术观察。不要让他们的表达方式或您自己的自尊心阻止这种情况发生。当您收到关于补丁的审查评论时,请花时间理解评审人员想要表达什么。如果可能,请修复评审人员要求您修复的内容。并回复评审人员:感谢他们,并描述您将如何回答他们的问题。

请注意,您不必同意评审人员提出的每一项更改建议。如果您认为评审人员误解了您的代码,请解释实际情况。如果您对建议的更改有技术异议,请描述它并证明您对问题的解决方案是正确的。如果您的解释有道理,评审人员会接受它们。但是,如果您的解释没有说服力,尤其是在其他人开始同意评审人员的观点时,请花一些时间重新考虑。很容易被您自己对某个问题的解决方案蒙蔽,以至于您没有意识到某些地方存在根本性的错误,或者,也许您甚至没有解决正确的问题。

Andrew Morton 建议,每个没有导致代码更改的审查评论都应该导致一个额外的代码注释;这可以帮助未来的评审人员避免第一次出现的问题。

一个致命的错误是忽略审查评论,希望它们会消失。它们不会消失。如果您在没有回应您上次收到的评论的情况下重新发布代码,您可能会发现您的补丁无处可去。

说到重新发布代码:请记住,评审人员不会记住您上次发布的代码的所有细节。因此,提醒评审人员之前提出的问题以及您如何处理这些问题总是一个好主意;补丁变更日志是此类信息的好地方。评审人员不应该搜索列表存档来熟悉上次说了什么;如果您帮助他们有一个良好的开端,他们在重新访问您的代码时会心情更好。

如果您已经尽力做好了所有事情,但事情仍然没有进展怎么办?大多数技术分歧都可以通过讨论来解决,但有时必须有人做出决定。如果您真的认为这个决定对您不利,您可以随时尝试向上级申诉。在撰写本文时,那个上级往往是 Andrew Morton。Andrew 在内核开发社区中享有很高的声望;他通常可以解除看似毫无希望的困境。但是,不应轻率地向 Andrew 申诉,而应在探索所有其他替代方案之后。当然,请记住,他可能也不会同意您的观点。

6.2. 接下来会发生什么

如果认为一个补丁添加到内核是一件好事,并且一旦大部分审查问题得到解决,下一步通常是进入子系统维护者的树。其运作方式因一个子系统而异;每个维护者都有自己做事的方式。特别是,可能存在多个树 - 一个可能专门用于计划在下一个合并窗口中使用的补丁,另一个用于长期工作。

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

包含到子系统树中可以为补丁带来更高的可见性。现在,其他使用该树的开发人员将默认获取该补丁。子系统树通常也会馈送到 linux-next,使其内容对整个开发社区可见。此时,您很有可能会从一组新的评审人员那里获得更多评论;这些评论需要像上一轮一样得到回答。

此时可能还会发生的事情,取决于您的补丁的性质,是与其他人的工作发生冲突。在最坏的情况下,严重的补丁冲突可能会导致一些工作被搁置,以便其余的补丁可以被处理成形并合并。其他时候,冲突解决将涉及与其他开发人员合作,并可能在树之间移动一些补丁,以确保一切顺利应用。这项工作可能很麻烦,但请为您的祝福而欢呼:在 linux-next 树出现之前,这些冲突通常只在合并窗口期间出现,并且必须在匆忙中解决。现在它们可以在合并窗口打开之前从容地解决。

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

首先,你的补丁的可见性再次提高。可能会有之前不了解该补丁的开发人员提出新一轮的评论。你可能会想忽略他们,因为你的代码是否会被合并已经没有疑问了。但是,请抵制这种诱惑;你仍然需要对有疑问或建议的开发人员做出回应。

更重要的是,纳入主线后,你的代码将进入更大范围的测试人员手中。即使你贡献的是尚未发布的硬件的驱动程序,你也会惊讶地发现有多少人会将你的代码构建到他们的内核中。当然,有测试人员的地方,就会有错误报告。

最糟糕的错误报告是回归。如果你的补丁导致了回归,你会发现很多双眼睛盯着你;回归需要尽快修复。如果你不愿意或无法修复回归(而且没有人为你做),你的补丁几乎肯定会在稳定期被删除。除了否定你为将补丁纳入主线所做的所有工作之外,由于未能修复回归而导致补丁被撤回,很可能会让你未来更难将工作合并进来。

在处理完所有回归之后,可能还有其他普通的错误需要处理。稳定期是你修复这些错误并确保你的代码在主线内核版本中首次亮相尽可能稳健的最佳机会。因此,请回复错误报告,并在可能的情况下修复问题。这就是稳定期的意义所在;一旦旧问题的处理完成,你就可以开始创建很酷的新补丁了。

别忘了,还有其他里程碑也可能产生错误报告:下一个主线稳定版本发布、主要发行商采用包含你的补丁的内核版本等等。继续回复这些报告是你对工作基本自豪感的体现。如果这还不足以激励你,那么还值得考虑的是,开发社区会记住那些在代码合并后就失去兴趣的开发人员。下次你发布补丁时,他们会假设你不会在事后维护它。

6.3. 其他可能发生的事情

有一天,你可能会打开你的邮件客户端,看到有人给你发送了针对你代码的补丁。毕竟,这就是你的代码公开的好处之一。如果你同意该补丁,你可以将其转发给子系统维护者(请确保包含正确的 From: 行以确保归属正确,并添加你自己的签名),或者发送一个 Acked-by: 回复,让原始发布者将其向上发送。

如果你不同意该补丁,请发送礼貌的回应,解释原因。如果可能,告诉作者需要进行哪些更改才能让你接受该补丁。对于代码的作者和维护者反对的补丁,存在一定的合并阻力,但这种阻力只是有限的。如果你被视为不必要地阻止了好的工作,那么这些补丁最终会绕过你,并被纳入主线。在 Linux 内核中,没有人对任何代码拥有绝对的否决权。除了 Linus 可能有。

在极少数情况下,你可能会看到完全不同的情况:另一位开发人员发布了针对你问题的不同解决方案。此时,很有可能这两个补丁中的一个不会被合并,并且“我的先到”不被认为是令人信服的技术论据。如果别人的补丁取代了你的补丁并进入了主线,那么只有一种方法可以回应:很高兴你的问题得到了解决,并继续你的工作。以这种方式被搁置自己的工作可能会令人受伤和沮丧,但社区会记住你的反应,很久之后他们就会忘记实际合并的是谁的补丁。