Submitting My First Linux Kernel Patch
Linux 内核的 patch 是以纯文本的邮件形式进行提交和代码走查的,而且 patch 是先到内核子系统 maintainer 维护的 git tree, 再到 Linus Torvalds 的 main tree。本文主要是以一个 patch 提交的实例来记录一下整个过程中的一些具体操作要点,至于 kernel patch 提交的规范和操作细节内核文档 和各种博客文章有很多,这里不再赘述。
用到的平台,软件,工具
- Windows Subsystem for Linux, Ubuntu 20.04 LTS (Focal Fossa)
- 邮件客户端 mutt 1.13.2 (
apt install mutt
) - git 2.25.1
- kernel git tree (mainly DRM) https://gitlab.freedesktop.org/drm
过程
准备 patch
- 当你的 commit 已经在源码树上提交好后,只需使用
git format-patch
命令即可轻松生成一个内核 patch (假设 patch 里只包含一个 commit)
1 | git format-patch HEAD^ -o /tmp/ # 将生成的 patch 文件保存在 /tmp 目录 |
- 当你的 patch 被开发者 review 后,如果需要修改,修改后可通过增加
-v N
选项生成下一个版本的 patch
1 | git format-patch HEAD^ -v 2 -o /tmp/ |
检查 patch
1 | ./scripts/checkpatch.pl /path/to/patch |
checkpatch.pl
工具执行各种 codestyle, patch 格式, 社区提交补丁规范的检查,它和测试一样,都是提交补丁前不可缺少的步骤
提交 patch
个人觉得提交补丁比较简单的方式是使用 git send-email
, 因为内核补丁或补丁集都是以纯文本(plain text)电子邮件形式提交的, 所以提交前需要
- 配置好你的 SMTP (Simple Mail Transfer Protocol)邮件发送服务器
- 确定好收件人和抄送人(Carbon Copy)
- 收件人一般是 subsystem maintainer 或邮件列表,如 dri-devel@lists.freedesktop.org
- 抄送人一般使用脚本
./scripts/get_maintainer.pl /path/to/patch
来自动获取./scripts/get_maintainer.pl
不加任何选项时输出格式是这样子的(具体内容随补丁而定)1
2
3
4
5
6
7Maarten Lankhorst <maarten.lankhorst@linux.intel.com> (maintainer:DRM DRIVERS AND MISC GPU PATCHES)
Maxime Ripard <mripard@kernel.org> (maintainer:DRM DRIVERS AND MISC GPU PATCHES)
Thomas Zimmermann <tzimmermann@suse.de> (maintainer:DRM DRIVERS AND MISC GPU PATCHES)
David Airlie <airlied@gmail.com> (maintainer:DRM DRIVERS)
Simona Vetter <simona@ffwll.ch> (maintainer:DRM DRIVERS)
dri-devel@lists.freedesktop.org (open list:DRM DRIVERS)
linux-kernel@vger.kernel.org (open list)
使用 mutt
提交 Linux kernel patch 实际上就是用邮件客户端将生成好的 patch 文件发送给相关的 maintainers 和 maillists. git send-email
也可以做同样的事,这里使用的是 mutt. mutt 的基本命令行格式是
1 | mutt [-Enx] [-e cmd] [-F file] [-H file] [-i file] [-s subj] [-b addr] [-c addr] [-a file [...] --] addr|mailto_url [...] |
本例中只使用到了 -H file
选项,它将包含有邮件头和邮件主体的 patch 文件作为参数创建邮件草稿 (意思是该命令执行后还会让你再编辑邮件,包括收件人,邮件内容增删改等)。本例中 mutt 的唯一参数是后面的收件人列表,它是通过内核源码树里的一个脚本工具自动获取的。
1 | mutt -H /tmp/v2-0001-drm-vram-helper-fix-function-names-in-vram-helper.patch \ |
带有 Fixes:
tag 的patch 应该会被 backport 到以前必要 -stable tree.
使用 git send-email
1 | git send-email --to dri-devel@lists.freedesktop.org --cc-cmd "./scripts/get_maintainer.pl --nogit-fallback --norolestats" /tmp/0001-drm-doc-Fix-doc-in-drm_file.patch |
注意事项
git send-email
同样需要配置发送邮件服务器 stmp
-
将 user@stmp.gmail.com 的密码配置在 ~/.gitconfig 的 sendemail 段
1
2
3
4
5
6[sendemail]
smtpserver = smtp.gmail.com
smtpencryption = tls
smtpserverport = 587
smtpuser = onion0709@gmail.com
smtppass = <16 characters Google App Password> -
mutt 需要配置 IMAP/SMTP, 即邮件收发协议配置 (这是整个过程中最费劲的)
mutt 的配置文件默认路径是$HOME/.mutt/muttrc
-
git 需要配置完整的
user.name
,user.email
. -
git commit
时需要加-s
(--signoff
) 来自动增加 Signed-off-by 标签 (如果你 Signed-off-by 标签的邮件地址和发送 patch 的邮箱地址不同的话,还需要在邮件主体的第一行手动添加From: Zhang San <xxx@yourmail.com>
, xxx@yourmail.com 是你的 Signed-off-by 邮件地址) -
如果 patch 邮件发出后2,3周,甚至一个月都没有收到任何回应,在确认收件地址没问题的情况下,可以再次
git send-email
原来的patch, 同时在邮件主题手动加上 RESEND 标识1
[PATCH RESEND] sub/sys: Condensed patch summary
-
git send-email -v 2 --in-reply-to="<v1-message-id> ..."
避免因提供补丁的下一个版本而中断线程。 -
对于补丁集 (Patch Series), 一般 Changelog 会写在补丁集的 cover letter 里。对于单个补丁,如果不想让 Changelog 出现在 commit message 里,但又想给 Maintainer 提供补丁迭代的信息,可以在
Signed-off-by
后面手动加上---
, 然后开始写 Changelog(如下), 这样 Changelog 就不会出现在最终的 Commit message 里, 修改的时机可以在git commit -s
写提交日志时,也可以在git send-email --to ...
发送邮件时选择[e]dit
1
2
3
4
5
6
7
8
9
10...
Signed-off-by: Zhang San <zhang.san@gmail.com>
---
v3:
- blablabla
- asdfasdfasdf
v2:
...