最近、Linux カーネルにパッチを提出する機会がありました。SMTP の設定に苦労し、何度も上司に差し戻され、メンテナからの修正提案を経て、ついにサブツリーに受け入れられました...(更新:メインラインカーネルに入りました!)
自分のコード名を永遠に残すチャンス❌
サイドチャネル攻撃を回避するためにドライバが削除される可能性があります ✅
カーネルパッチとは#
周知の通り、Linux カーネルは世界で最も大きく、最も複雑で、最も重要なソフトウェアの一つです。その開発とメンテナンスは、世界中の何万人もの開発者の共同努力に依存しています。
Linux コミュニティにコードを貢献する最も基本的な方法は、メールを使用してカーネルメンテナにパッチを提出することです(コードホスティングプラットフォームでのプルリクエストを使用するという「現代的な」方法ではありません)
パッチとは、ソースツリーの 2 つの異なるバージョン間の変更の差分を含む小さなテキストドキュメントです。FROM kernel.org.
パッチファイルは、コードの変更内容とその変更の理由を特定の形式で説明します。カーネルメンテナによる承認後、このパッチはメインラインカーネルに統合されるか、特定のブランチに入れられます。
準備の設定#
この記事では、パッチの送信の基本的な設定を Ubuntu をベースに説明します。
- git
- git send-email (
apt install git-email
、git-core
も必要です) - diff
- perl
git はバージョン管理とコードのコミットに使用され、git send-email はパッチを添付したメールを送信するために使用され、diff はファイルの差分を比較するために使用され、perl はパッチの送信に必要なスクリプトを実行するために使用されます。
メール送信のために smtp を設定するには、.gitconfig
ファイルにメール関連の設定を追加する必要があります。以下は、Gmail を送信メールボックスとして使用する例です:
[user]
name = YOURNAME
# ここには送信メールボックスのメールアドレスを入力してください
email = [email protected]
[sendemail]
from = YOURNAME <[email protected]>
smtpencryption = ssl
# 暗号化方式としてtlsを使用することもできますが、ポートは578に変更する必要があります
smtpserver = smtp.gmail.com
smtpuser = YOURNAME
smtpserverport = 465
smtpAuth = LOGIN # 必須ではありません
chainreplyto = false # 必須ではありません
# tocmdとcccmdはカーネルメーリングリストを取得するための簡略化されたコマンドです。テスト用に自分自身に送信する場合は、コメントアウトするだけで十分です
tocmd = "`pwd`/scripts/get_maintainer.pl --nogit --norolestats --nol"
cccmd = "`pwd`/scripts/get_maintainer.pl --nogit --norolestats --nom"
変更の実施#
カーネルパッチを提出するためには、まずカーネルコードのコピーを取得する必要があります!kernel.orgなどからカーネルソースリポジトリを取得し、お好きな場所にgit clone
して、変更作業を行うためのブランチを作成します。
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
git branch -b fix/blablabla
注意:衝突を避けるために、ローカルコードをメインラインと同期させる必要があります。変更を開始する前にgit pull
することが良い習慣です。
変更の記述#
commit
する際に、行った変更の簡単な説明を記述し、commit
のタイトルの形式は他のパッチを参考にしてください。一般的にはA: B: blablabla
の形式です。git commit -s
を使用してSigned-off-by: YOUNAME <[email protected]>
を自動的に追加するか、パッチファイルにこの行を追加する必要があります。
git format-patch -1
git format-patch
は、現在のディレクトリに、標準的なメール形式(ただし、必ずしも標準的なパッチ形式ではない)の.patch
ファイルを生成します。ここでの-1
は、このパッチファイルには 1 つのcommit
のみを含めることを意味します。
Subject:
とSigned-off-by
の行の間に、このパッチについての詳細な説明が必要です。私が提出したパッチでは、問題の発見方法(Smatch からのエラーメッセージ)、問題の原因(ioremap
によるメモリのマッピング解除が行われていない)と修正方法(デバイスの削除時にメモリマッピングを解除するためにdevm_ioremap
に変更)を説明しています。
テストを忘れずに!カーネル全体をビルドするか、変更したモジュールのみをビルドすることができます(例:ドライバーの場合)
送信と待機#
フォーマットのチェック:カーネルソースコードに組み込まれているスクリプトを使用します。
$PATH_TO_KERNEL/scripts/checkpatch.pl YOUR_PATCH.patch
よくあるエラーは次のとおりです。
WARNING: Possible unwrapped commit description (prefer a maximum 75 chars per line)
これは、Linux カーネルのCOMMIT_MSG
とパッチが 80 文字のターミナルで正常に表示されるようにするため、各行は 80 文字を超えてはいけないためです(信じるか信じないか、カーネルには古い規則がたくさんあります)。エラーメッセージに従って修正してください。
.gitconfig
に追加したtocmd
とcccmd
を覚えていますか?
tocmd = "`pwd`/scripts/get_maintainer.pl --nogit --norolestats --nol"
cccmd = "`pwd`/scripts/get_maintainer.pl --nogit --norolestats --nom"
tocmd
行は受信者、つまり変更部分のカーネルメンテナのメールを自動的に取得します。同様に、cccmd
行は CC リストのメールを取得します。これにより、メールを送信する際の「CLI の負担」が軽減されます。
git send-email YOUR_PATCH.patch
はい、最終的な送信コマンドはこれだけ簡単です!
自分自身に送信したり、他の経験豊富な人にレビューしてもらったりして、不適切なパッチがメンテナの怒りを引き起こさないようにすることはできますか?tocmd
とcccmd
をコメントアウトし、送信時に--to
と--cc
オプションを追加して送信先 / CC を指定することができます。
git send-email --to [email protected] --cc [email protected] YOUR_PATCH.patch
送信後、必要なのは... 待つことだけです。まあ、カーネルメンテナたちは非常に忙しいですが、すべてのメールをすぐに確認して返信することはできませんよね?
数週間後にパッチメールに誰も反応しない場合(これは珍しいことではありません)、PING または RESEND を送信してメンテナにリマインドすることができます。
git fromat-patch -1 --subject-prefix='PING'
# または
git format-patch -1 --subject-prefix='RESEND'
変更、v2、v3、v4...#
長い待ち時間の後、あなたのメールボックスに「Re: PATCH」という件名のメールが届きました - おそらく単純な「Applied, thanks」という一言、または不満や怒りに満ちたメッセージ(もちろん、ほとんどの場合は礼儀正しく友好的なもの)が待っているかもしれません。
新しい PATCH、つまりPATCH v2
は、最初と同じく、元の HEAD ブランチをベースに変更を行う必要があります。自分のコミットを基に新しいコードを提出するのではありません。
意見に従って修正した後、PATCH v2
を送信することができます。Reviewed by
の後に Changelog 情報を追加し、どのような変更を行ったかを記述してください。例:
v2 -> v3: Directly deleted 'base' and its related code based on master.
v1 -> v2: Directly deleted 'base' and its related code based on PATCH v1.
新しいメールの件名も変更する必要があります。
git format-patch -1 --subject-prefix='PATCH v2'
新しいパッチを送信するプロセスは最初の場合と同じですが、送信するファイルを間違えないように注意してください。
修正パッチのプロセスは何度も繰り返す必要があるかもしれませんし、v3、v4 を送信する必要があるかもしれませんが、あきらめないでください!
受け入れ後#
メンテナに受け入れられたパッチは、まずそのモジュールのサブツリーにマージされます(git.kernel.orgで見つけることができます)、そして他のパッチと一緒に Linus に送信され、最終的にメインラインカーネルに統合されます。おめでとうございます!
その他の注意事項#
- パッチを送信するだけでなく、メールに返信するだけでも、
git send-email
を使用することができます。具体的なコマンドは、返信するメールの後にhttps://lore.kernel.org/lkml/で見つけることができます。 - この記事では、複数の PATCH を一度に送信する場合については触れていません。詳細な情報はこちらを参照してください。