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
相关文章
相关标签/搜索