Kpatch是給Linux內核打熱補丁的工具,所謂熱補丁,就是指打完補丁後,補丁可當即生效,而不須要像傳統打補丁那樣必須重啓Linux才能生效。linux
最先出現的打熱補丁工具不是Kpatch,而是Ksplice。可是Ksplice被Oracle收購後,一些發行版生產商就不得不開發本身的熱補丁工具,分別是Redhat的Kpatch和Suse的KGraft。同時,在這兩家廠商的推動下,kernel4.0開始,開始集成了livepatch技術,該技術和其餘熱補丁技術相似。
Kpatch雖然是Redhat研發,但其也支持Ubuntu、Debian、Oracle Linux等的發行版,本文將介紹在Ubuntu14.04下安裝和使用Kpatch軟件。git
熱補丁不是萬能的,尤爲是如今技術還不足夠成熟的時候。在使用Kpatch熱補丁前,咱們須要知道Kpatch的不足之處:
1.若是在已經打過patch的環境繼續打patch,那麼新patch必須是基於上個patch打的補丁。
2.不支持修改數據結構的patch,若是有這樣的patch,用戶必須改代碼。
3. 不支持修改__init函數的補丁。
4.不支持修改靜態數據。
5.不支持修改vdso的函數,由於其運行在用戶空間。github
注意:必須保證有15GB的空閒磁盤空間,以便在~/.kpatch下生成中間緩存文件。 1.安裝編譯Kpatch所需的依賴環境:ubuntu
apt-get install make gcc libelf-dev
安裝kptch-build運行所需的環境:vim
apt-get install dpkg-dev apt-get build-dep linux # optional, but highly recommended apt-get install ccache ccache --max-size=5G
安裝內核調試信息:緩存
# Add ddebs repository codename=$(lsb_release -sc) sudo tee /etc/apt/sources.list.d/ddebs.list << EOF deb http://ddebs.ubuntu.com/ ${codename} main restricted universe multiverse deb http://ddebs.ubuntu.com/ ${codename}-security main restricted universe multiverse deb http://ddebs.ubuntu.com/ ${codename}-updates main restricted universe multiverse deb http://ddebs.ubuntu.com/ ${codename}-proposed main restricted universe multiverse EOF # add APT key wget -Nq http://ddebs.ubuntu.com/dbgsym-release-key.asc -O- | sudo apt-key add - apt-get update && apt-get install linux-image-$(uname -r)-dbgsym
從github下載源碼,路徑爲:https://github.com/dynup/kpatch。這裏我沒有使用master,而是用了當前最新的branch——v0.3.4。安裝較爲簡單:數據結構
make make install
**注意:**若是使用了新的內核,那麼也須要從新編譯並安裝Kpatch,由於它會根據當前kernel版本,生成一些符號表文件。若是沒有從新編譯安裝Kpatch,那麼你在使用Kpatch-build時,就會出現「unable to find Module.symvers for kpatch core module.」的錯誤。函數
Kpatch安裝完成後,提供了kpath和kpatch-build這兩個腳本程序。其中,kpatch-build經過源代碼、patch文件、config文件等生成一個或多個ko模塊,kpatch再加載這些ko模塊,從而達到打熱補丁的效果。工具
從http://www.kernel.org或者其餘鏡像源下載3.9.0及以上的kernel版本(Kpatch不支持3.9如下的版本),儘可能選擇國內的鏡像,下載速度會稍微快一些。我這裏使用3.9版本的kernel代碼。ui
cd /usr/src wget http://mirror.lzu.edu.cn/kernel/v3.x/linux-3.9.tar.gz tar zxvf linux-3.9.tar.gz cd linux-3.9 # 生成.config文件,爲了編譯較快,我這裏只使用較精簡的config make localmodconfig # 編譯並安裝新版本的kernel # 若是編譯過程當中出現什麼問題,請參考其餘文章解決,這裏再也不詳述 make bzImage -j 4 && make modules -j 4 && make modules_install && make install # 配置grub,使最新編譯的kernel生效,詳細配置方法可參考我其餘博客 reboot
重啓後,再進入/usr/src目錄,作一份代碼的拷貝,並在拷貝代碼中,在Kpatch容許的範圍內,修改一些代碼,而後生成patch文件。我這裏是在建立文件夾的地方增長了一行打印,調用的地方不會太多,並且容易觸發,查看效果比較直觀。
cd /usr/src cp -arf linux-3.9 linux-3.9-modify vim linux-3.9-modify/fs/namei.c # 查找vfs_mkdir關鍵字,並在vfs_mkdir函數中的字段定義後,直接加入一些打印,我這裏加入了「printk(KERN_ERR "kpatch test mkdir\n");」建立文件夾後,就會打印kpatch test mkdir。 # 建立patch文件 diff -Naur linux-3.9 linux-3.9-modify > my.patch
以後,就可經過kpatch-build生成ko模塊。
kpatch-build -s /usr/src/linux-3.9 /usr/src/my.patch
上面命令行中,-s後跟kernel源代碼的目錄。-r後跟指定的vmlinux,若不直接指定vmlinux,kpatch就會從源目錄中查找vmlinux,如上所示中,咱們就沒有指定vmlinux。patch文件至於最後的位置。kpatch-build更多的參數可經過命令kpatch-build --help或者man kpatch-build來查看。
kpatch-build若是運行失敗,可經過日誌文件~/.kpatch/build.log來查看失敗的具體緣由。若是運行成功,則會在當前目錄生成ko文件。由於個人patch名爲my.patch,根據其名稱生成規則,就生成了名爲kpatch-my.ko的模塊文件。注意,kpatch-build生成的ko文件,不能經過insmod的方式來裝載,而必須使用kpatch load來裝載。並經過kpatch unload來卸載,同時,也可經過kpatch list來查看加載信息。
# kpatch load kpatch-my.ko loading patch module: kpatch-my.ko # kpatch list Loaded patch modules: kpatch_my Installed patch modules:
加載成功後,再任意建立一個目錄,查看/var/log/kern.log或者dmesg,相關日誌以下:
# dmesg [31478.707301] kpatch: loaded patch module 'kpatch_my' [31839.683442] kpatch test mkdir
指望的打印出現,證實咱們此次打熱補丁完美成功。
若是以爲源碼安裝kpatch麻煩,可直接使用apt-get安裝,解決因此依賴問題。固然,這種方法不能選擇本身想要的版本,並且版本偏老。
apt-get install kpatch apt-get install kpatch-build