treewide: remove redundant IS_ERR() before error code check
[linux/fpc-iii.git] / Documentation / translations / zh_CN / process / 2.Process.rst
blobceb733bb0294e3ce54d1f3d16315ce8ce14af58f
1 .. include:: ../disclaimer-zh_CN.rst
3 :Original: :ref:`Documentation/process/2.Process.rst <development_process>`
4 :Translator: Alex Shi <alex.shi@linux.alibaba.com>
6 .. _cn_development_process:
8 开发流程如何工作
9 ================
11 90年代早期的Linux内核开发是一件相当松散的事情,涉及的用户和开发人员相对较
12 少。由于拥有数以百万计的用户群,并且在一年的时间里有大约2000名开发人员参与
13 进来,内核因此必须发展许多流程来保持开发的顺利进行。要成为流程的有效组成
14 部分,需要对流程的工作方式有一个扎实的理解。
16 总览
17 ----
19 内核开发人员使用一个松散的基于时间的发布过程,每两到三个月发布一次新的主要
20 内核版本。最近的发布历史记录如下:
22         ======  =================
23         4.11    四月 30, 2017
24         4.12    七月 2, 2017
25         4.13    九月 3, 2017
26         4.14    十一月 12, 2017
27         4.15    一月 28, 2018
28         4.16    四月 1, 2018
29         ======  =================
31 每4.x版本都是一个主要的内核版本,具有新特性、内部API更改等等。一个典型的4.x
32 版本包含大约13000个变更集,变更了几十万行代码。因此,4.x是Linux内核开发的前
33 沿;内核使用滚动开发模型,不断集成重大变化。
35 对于每个版本的补丁合并,遵循一个相对简单的规则。在每个开发周期的开始,“合并
36 窗口”被打开。当时,被认为足够稳定(并且被开发社区接受)的代码被合并到主线内
37 核中。在这段时间内,新开发周期的大部分变更(以及所有主要变更)将以接近每天
38 1000次变更(“补丁”或“变更集”)的速度合并。
40 (顺便说一句,值得注意的是,合并窗口期间集成的更改并不是凭空产生的;它们是
41 提前收集、测试和分级的。稍后将详细描述该过程的工作方式)。
43 合并窗口持续大约两周。在这段时间结束时,LinusTorvalds将声明窗口已关闭,并
44 释放第一个“rc”内核。例如,对于目标为4.14的内核,在合并窗口结束时发生的释放
45 将被称为4.14-rc1。RC1版本是一个信号,表示合并新特性的时间已经过去,稳定下一
46 个内核的时间已经开始。
48 在接下来的6到10周内,只有修复问题的补丁才应该提交给主线。有时会允许更大的
49 更改,但这种情况很少发生;试图在合并窗口外合并新功能的开发人员往往会受到不
50 友好的接待。一般来说,如果您错过了给定特性的合并窗口,最好的做法是等待下一
51 个开发周期。(对于以前不支持的硬件,偶尔会对驱动程序进行例外;如果它们不
52 改变已有代码,则不会导致回归,并且应该可以随时安全地添加)。
54 随着修复程序进入主线,补丁速度将随着时间的推移而变慢。Linus大约每周发布一次
55 新的-rc内核;一个正常的系列将在-rc6和-rc9之间,内核被认为足够稳定并最终发布。
56 然后,整个过程又重新开始了。
58 例如,这里是4.16的开发周期进行情况(2018年的所有日期):
60         ==============  ==============================
61         一月 28           4.15 稳定版发布
62         二月 11           4.16-rc1, 合并窗口关闭
63         二月 18           4.16-rc2
64         二月 25           4.16-rc3
65         三月 4            4.16-rc4
66         三月 11           4.16-rc5
67         三月 18           4.16-rc6
68         三月 25           4.16-rc7
69         四月 1            4.16 稳定版发布
70         ==============  ==============================
72 开发人员如何决定何时结束开发周期并创建稳定的版本?使用的最重要的指标是以前
73 版本的回归列表。不欢迎出现任何错误,但是那些破坏了以前能工作的系统的错误被
74 认为是特别严重的。因此,导致回归的补丁是不受欢迎的,很可能在稳定期内删除。
76 开发人员的目标是在稳定发布之前修复所有已知的回归。在现实世界中,这种完美是
77 很难实现的;在这种规模的项目中,变量太多了。有一点,延迟最终版本只会使问题
78 变得更糟;等待下一个合并窗口的一堆更改将变大,从而在下次创建更多的回归错误。
79 因此,大多数4.x内核都有一些已知的回归错误,不过,希望没有一个是严重的。
81 一旦一个稳定的版本发布,它正在进行的维护工作就被移交给“稳定团队”,目前由
82 Greg Kroah-Hartman组成。稳定团队将使用4.x.y编号方案不定期的发布稳定版本的更
83 新。要加入更新版本,补丁程序必须(1)修复一个重要的bug,(2)已经合并到
84 下一个开发主线中。内核通常会在超过其初始版本的一个以上的开发周期内接收稳定
85 的更新。例如,4.13内核的历史如下
87         ==============  ===============================
88         九月 3            4.13 稳定版发布
89         九月 13           4.13.1
90         九月 20           4.13.2
91         九月 27           4.13.3
92         十月 5            4.13.4
93         十月 12         4.13.5
94         ...             ...
95         十一月 24       4.13.16
96         ==============  ===============================
98 4.13.16是4.13版本的最终稳定更新。
100 有些内核被指定为“长期”内核;它们将得到更长时间的支持。在本文中,当前的长期
101 内核及其维护者是:
103         ======  ======================  ==============================
104         3.16    Ben Hutchings           (长期稳定内核)
105         4.1     Sasha Levin
106         4.4     Greg Kroah-Hartman      (长期稳定内核)
107         4.9     Greg Kroah-Hartman
108         4.14    Greg Kroah-Hartman
109         ======  ======================  ==============================
111 为长期支持选择内核纯粹是维护人员有必要和时间来维护该版本的问题。目前还没有
112 为即将发布的任何特定版本提供长期支持的已知计划。
114 补丁的生命周期
115 --------------
117 补丁不会直接从开发人员的键盘进入主线内核。相反,有一个稍微复杂(如果有些非
118 正式)的过程,旨在确保对每个补丁进行质量审查,并确保每个补丁实现了一个在主线
119 中需要的更改。对于小的修复,这个过程可能会很快发生,或者,在大的和有争议的
120 变更的情况下,会持续数年。许多开发人员的挫折来自于对这个过程缺乏理解或者
121 试图绕过它。
123 为了减少这种挫折感,本文将描述补丁如何进入内核。下面是一个介绍,它以某种
124 理想化的方式描述了这个过程。更详细的过程将在后面的章节中介绍。
126 补丁程序经历的阶段通常是:
128 - 设计。这就是补丁的真正需求——以及满足这些需求的方式——的所在。设计工作通常
129   是在不涉及社区的情况下完成的,但是如果可能的话,最好是在公开的情况下完成
130   这项工作;这样可以节省很多稍后再重新设计的时间。
132 - 早期评审。补丁被发布到相关的邮件列表中,列表中的开发人员会回复他们可能有
133   的任何评论。如果一切顺利的话,这个过程应该会发现补丁的任何主要问题。
135 - 更广泛的评审。当补丁接近准备好纳入主线时,它应该被相关的子系统维护人员
136   接受——尽管这种接受并不能保证补丁会一直延伸到主线。补丁将出现在维护人员的
137   子系统树中,并进入 -next 树(如下所述)。当流程工作时,此步骤将导致对补丁
138   进行更广泛的审查,并发现由于将此补丁与其他人所做的工作集成而导致的任何
139   问题。
141 - 请注意,大多数维护人员也有日常工作,因此合并补丁可能不是他们的最高优先级。
142   如果您的补丁程序得到了关于所需更改的反馈,那么您应该进行这些更改,或者为
143   不应该进行这些更改的原因辩护。如果您的补丁没有评审意见,但没有被其相应的
144   子系统或驱动程序维护者接受,那么您应该坚持不懈地将补丁更新到当前内核,使
145   其干净地应用,并不断地将其发送以供审查和合并。
147 - 合并到主线。最终,一个成功的补丁将被合并到由LinusTorvalds管理的主线存储库
148   中。此时可能会出现更多的评论和/或问题;开发人员应对这些问题并解决出现的
149   任何问题很重要。
151 - 稳定版发布。可能受补丁影响的用户数量现在很大,因此可能再次出现新的问题。
153 - 长期维护。虽然开发人员在合并代码后可能会忘记代码,但这种行为往往会给开发
154   社区留下不良印象。合并代码消除了一些维护负担,因为其他代码将修复由API
155   更改引起的问题。但是,如果代码要长期保持有用,原始开发人员应该继续为
156   代码负责。
158 内核开发人员(或他们的雇主)犯的最大错误之一是试图将流程简化为一个
159 “合并到主线”步骤。这种方法总是会让所有相关人员感到沮丧。
161 补丁如何进入内核
162 ----------------
164 只有一个人可以将补丁合并到主线内核存储库中:LinusTorvalds。但是,在进入
165 2.6.38内核的9500多个补丁中,只有112个(大约1.3%)是由Linus自己直接选择的。
166 内核项目已经发展到一个规模,没有一个开发人员可以在没有支持的情况下检查和
167 选择每个补丁。内核开发人员处理这种增长的方式是通过使用围绕信任链构建的
168 助理系统。
170 内核代码库在逻辑上被分解为一组子系统:网络、特定的体系结构支持、内存管理、
171 视频设备等。大多数子系统都有一个指定的维护人员,开发人员对该子系统中的代码
172 负有全部责任。这些子系统维护者(松散地)是他们所管理的内核部分的守护者;
173 他们(通常)会接受一个补丁以包含到主线内核中。
175 子系统维护人员每个人都使用git源代码管理工具管理自己版本的内核源代码树。Git
176 等工具(以及Quilt或Mercurial等相关工具)允许维护人员跟踪补丁列表,包括作者
177 信息和其他元数据。在任何给定的时间,维护人员都可以确定他或她的存储库中的哪
178 些补丁在主线中找不到。
180 当合并窗口打开时,顶级维护人员将要求Linus从其存储库中“拉出”他们为合并选择
181 的补丁。如果Linus同意,补丁流将流向他的存储库,成为主线内核的一部分。
182 Linus对拉操作中接收到的特定补丁的关注程度各不相同。很明显,有时他看起来很
183 关注。但是,作为一般规则,Linus相信子系统维护人员不会向上游发送坏补丁。
185 子系统维护人员反过来也可以从其他维护人员那里获取补丁。例如,网络树是由首先
186 在专用于网络设备驱动程序、无线网络等的树中积累的补丁构建的。此存储链可以
187 任意长,但很少超过两个或三个链接。由于链中的每个维护者都信任那些管理较低
188 级别树的维护者,所以这个过程称为“信任链”。
190 显然,在这样的系统中,获取内核补丁取决于找到正确的维护者。直接向Linus发送
191 补丁通常不是正确的方法。
193 Next 树
194 -------
196 子系统树链引导补丁流到内核,但它也提出了一个有趣的问题:如果有人想查看为
197 下一个合并窗口准备的所有补丁怎么办?开发人员将感兴趣的是,还有什么其他的
198 更改有待解决,以查看是否存在需要担心的冲突;例如,更改核心内核函数原型的
199 修补程序将与使用该函数旧形式的任何其他修补程序冲突。审查人员和测试人员希望
200 在所有这些变更到达主线内核之前,能够访问它们的集成形式中的变更。您可以从所有
201 有趣的子系统树中提取更改,但这将是一项大型且容易出错的工作。
203 答案以-next树的形式出现,在这里子系统树被收集以供测试和审查。Andrew Morton
204 维护的这些旧树被称为“-mm”(用于内存管理,这就是它的启动名字)。-mm 树集成了
205 一长串子系统树中的补丁;它还包含一些旨在帮助调试的补丁。
207 除此之外,-mm 还包含大量由Andrew直接选择的补丁。这些补丁可能已经发布在邮件
208 列表上,或者它们可能应用于内核中没有指定子系统树的部分。结果,-mm 作为一种
209 最后手段的子系统树运行;如果没有其他明显的路径可以让补丁进入主线,那么它很
210 可能以-mm 结束。累积在-mm 中的各种补丁最终将被转发到适当的子系统树,或者直接
211 发送到Linus。在典型的开发周期中,大约5-10%的补丁通过-mm 进入主线。
213 当前-mm 补丁可在“mmotm”(-mm of the moment)目录中找到,地址:
215         http://www.ozlabs.org/~akpm/mmotm/
217 然而,使用mmotm树可能是一种令人沮丧的体验;它甚至可能无法编译。
219 下一个周期补丁合并的主要树是linux-next,由Stephen Rothwell 维护。根据设计
220 linux-next 是下一个合并窗口关闭后主线的快照。linux-next树在Linux-kernel 和
221 Linux-next 邮件列表中发布,可从以下位置下载:
223         http://www.kernel.org/pub/linux/kernel/next/
225 Linux-next 已经成为内核开发过程中不可或缺的一部分;在一个给定的合并窗口中合并
226 的所有补丁都应该在合并窗口打开之前的一段时间内找到进入Linux-next 的方法。
228 Staging 树
229 ----------
231 内核源代码树包含drivers/staging/directory,其中有许多驱动程序或文件系统的
232 子目录正在被添加到内核树中。它们然需要更多的工作的时候可以保留在
233 driver/staging目录中;一旦完成,就可以将它们移到内核中。这是一种跟踪不符合
234 Linux内核编码或质量标准的驱动程序的方法,但人们可能希望使用它们并跟踪开发。
236 Greg Kroah Hartman 目前负责维护staging 树。仍需要工作的驱动程序将发送给他,
237 每个驱动程序在drivers/staging/中都有自己的子目录。除了驱动程序源文件之外,
238 目录中还应该有一个TODO文件。todo文件列出了驱动程序需要接受的挂起的工作,
239 以及驱动程序的任何补丁都应该抄送的人员列表。当前的规则要求,staging的驱动
240 程序必须至少正确编译。
242 Staging 是一种相对容易的方法,可以让新的驱动程序进入主线,幸运的是,他们会
243 引起其他开发人员的注意,并迅速改进。然而,进入staging并不是故事的结尾;
244 staging中没有看到常规进展的代码最终将被删除。经销商也倾向于相对不愿意使用
245 staging驱动程序。因此,在成为一名合适的主线驱动的路上,staging 充其量只是
246 一个停留。
248 工具
249 ----
251 从上面的文本可以看出,内核开发过程在很大程度上依赖于在不同方向上聚集补丁的
252 能力。如果没有适当强大的工具,整个系统将无法在任何地方正常工作。关于如何使用
253 这些工具的教程远远超出了本文档的范围,但是还是有一些指南的空间。
255 到目前为止,内核社区使用的主要源代码管理系统是git。Git是在自由软件社区中开发
256 的许多分布式版本控制系统之一。它非常适合内核开发,因为它在处理大型存储库和
257 大量补丁时性能非常好。它还有一个难以学习和使用的名声,尽管随着时间的推移它
258 变得更好了。对于内核开发人员来说,对Git的某种熟悉几乎是一种要求;即使他们不
259 将它用于自己的工作,他们也需要Git来跟上其他开发人员(以及主线)正在做的事情。
261 现在几乎所有的Linux发行版都打包了Git。主页位于:
263         http://git-scm.com/
265 那个页面有指向文档和教程的指针。
267 在不使用git的内核开发人员中,最流行的选择几乎肯定是mercurial:
269         http://www.seleric.com/mercurial/
271 Mercurial与Git共享许多特性,但它提供了一个界面,许多人觉得它更易于使用。
273 另一个值得了解的工具是quilt:
275         http://savannah.nongnu.org/projects/quilt
277 Quilt 是一个补丁管理系统,而不是源代码管理系统。它不会随着时间的推移跟踪历史;
278 相反,它面向根据不断发展的代码库跟踪一组特定的更改。一些主要的子系统维护人员
279 使用Quilt来管理打算向上游移动的补丁。对于某些树的管理(例如-mm),quilt 是
280 最好的工具。
282 邮件列表
283 --------
285 大量的Linux内核开发工作是通过邮件列表完成的。如果不在某个地方加入至少一个列表,
286 就很难成为社区中一个功能完备的成员。但是,Linux邮件列表对开发人员来说也是一个
287 潜在的危险,他们可能会被一堆电子邮件淹没,违反Linux列表上使用的约定,或者
288 两者兼而有之。
290 大多数内核邮件列表都在vger.kernel.org上运行;主列表位于:
292         http://vger.kernel.org/vger-lists.html
294 不过,也有一些列表托管在别处;其中一些列表位于lists.redhat.com。
296 当然,内核开发的核心邮件列表是linux-kernel。这个名单是一个令人生畏的地方;
297 每天的信息量可以达到500条,噪音很高,谈话技术性很强,参与者并不总是表现出
298 高度的礼貌。但是,没有其他地方可以让内核开发社区作为一个整体聚集在一起;
299 避免使用此列表的开发人员将错过重要信息。
301 有一些提示可以帮助在linux-kernel生存:
303 - 将邮件转移到单独的文件夹,而不是主邮箱。我们必须能够持续地忽略洪流。
305 - 不要试图跟踪每一次谈话-其他人都不会。重要的是要对感兴趣的主题(尽管请
306   注意,长时间的对话可以在不更改电子邮件主题行的情况下偏离原始主题)和参与
307   的人进行筛选。
309 - 不要挑事。如果有人试图激起愤怒的反应,忽略他们。
311 - 当响应Linux内核电子邮件(或其他列表上的电子邮件)时,请为所有相关人员保留
312   cc:header。如果没有强有力的理由(如明确的请求),则不应删除收件人。一定要
313   确保你要回复的人在cc:list中。这个惯例也使你不必在回复邮件时明确要求被抄送。
315 - 在提出问题之前,搜索列表档案(和整个网络)。有些开发人员可能会对那些显然
316   没有完成家庭作业的人感到不耐烦。
318 - 避免贴顶帖(把你的答案放在你要回复的引文上面的做法)。这会让你的回答更难
319   理解,印象也很差。
321 - 询问正确的邮件列表。linux-kernel 可能是通用的讨论点,但它不是从所有子系统
322   中寻找开发人员的最佳场所。
324 最后一点——找到正确的邮件列表——是开发人员出错的常见地方。在Linux内核上提出与
325 网络相关的问题的人几乎肯定会收到一个礼貌的建议,转而在netdev列表上提出,
326 因为这是大多数网络开发人员经常出现的列表。还有其他列表可用于scsi、
327 video4linux、ide、filesystem等子系统。查找邮件列表的最佳位置是与内核源代码
328 一起打包的MAINTAINERS文件。
330 开始内核开发
331 ------------
333 关于如何开始内核开发过程的问题很常见——来自个人和公司。同样常见的是错误,这
334 使得关系的开始比必须的更困难。
336 公司通常希望聘请知名的开发人员来启动开发团队。实际上,这是一种有效的技术。
337 但它也往往是昂贵的,而且没有增长经验丰富的内核开发人员储备。考虑到时间的
338 投入,可以让内部开发人员加快Linux内核的开发速度。花这个时间可以让雇主拥有
339 一批了解内核和公司的开发人员,他们也可以帮助培训其他人。从中期来看,这往往
340 是更有利可图的方法。
342 可以理解的是,单个开发人员往往对起步感到茫然。从一个大型项目开始可能会很
343 吓人;人们往往想先用一些较小的东西来测试水域。这是一些开发人员开始创建修补
344 拼写错误或轻微编码风格问题的补丁的地方。不幸的是,这样的补丁会产生一定程度
345 的噪音,这会分散整个开发社区的注意力,因此,越来越多的人看不起它们。希望向
346 社区介绍自己的新开发人员将无法通过这些方式获得他们想要的那种接待。
348 Andrew Morton 为有抱负的内核开发人员提供了这个建议
352         所有内核初学者的No.1项目肯定是“确保内核在所有的机器上,你可以触摸
353         到的,始终运行良好" 通常这样做的方法是与其他人一起解决问题(这
354         可能需要坚持!)但这很好——这是内核开发的一部分
356 (http://lwn.net/articles/283982/)
358 在没有明显问题需要解决的情况下,建议开发人员查看当前的回归和开放式错误列表.
359 解决需要修复的问题没有任何缺点;通过解决这些问题,开发人员将获得处理过程的
360 经验,同时与开发社区的其他人建立尊重。