Ubuntu14.04下kpatch源碼安裝使用

背景

  Kpatch是給Linux內核打熱補丁的工具,所謂熱補丁,就是指打完補丁後,補丁可當即生效,而不須要像傳統打補丁那樣必須重啓Linux才能生效。linux

Kpatch簡介

  最先出現的打熱補丁工具不是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

安裝Kpatch

  從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

  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

  指望的打印出現,證實咱們此次打熱補丁完美成功。

apt-get安裝kpatch

  若是以爲源碼安裝kpatch麻煩,可直接使用apt-get安裝,解決因此依賴問題。固然,這種方法不能選擇本身想要的版本,並且版本偏老。

apt-get install kpatch
apt-get install kpatch-build
相關文章
相關標籤/搜索