自研操作系统:DIM-SUM设计与实现
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.5 向DIM-SUM操作系统提交补丁

想修改DIM-SUM的代码,并把它合入DIM-SUM的Git仓库吗?试着给DIM-SUM操作系统提交补丁吧。维护DIM-SUM操作系统的人使用的都是汉语,沟通起来完全没有问题,并且他们都不是外星人,你不用觉得他们凶巴巴的。

1.5.1 心态

Paul 在《深入理解并行编程》一书第 11.1.2 节中说过,验证和测试工作都需要良好的心态。应当以一种破坏性的,甚至带一点仇恨的心态来验证代码,有时也应当考虑到:不少人的生命都和代码的正确性息息相关。总之,心态对事情的成败有重要的影响。

你在向DIM-SUM提交补丁之前,请保持如下正确的心态:

1.撇开DIM-SUM不谈,我们的代码可能会影响不少人的生命,所以为任何项目编写代码,都一定要细心。

2.悲观地说,如果补丁做得不好,会影响自己的声誉,并且得不到足够的关注,最终会导致补丁没有被采纳。

3.乐观地说,DIM-SUM的维护者、开发者一般都比较友好。

4.更进一步乐观地说,你提交的高质量的补丁可能会为你带来良好的声誉、满意的工作。

如果你和我一样,有着近乎自大的自信,想要在操作系统方面做出一些成绩,请仔细阅读后面的章节。

1.5.2 准备工作

跃跃欲试想要提交补丁的读者,一定已经熟悉Linux开发环境了。在此,我假设你已经安装好Linux和Git。

1.配置Git用户名和邮箱

在配置用户名的时候,建议“名在前,姓在后”,并且第一个拼音字母大写。例如,我的用户名是Baoyou Xie。

在配置邮箱时,请使用有意义的邮箱名,而不要使用纯数字邮箱名。

以下是我的配置:

2.配置sendemail

你可以手动修改~/.gitconfig或者Git仓库下的.git/config文件,添加[sendemail]节。该配置用于指定发送补丁时用到的邮件服务器参数。

以下是我的配置,仅供参考:

配置完成后,请用如下命令向自己发送一个测试补丁:

3.下载源代码

如果仅仅是为了阅读本书,而不想向 DIM-SUM 提交补丁,那么使用 Git 直接从 DIM-SUM主分支拉取代码就行了。

从Git服务器下载源代码后,可以随时使用如下命令更新主分支代码:

但是,如果想参与到DIM-SUM的开发中,那么就需要从多个Git分支拉取代码。这是因为:主分支代码并不一定是最新的,如果基于这个代码制作补丁,很有可能不会顺利地合入维护分支。换句话说,如果你的代码分支没有与维护者的保持一致,那么维护者有时会将补丁发回给你,要求你重新制作。所以,一般情况下,你需要再用以下命令添加其他分支:

其中,tag-name是你为分支添加的别名,git-url是DIM-SUM分支的URL路径。

随时可以使用如下命令更新分支代码:

随着DIM-SUM的发展,不同的模块会由不同的维护者来维护。这些维护者会有自己的代码分支。你可以在 DIM-SUM 源代码目录的 MAINTAINERS 文件中找到相应文件的维护者,及其Git地址。

MAINTAINERS文件的格式与Linux中的MAINTAINERS文件的格式类似。例如,在Linux内核中,watchdog模块的信息如下所示:

代码仓库的链接地址也包含在其中。

4.阅读Documentation/SubmittingPatches文件

认真阅读这个文件,对正确制作补丁来说很重要。

5.使用如下命令检出源代码

这个命令表示将remote-branch远程分支作为本地mybranch分支,作为工作的基础。在这个分支上制作补丁,更容易被维护者合入。

使用如下命令切换为本地mybranch分支:

接下来,就可以修改本地代码,开始制作补丁了。

1.5.3 制作补丁

参与DIM-SUM的开发,可以从简单的事情入手。例如:

1.消除编译警告。

2.整理编码格式,例如注释里面的单词拼写错误、对齐不规范、代码格式不符合社区要求。

Linux社区里面的很多大牛就是从消除Linux内核警告开始参与Linux开发的。下面举一个简单的格式整理例子。

在kernel/sched/core.c的第192~193行,其代码看起来如下所示:

其中,第193行存在两个问题:

1.该行包含了84个字符,其中每个Tab键占用8个字符空间,代码超过了80个字符的限制。

2.没有与上一行对齐,排版太难看了。

删除该行前面几个Tab键,使其看起来如下所示:

修改完成后,在控制台输入如下命令将补丁提交到本地Git仓库:

然后使用如下命令生成补丁文件:

生成的补丁文件内容如下:

在core.c第193行,代码超过了80个字符,并且与上一行没有正确地对齐,因此应该删除其中多余的Tab键。本补丁删除这些多余的Tab键以满足代码格式规范。

* 在什么情况下,二者会相等?

难道制作一个补丁就这么简单?现在可以将它发送给维护者了吗?

答案当然是否定的。这个补丁有如下问题:

1.没有彻底解决模块中的同类问题。

2.补丁格式不正确。

首先应当将补丁退回。使用如下命令退回:

1.5.4 制作正确的补丁

实际上,在向维护者发送补丁之前,应对补丁进行检查,如下所示:

对于刚才生成的补丁,会得到如下错误:

在core.c第193行,代码超过了80个字符,并且与上一行没有正确地对齐,因此应该删除其中多余的Tab键。本补丁删除这些多余的Tab键以满足代码格式规范。

错误在于:补丁描述行太长了,应当折行,使每一行少于 75 个字符。再次使用如下命令提交补丁:

在提交补丁的时候,注意修改补丁描述,使其满足格式规范。反复制作补丁并使用checkpatch.pl检查其正确性,直到消除了所有警告为止。当然,极个别的警告是允许存在的。

使用checkpatch.pl仅仅能检查格式规范方面的错误。但是一个正确的补丁远不止格式正确这么简单,它还应该满足如下要求:

1.在一般情况下,同一个补丁只修改同一个模块的代码。

如果必须同时修改多个模块中的代码,那么应该让所有模块的维护者同意,并确定由其中某一个维护者合入补丁。这种情况仅仅是特例。

但是怎么确定某个文件属于哪一个模块?应当查看MAINTAINERS文件,其中有一个例子:

内核同步与互斥

可以看出,kernel/locking目录下的所有代码均属于“内核同步与互斥”模块。

2.同一个补丁仅仅解决一个独立的问题。

不要试图在同一个补丁中解决多个问题。例如,既消除一个编译警告,又整理一行代码。

小问题 1.9:但是,消除编译警告和整理代码都仅仅修改了一行代码,并且位于同一个文件之中,这样也不能将它们制作到同一个补丁中吗?如果不能,请告诉我正确的做法。

3.同一个补丁必须完整地解决一个问题。

换句话说,不能将一个问题分拆到多个补丁中去。正如前一个例子所述,需要在一个补丁中将整个模块的格式全部整理完毕。如果补丁太大,可以考虑按照每个文件或者每个功能模块对补丁进行拆分。

4.补丁不要太大,但这不是一个强制要求遵循的规则。

一般来说,一个补丁修改的代码行数不要超过200行。不过此规则比较灵活。如果一个单独的问题确实需要修改超过200行代码,那么就打破这个规则吧。

要制作一个正确的补丁,还有一个问题比较重要:补丁的标题和描述。

补丁第一行是标题,它首先应当是模块名称。

但是要怎么找到kernel/sched/core.c文件属于哪个模块呢?

可以试试下面这个命令,查看kernel/sched/core.c文件的历史补丁:

可以看到,kernel/sched/core.c文件所在的模块名称是“调度”。

其中,第一行是标题,在模块名称后面是补丁标题,应当简单、清楚地表明了补丁的内容。当然,标题可以超过80个字符。

随后的内容是补丁描述符,要清楚地描述:

1.为什么要制作这个补丁。

2.这个补丁是如何实现的。

当然了,模块的维护者可能对补丁描述有额外的要求,你可能也有需要特殊说明的地方,可以将它们都补充在描述中。这有点像写作文,既要求条理清楚,又没有成规。

1.5.5 发送补丁

在发送补丁前,需要用脚本再次检查一下补丁,确保其正确:

如果想要一次性生成并发送多个补丁,可以使用如下命令生成补丁:

在我的环境中,上述命令生成了两个补丁:

然后用checkpatch.pl检查这两个补丁:

一切无误,可以准备将补丁发送给维护者了。

但是应该将补丁发送给谁?这可以用get_maintainer.pl来查看:

接下来,可以用git send-email命令发送补丁:

需要注意分辨,哪些人应当作为邮件接收者,哪些人应当作为抄送者。在本例中,补丁是属于实验性质的,可以不抄送给邮件列表账户。

提醒:你应当将补丁先发送给自己,检查无误后再发送出去。如果你有朋友在Linux社区有较高的威望,有补丁走查的经验,或者深度参与了DIM-SUM的开发,那么也可以抄送给他,在必要的时候,也许他能给你一些帮助。这有助于将补丁顺利地合入DIM-SUM。

重要提醒:本章讲述的主要是实验性质的补丁,用于让你熟悉提交补丁的流程。真正重要的补丁可能需要经过反复修改后才能合入 DIM-SUM。并且,这需要你反复阅读本书后面章节中对DIM-SUM内核的代码分析。最重要的一点是,需要你熟练掌握DIM-SUM的代码。