banner
Fel!xpace

Fel!xpace

Mapping of my blog on Web3.

Linuxカーネルへのパッチの提出:最も簡単な実践方法

最近、Linux カーネルにパッチを提出する機会がありました。SMTP の設定に苦労し、何度も上司に差し戻され、メンテナからの修正提案を経て、ついにサブツリーに受け入れられました...(更新:メインラインカーネルに入りました!)

自分のコード名を永遠に残すチャンス
サイドチャネル攻撃を回避するためにドライバが削除される可能性があります ✅

カーネルパッチとは#

周知の通り、Linux カーネルは世界で最も大きく、最も複雑で、最も重要なソフトウェアの一つです。その開発とメンテナンスは、世界中の何万人もの開発者の共同努力に依存しています。

Linux コミュニティにコードを貢献する最も基本的な方法は、メールを使用してカーネルメンテナにパッチを提出することです(コードホスティングプラットフォームでのプルリクエストを使用するという「現代的な」方法ではありません)

パッチとは、ソースツリーの 2 つの異なるバージョン間の変更の差分を含む小さなテキストドキュメントです。FROM kernel.org.

パッチファイルは、コードの変更内容とその変更の理由を特定の形式で説明します。カーネルメンテナによる承認後、このパッチはメインラインカーネルに統合されるか、特定のブランチに入れられます。

準備の設定#

この記事では、パッチの送信の基本的な設定を Ubuntu をベースに説明します。

  • git
  • git send-email (apt install git-emailgit-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に追加したtocmdcccmdを覚えていますか?

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

はい、最終的な送信コマンドはこれだけ簡単です!

自分自身に送信したり、他の経験豊富な人にレビューしてもらったりして、不適切なパッチがメンテナの怒りを引き起こさないようにすることはできますか?tocmdcccmdをコメントアウトし、送信時に--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 を一度に送信する場合については触れていません。詳細な情報はこちらを参照してください。
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。