手动安装 kpatch 编译环境

手动安装 kpatch 编译环境



1. 环境

  • Red Hat Enterprise Linux 7.6
  • 3.10.0-957.el7.x86_64
  • ccache-3.3.4-1.el7.x86_64.rpm


    2. 安装编译依赖的rpm 包

    1
    # yum install gcc kernel-devel-$(uname -r) elfutils elfutils-devel pesign yum-utils zlib-devel binutils-devel newt-devel python-devel perl-ExtUtils-Embed audit-libs-devel numactl-devel pciutils-devel bison ncurses-devel gcc-plugin-devel kernel-debuginfo kernel-debuginfo-common gcc-plugin-devel patchutils


    3. 创建 ccache, 可以优化编译的速度 (可选步骤,但是建议安装)

  • (ccache represents “compiler cache” which is a tool for the gcc compiler used to compile the same program over and over again with little downtime, While it may take a few seconds longer to compile a program the first time with ccache, subsequent compiles will be much, much faster.)

    3.1 安装ccache rpm 包

    1
    # yum install https://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/c/ccache-3.3.4-1.el7.x86_64.rpm

    3.2 设置最大可用的cache 大小

    1
    # ccache --max-size=8G

    3.3 修改 gcc 别名,这样在调用gcc的时候就可以使用ccache了

    1
    2
    3
    # vi /etc/profile.d/gcc.sh
    alias gcc="ccache gcc"
    # source /etc/profile.d/gcc.sh


    4. 下载kpatch 源代码

    1
    # git clone https://github.com/dynup/kpatch.git


    5. 编译安装kpatch源代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    # make -j2 && make install
    make -C kpatch-build
    make -C kpatch
    make[1]: Entering directory `/mnt/kpatchDemoSam/kpatch/kpatch'
    make[1]: Nothing to be done for `all'.
    make[1]: Leaving directory `/mnt/kpatchDemoSam/kpatch/kpatch'
    make -C kmod
    make[1]: Entering directory `/mnt/kpatchDemoSam/kpatch/kpatch-build'
    gcc -MMD -MP -I../kmod/patch -Iinsn -Wall -Wsign-compare -g -Werror -c -o create-diff-object.o create-diff-object.c
    make[1]: Entering directory `/mnt/kpatchDemoSam/kpatch/kmod'
    make -C core clean
    make[2]: Entering directory `/mnt/kpatchDemoSam/kpatch/kmod/core'
    rm -f -Rf .*.o.cmd .*.ko.cmd .tmp_versions *.o *.ko *.mod.c \
    Module.symvers
    make[2]: Leaving directory `/mnt/kpatchDemoSam/kpatch/kmod/core'
    make -C core
    make[2]: Entering directory `/mnt/kpatchDemoSam/kpatch/kmod/core'
    make -C /lib/modules/3.10.0-957.el7.x86_64/build M=/mnt/kpatchDemoSam/kpatch/kmod/core kpatch.ko
    gcc -MMD -MP -I../kmod/patch -Iinsn -Wall -Wsign-compare -g -Werror -c -o kpatch-elf.o kpatch-elf.c
    gcc -MMD -MP -I../kmod/patch -Iinsn -Wall -Wsign-compare -g -Werror -c -o lookup.o lookup.c
    gcc -MMD -MP -I../kmod/patch -Iinsn -Wall -Wsign-compare -g -Werror -c -o insn/insn.o insn/insn.c
    gcc -MMD -MP -I../kmod/patch -Iinsn -Wall -Wsign-compare -g -Werror -c -o insn/inat.o insn/inat.c
    gcc -MMD -MP -I../kmod/patch -Iinsn -Wall -Wsign-compare -g -Werror -c -o create-klp-module.o create-klp-module.c
    make[3]: Entering directory `/usr/src/kernels/3.10.0-957.el7.x86_64'
    make[3]: warning: jobserver unavailable: using -j1. Add `+' to parent make rule.
    gcc -MMD -MP -I../kmod/patch -Iinsn -Wall -Wsign-compare -g -Werror -c -o create-kpatch-module.o create-kpatch-module.c
    CC [M] /mnt/kpatchDemoSam/kpatch/kmod/core/core.o
    gcc create-diff-object.o kpatch-elf.o lookup.o insn/insn.o insn/inat.o -lelf -o create-diff-object
    gcc create-klp-module.o kpatch-elf.o -lelf -o create-klp-module
    gcc create-kpatch-module.o kpatch-elf.o -lelf -o create-kpatch-module
    make[1]: Leaving directory `/mnt/kpatchDemoSam/kpatch/kpatch-build'
    make -C man
    make[1]: Entering directory `/mnt/kpatchDemoSam/kpatch/man'
    gzip -c -9 kpatch.1 > kpatch.1.gz
    gzip -c -9 kpatch-build.1 > kpatch-build.1.gz
    make[1]: Leaving directory `/mnt/kpatchDemoSam/kpatch/man'
    make -C contrib
    make[1]: Entering directory `/mnt/kpatchDemoSam/kpatch/contrib'
    make[1]: Nothing to be done for `all'.
    make[1]: Leaving directory `/mnt/kpatchDemoSam/kpatch/contrib'
    CC [M] /mnt/kpatchDemoSam/kpatch/kmod/core/shadow.o
    LD [M] /mnt/kpatchDemoSam/kpatch/kmod/core/kpatch.o
    MODPOST 1 modules
    CC /mnt/kpatchDemoSam/kpatch/kmod/core/kpatch.mod.o
    LD [M] /mnt/kpatchDemoSam/kpatch/kmod/core/kpatch.ko
    make[3]: Leaving directory `/usr/src/kernels/3.10.0-957.el7.x86_64'
    make[2]: Leaving directory `/mnt/kpatchDemoSam/kpatch/kmod/core'
    make[1]: Leaving directory `/mnt/kpatchDemoSam/kpatch/kmod'
    make -C kpatch-build install
    make[1]: Entering directory `/mnt/kpatchDemoSam/kpatch/kpatch-build'
    /usr/bin/install -d /usr/local/libexec/kpatch
    /usr/bin/install create-diff-object create-klp-module create-kpatch-module kpatch-gcc /usr/local/libexec/kpatch
    /usr/bin/install -d /usr/local/bin
    /usr/bin/install kpatch-build /usr/local/bin
    make[1]: Leaving directory `/mnt/kpatchDemoSam/kpatch/kpatch-build'
    make -C kpatch install
    make[1]: Entering directory `/mnt/kpatchDemoSam/kpatch/kpatch'
    /usr/bin/install -d /usr/local/sbin
    /usr/bin/install kpatch /usr/local/sbin
    make[1]: Leaving directory `/mnt/kpatchDemoSam/kpatch/kpatch'
    make -C kmod install
    make[1]: Entering directory `/mnt/kpatchDemoSam/kpatch/kmod'
    /usr/bin/install -d /usr/local/lib/kpatch/3.10.0-957.el7.x86_64
    /usr/bin/install -m 644 core/kpatch.ko /usr/local/lib/kpatch/3.10.0-957.el7.x86_64
    /usr/bin/install -m 644 core/Module.symvers /usr/local/lib/kpatch/3.10.0-957.el7.x86_64
    /usr/bin/install -d /usr/local/share/kpatch/patch
    /usr/bin/install -m 644 patch/* /usr/local/share/kpatch/patch
    make[1]: Leaving directory `/mnt/kpatchDemoSam/kpatch/kmod'
    make -C man install
    make[1]: Entering directory `/mnt/kpatchDemoSam/kpatch/man'
    /usr/bin/install -d /usr/local/share/man/man1
    /usr/bin/install -m 644 kpatch.1.gz /usr/local/share/man/man1
    /usr/bin/install -m 644 kpatch-build.1.gz /usr/local/share/man/man1
    make[1]: Leaving directory `/mnt/kpatchDemoSam/kpatch/man'
    make -C contrib install
    make[1]: Entering directory `/mnt/kpatchDemoSam/kpatch/contrib'
    /usr/bin/install -d /usr/local/lib/systemd/system
    /usr/bin/install -m 0644 kpatch.service /usr/local/lib/systemd/system
    sed -i 's~PREFIX~/usr/local~' /usr/local/lib/systemd/system/kpatch.service
    /usr/bin/install -d /etc/init
    /usr/bin/install -m 0644 kpatch.conf /etc/init
    sed -i 's~PREFIX~/usr/local~' /etc/init/kpatch.conf
    make[1]: Leaving directory `/mnt/kpatchDemoSam/kpatch/contrib'


    6. 检查ccache是否正常工作

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    # ccache -s
    cache directory /root/.ccache
    primary config /root/.ccache/ccache.conf
    secondary config (readonly) /etc/ccache.conf
    cache hit (direct) 0
    cache hit (preprocessed) 0
    cache miss 2
    cache hit rate 0.00 %
    called for link 2
    called for preprocessing 16
    no input file 75
    cleanups performed 0
    files in cache 4
    cache size 733.2 kB
    max cache size 5.0 GB


    7. 编译生成kpatch模块

  • 我已经提前修改了内核代码,所以就可以直接生成kpatch了
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    # ccache make -j2
    patch < patch
    patching file testmod_drv.c
    KCFLAGS="-ffunction-sections -fdata-sections" /usr/bin/make -C /lib/modules/3.10.0-957.el7.x86_64/build M=/mnt/kpatchDemoSam/kpatch/test/testmod testmod.ko
    make[1]: Entering directory `/usr/src/kernels/3.10.0-957.el7.x86_64'
    CC [M] /mnt/kpatchDemoSam/kpatch/test/testmod/testmod_drv.o
    LD [M] /mnt/kpatchDemoSam/kpatch/test/testmod/testmod.o
    MODPOST 1 modules
    CC /mnt/kpatchDemoSam/kpatch/test/testmod/testmod.mod.o
    LD [M] /mnt/kpatchDemoSam/kpatch/test/testmod/testmod.ko
    make[1]: Leaving directory `/usr/src/kernels/3.10.0-957.el7.x86_64'
    strip --keep-file-symbols -d testmod_drv.o
    cp testmod_drv.o testmod_drv.o.patched
    patch -R < patch
    patching file testmod_drv.c
    KCFLAGS="-ffunction-sections -fdata-sections" /usr/bin/make -C /lib/modules/3.10.0-957.el7.x86_64/build M=/mnt/kpatchDemoSam/kpatch/test/testmod testmod.ko
    make[1]: Entering directory `/usr/src/kernels/3.10.0-957.el7.x86_64'
    CC [M] /mnt/kpatchDemoSam/kpatch/test/testmod/testmod_drv.o
    LD [M] /mnt/kpatchDemoSam/kpatch/test/testmod/testmod.o
    MODPOST 1 modules
    CC /mnt/kpatchDemoSam/kpatch/test/testmod/testmod.mod.o
    LD [M] /mnt/kpatchDemoSam/kpatch/test/testmod/testmod.ko
    make[1]: Leaving directory `/usr/src/kernels/3.10.0-957.el7.x86_64'
    strip --keep-file-symbols -d testmod_drv.o
    cp testmod_drv.o testmod_drv.o.orig
    /usr/bin/make -C /lib/modules/3.10.0-957.el7.x86_64/build M=/mnt/kpatchDemoSam/kpatch/test/testmod clean
    make[1]: Entering directory `/usr/src/kernels/3.10.0-957.el7.x86_64'
    CLEAN /mnt/kpatchDemoSam/kpatch/test/testmod/.tmp_versions
    CLEAN /mnt/kpatchDemoSam/kpatch/test/testmod/Module.symvers
    make[1]: Leaving directory `/usr/src/kernels/3.10.0-957.el7.x86_64'
    /usr/bin/make -C /lib/modules/3.10.0-957.el7.x86_64/build M=/mnt/kpatchDemoSam/kpatch/test/testmod testmod.ko
    make[1]: Entering directory `/usr/src/kernels/3.10.0-957.el7.x86_64'
    CC [M] /mnt/kpatchDemoSam/kpatch/test/testmod/testmod_drv.o
    LD [M] /mnt/kpatchDemoSam/kpatch/test/testmod/testmod.o
    MODPOST 1 modules
    CC /mnt/kpatchDemoSam/kpatch/test/testmod/testmod.mod.o
    LD [M] /mnt/kpatchDemoSam/kpatch/test/testmod/testmod.ko
    make[1]: Leaving directory `/usr/src/kernels/3.10.0-957.el7.x86_64'


    8. 安装测试生成的kpatch模块

    8.1 确认已经生成

    1
    2
    # ls *.ko
    testmod.ko

    8.2 安装kpatch模块

    1
    2
    3
    # kpatch install testmod.ko
    installing testmod.ko (3.10.0-957.el7.x86_64)
    Created symlink from /etc/systemd/system/multi-user.target.wants/kpatch.service to /usr/local/lib/systemd/system/kpatch.service.

    8.3 确认模块已经安装完毕

    1
    2
    3
    4
    5
    [root@vm2rhel76 (i_am_vm2_rhel76) testmod]# kpatch list
    Loaded patch modules:

    Installed patch modules:
    testmod (3.10.0-957.el7.x86_64)

    8.4 卸载kpatch模块

    1
    2
    # kpatch uninstall testmod.ko
    uninstalling testmod.ko (3.10.0-957.el7.x86_64)