本文介绍如何在 Alibaba Cloud Linux 2 上使用内核热补丁 (Kernel Live Patching) 功能。
1. 准备工作
1.1 内核版本
首先要确认当前运行的内核版本。在操作系统内部运行下列命令:
uname -r
4.19.57-15.1.al7.x86_64
1.2 安装依赖包和内核相关工具
sudo yum install -y alinux-release-source alinux-release-kernels
sudo yum install -y yum-utils
sudo debuginfo-install -y kernel-$(uname -r) # 安装 Debuginfo 包
sudo yum install -y kpatch pesign zlib-devel \
binutils-devel newt-devel python-devel perl-ExtUtils-Embed \
audit-libs audit-libs-devel numactl-devel pciutils-devel bison patchutils \
kernel-devel-$(uname -r) # 安装依赖工具
sudo yum-builddep -y kernel-$(uname -r) # 检查 build 内核的时候的依赖
1.3 安装 kpatch-build
要想制作热补丁,需要用到一个还没有放进 YUM 源的工具 kpatch-build,需要从 GitHub 上获取源码。运行下列命令获取代码,并进行编译:
sudo yum install -y git
git clone https://github.com/dynup/kpatch.git
cd kpatch
make
1.4 准备内核源码
sudo yumdownloader --source kernel-$(uname -r) #安装内核源码
export VRDA=$(uname -r)
rpm -ivh kernel-${VRDA/x86_64/src}.rpm
rpmbuild --without debug \
--without doc \
--without perf \
--without tools \
--without bpftool \
--without debuginfo \
-bp ~/rpmbuild/SPECS/kernel.spec
export SourceDir=$(ls -d ~/rpmbuild/BUILD/kernel-${VRDA/-*/}/linux-*)
cp ~/rpmbuild/SOURCES/modsign_alinux.pem $SourceDir/certs
cp ~/rpmbuild/SOURCES/x509.genkey $SourceDir/certs
sed -i "s/CONFIG_LOCALVERSION=.*/CONFIG_LOCALVERSION=\"${VRDA/*-/-}\"/" $SourceDir/.config
2. 准备需要进行热补丁的补丁文件
请根据实际情况准备热补丁文件,一般来说从内核源码的 Git 树中获取的补丁文件就可以使用,但是不是所有补丁文件都可以用来制作热补丁,请确保事先对于热补丁的使用范围与限制有充分的了解,否则可能会出现不仅限于操作系统宕机等严重问题。
这里是一个样例补丁文件:
diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c
index edda898..8a4a686 100644
--- a/fs/proc/meminfo.c
+++ b/fs/proc/meminfo.c
@@ -121,7 +121,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
seq_printf(m, "VmallocTotal: %8lu kB\n",
(unsigned long)VMALLOC_TOTAL >> 10);
show_val_kb(m, "VmallocUsed: ", 0ul);
- show_val_kb(m, "VmallocChunk: ", 0ul);
+ show_val_kb(m, "VMALLOCCHUNK: ", 0ul);
show_val_kb(m, "Percpu: ", pcpu_nr_pages());
注意补丁文件一定要与当前下载的内核源码包解压缩之后的源码相匹配。
3. 执行热补丁制作
cd kpatch
export VRDA=$(uname -r)
export SourceDir=$(ls -d ~/rpmbuild/BUILD/kernel-${VRDA/-*/}/linux-*)
./kpatch-build/kpatch-build -v /usr/lib/debug/usr/lib/modules/$(uname -r)/vmlinux \
meminfo.patch \
-s $SourceDir \
-t vmlinux \
-j$(getconf _NPROCESSORS_ONLN) #meminfo.patch 是前面一步里的补丁文件
执行完毕后如果顺利,会在当前目录下产生 livepatch-meminfo.ko 文件
4. 加载热补丁
sudo kpatch load livepatch-meminfo.ko