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的代码。