--- tags: Linux Kernel --- # 提交第一份 Patch 到 Linux Kernel contributed by < [steven1lung](https://github.com/steven1lung) > ## 我自己的心得 在看老師的書 Demystifying the Linux CPU Scheduler 的時候,突然好奇說每一個任務的 loading 是如何運算的,畢竟排程器上的任務如此多,計算出 load 然後依據每個 CPU 的狀態去做 task migration 應該是很重要的課題。所以我就跑去 [pelt.c ](https://elixir.bootlin.com/linux/latest/source/kernel/sched/pelt.c) 看了一下實際的運算是如何做到的。 > pelt 全名是 Per Entity Load Tracking 在看程式碼的時候,發現有個地方的中括號打反了變成 `[1002..1024[`,我就想說試試看發人生第一個 patch。 結果自己在摸索如何發 patch 花了好多時間...,轉眼間就早上了。所以就記錄了一下自己發 patch 的過程來紀念逝去的時間。雖然這個 patch 最後是我誤會中括號的用法,所以並沒有被採納,但跟這些厲害的人交流讓人有點興奮>< > 結果發現反過來的中括號是法文的用法,是我自己搞錯 xD 我發的 patch 在[這裡](https://lore.kernel.org/lkml/3193fcc9-c672-19d9-a2e2-ad67809dd20b@infradead.org/T/)。 ## 前言 Linux Kernel 的開發跟維護方法是透過信件來溝通跟 review,Linux Kernel 有一個龐大的 mail server,每天收到近千個信件提交 patches,格式不正確或是表達不好的 patch 很常會被忽略,連回覆都不會有,所以要如何寫好一個好的 patch 充滿學問。 > “Only wimps use tape backup. REAL men just upload their important stuff on ftp and let the rest of the world mirror it.” --Linus Torvalds ## 準備提交 Patch 會使用到的 Email Client * git send-email * mutt git 其實就有提供一個命令:`git send-email` 來做到發出信件的功能,或是也有很多人會使用 `mutt` 來幫忙發 plain text mail。我自己是 send patches 時會使用 `git send-email`,如果只是回覆 comment 之類就會用 mutt。 > 這邊要小心如果回覆 patch 的 comment 的時候使用 gmail 或是手機內建的信箱,要記得信件不要使用到 html,會被 lkml 認為是 spam 或病毒,就會被退回。 ### git send-email 使用之前還需要到 `~/.gitconfig` 裡先設定一些 smtp 的資料: ``` $ vi ~/.gitconfig ``` 然後在最後面加上: ``` [sendemail] smtpencryption=tls smtpserver=smtp.gmail.com smtpuser=你的信箱@xxxx.com smtpserverport=587 smtpPass=你的APP密碼 ``` > APP 密碼的設定方式在下面有說明。 ### mutt mutt 是一個很多開發者都會使用到 mail client,Greg Kroah-Hartman 也是使用這個!他也有在網路上分享自己的 workflow,詳情可以看[這裡](http://kroah.com/log/blog/2019/08/14/patch-workflow-with-mutt-2019/)。 mutt 並不是內建的,所以事先需要安裝: ``` $ sudo apt install mutt # Debian $ sudo dnf install mutt # Fedora $ brew install mutt # Macos ``` 接著一樣要去設定一些 smtp 的參數: ``` $ vi ~/.muttrc ``` 把以下的資料填好並且儲存: ``` set ssl_starttls=yes set ssl_force_tls=yes set imap_user = "你的信箱@XXXX.com" set imap_pass = "你的APP密碼" set from="你的信箱@XXXX.com" set realname="FIRST_NAME LAST_NAME" set folder = "imaps://imap.gmail.com/" set spoolfile = "imaps://imap.gmail.com/INBOX" set postponed="imaps://imap.gmail.com/[Gmail]/Drafts" set header_cache = "~/.mutt/cache/headers" set message_cachedir = "~/.mutt/cache/bodies" set certificate_file = "~/.mutt/certificates" set smtp_url = "smtps://你的信箱@XXX.com:你的APP密碼@smtp.gmail.com:465/" set record="~/mail/sent" set move = no set imap_keepalive = 900 ``` ### App 密碼設定 因為我信箱是使用 gmail,這邊就放我是如何設定 gmail 的。其中 `你的APP密碼` 需要到 gmail 裡面設定一個給應用程式的密碼,步驟如下: > https://support.google.com/mail/answer/185833?hl=en 1. 開啟 google 的 2FA 認證 > 到 [這裡](https://myaccount.google.com/security?rapt=AEjHL4Ma9vPuhKss9SEbsfcQQAYyuW0pwsA_mMKLb2w6XyJJucvD-5MgBKAW5_O8KOD4tnetMuUtSxfGiGvzFqhnkC-wnUkwpA) 的 「登入 Google」點選兩步驟驗證,並且完成設定。 2. 建立應用程式密碼 > 「開啟兩步驟驗證」的下方有一個「應用程式密碼」,點進去後選擇「郵件」跟「其他」,名字就取一個自己會認得的就可以,完成後會顯示密碼,複製貼到 `.gitconfig` 或是 `.muttrc` 就可以了。 ## 在本地端建立一個 Repo 如果直接去 github 上 clone 會花很長的時間,這裡我是到 [release](https://github.com/torvalds/linux/tags) 找最新的檔案下載,之後再解壓縮就好了。 這裡舉我下載的 `linux-5.19-rc1.tar.gz` 為例,載完後將檔案解壓縮到想要開發的目錄下: ``` $ tar -zxvf linux-5.19-rc1.tar.gz ``` 之後就可以進去設定 git: ``` $ cd linux-5.19-rc1 $ git init $ git add . $ git commit -m "origin" $ git checkout -b my-patch ``` > 如果是第一次使用 git 也要記得先`git config` 設定一下名字跟信箱喔! 之後就可以進行修改了! ## Commit Message 完成自己的修改後就可以新增 commit: ``` $ git commit -asv ``` -a:加入剛剛修改並且有 track 的檔案 -s:commit 會加上 `Signed-off-by: <你的名字> <你的信箱@XXX.com>` -v:verbose,會列出你的修改,看著寫 commit message 會比較方便 ### commit message 格式 Patch 的格式都有嚴格的限制,沒有寫過的同學可以去看你編輯的檔案之前 commit 是如何寫的比較有概念。 簡單來說就是會分成:標題、內容描述、自己的簽名,中間都會空一行: ``` subsystemName: short description # blank line patch content description # blank line Signed-off-by: "name" <email> ``` ## 建立 Patch 完成 commit 就可以建立等等要寄出去的 patch 了: ``` $ git format-patch master ``` 建立好的 patch 要先通過一些 scripts 裡面的檢查: ``` $ ./scripts/checkpatch.pl ./patch_name.patch ``` 如果你的 patch 有問題,會有提示訊息跟你說是哪裡需要修改,修改完後可以使用: ``` $ git commit -a --amend $ git format-patch master ``` ## 寄送 Patch 接著就要找出 maintainer 是誰,並且將 patch 寄給他,這邊舉修改 docs 為例: ``` $ ./scripts/get_maintainer.pl ./patch_name.patch Jonathan Corbet <corbet@lwn.net> (maintainer:DOCUMENTATION) linux-doc@vger.kernel.org (open list:DOCUMENTATION) linux-kernel@vger.kernel.org (open list) ``` 從輸出就可以看到要寄給的人了,通常裡面的人都會要 CC 到。 使用 `git send-email`: ``` $ git send-email --to corbet@lwn.net \ --cc linux-doc@vger.kernel.org \ --cc linux-kernel@vger.kernel.org \ ./patch_name.patch ``` 使用 `mutt`: ``` $ mutt -H ./patch_name.patch ``` ## 後續 之後就可以到 [lkml.org](https://lkml.org/) 看看有沒有出現你的 patch 了,靜靜等待 review 就好了。 ### 後記 之後在看 UML (User Mode Linux) 的時候找到一個錯字,也順手送了一個 patch 過去,document 的維護者 Jonathon 還恭喜我發送第一個 kernel patch,人真的很好 xD > Jonathon 的[回覆](https://lore.kernel.org/all/20220621072910.4704-1-1030steven@gmail.com/t/)