1 Star 0 Fork 43

henry_Fan / kpatch

forked from src-openEuler / kpatch 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
make_hotpatch 20.01 KB
一键复制 编辑 原始数据 按行查看 历史
谢志鹏 提交于 2022-03-30 16:22 . delete useless code
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673
#!/bin/bash
# Copyright (C) 2019. Huawei Technologies Co., Ltd. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 and
# only version 2 as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
SHELL_DIR=$(dirname $0)
SHELL_DIR=$(cd $SHELL_DIR; pwd)
G_PRIVATE_MODULE=
G_HOTPATCH=
G_HOTPATCH_ID=
G_HOTPATCH_TAR=
G_DIFFEXT=
G_JOBS="$(getconf _NPROCESSORS_ONLN)"
G_PATCH_SRC=
G_KERNEL_SRC=/opt/patch_workspace/kernel-source
G_KERNEL_CONFIG=/opt/patch_workspace/.config
G_HOTPATCH_DIR=/opt/patch_workspace/hotpatch
G_VMLINUX=/opt/patch_workspace/vmlinux
G_PREFIX=klp
G_TMP_DIR=
G_PATCHFILE=
G_MODULE_SRC=
G_MODULE_MAKEFILE=
G_KPLICE_PWD_FIELD="KPLICE_PWD"
G_PRIVATE_MODULE_SRC_FIELD="PRIVATE_MODULE_SRC"
G_KPATCH_FLAGS=/opt/patch_workspace/.flags
G_DEBUG_INFO=
G_EXT_FLAGS=
USERMODBUILDDIR=
#########################################################
# Description: usage
# Input:
# Return: 0-success
#########################################################
function fn_usage()
{
cat << EOF
Usage:
make_hotpatch [*OPTIONS*] -d patch_diffext -i patch_id -m module_src
Options:
-d,--diffext
make hotpatch using the modified source files with
names ending in *patch_diffext*. The patch will be determined by
comparing all of the files in the build directory tree
whose names end with the extra extension *patch_diffext* against the
corresponding files without the extra extension.
-j,--jobs
Specifies the number of jobs to run simultaneously while
performing builds.
-i,--id
Specifies the unique value that will be used as the identifier
of the hotpatch.
-m,--modulesrc
Specifies the module src path for make user module hotpatch.
-f,--makefile
Specifies the module makefile for make user module hotpatch.
--extra_flags
Specifies extra flags file for make user module hotpatch.
--no_stack_check
make hotpatch without stack check when activating or deactivating this patch.
--debug_info
Save debug info when hotpatch building.Default is closed.
-p,--patch
Specifies the patch file
--kallsyms
Specifies module kallsyms in running system(cat /proc/kallsyms|grep mod)
-h,--help
help info
EOF
return 0
}
#########################################################
# Description: fn_do_clean, remove tmp file
# Input:
# $1: init flag
# Return: 0-success
#########################################################
function fn_do_clean()
{
local ret=0
G_EXT_FLAGS=
unset NO_STACK_CHECK
unset KALLSYMS
rm -rf $G_TMP_DIR
}
#########################################################
# Description: fn_check_reg_char
# Input:
# $@: input param
# Return: 0-success,1-failed
#########################################################
function fn_check_reg_char()
{
local l_str=$1
local l_str_maxlen=$2
local l_str_ex=$3
local len_str=${#l_str}
if [ -z "$l_str" ];then
echo "error: the string is empty, check string failed"
return 1
fi
##字符串长度
if [ -n "$l_str_maxlen" ] && [ -z "`echo $l_str_maxlen | sed 's/[0-9]//g'`" ];then
if [ $len_str -gt $l_str_maxlen ]; then
echo "error: The length of $l_str exceed max length $l_str_maxlen."
return 1
fi
fi
#不能包含其他字符
if [ -n "$l_str_ex" ] && [ -n "`echo $l_str | grep -E [$l_str_ex] 2>/dev/null`" ];then
echo "error: string $l_str included characters $l_str_ex."
return 1
fi
##数字和字母开头
if [ -z "`echo $l_str | grep -E '^[a-z0-9A-Z]'`" ];then
echo "error: string $l_str must start with a character ('0-9' or 'A-Z' or 'a-z')."
return 1
fi
##只能数字和字母 -_
if [ -n "`echo $l_str | grep -E '[^a-z0-9A-Z_-]'`" ];then
if [ -n "$l_str_ex" ] ;then
##这个日志写不好
echo "error: string $l_str can only contain characters included by ('0-9', 'a-z', 'A-Z')"
else
echo "error: string $l_str can only contain characters included by ('0-9', 'a-z', 'A-Z', '-', '_')."
fi
return 1
fi
}
#########################################################
# Description: fn_check_id
# Input:
# $1:
# Return: 0-success,1-failed
#########################################################
function fn_check_id()
{
local l_id=$1
fn_check_reg_char "$l_id" "32" "-_"
if [ $? -ne 0 ];then
echo "error: check hotpatch id failed"
return 1
fi
G_HOTPATCH_ID=$l_id
G_HOTPATCH=${G_PREFIX}_${G_HOTPATCH_ID}.ko
G_HOTPATCH_TAR=${G_PREFIX}_${G_HOTPATCH_ID}.tar.gz
if [ -f "$G_HOTPATCH_DIR/$G_HOTPATCH_TAR" ];then
echo "error: $G_HOTPATCH_DIR/$G_HOTPATCH_TAR is exist, check hotpatch id failed"
return 1
fi
return 0
}
#########################################################
# Description: fn_check_jobs
# Input:
# $1:
# Return: 0-success,1-failed
#########################################################
function fn_check_jobs()
{
local l_jobs=$1
if [ -z "`echo "$l_jobs" | grep ^[1-9]`" ] || [ -n "`echo "$l_jobs" | sed 's/[0-9]//g'`" ];then
echo "error: the '-j' option requires a positive integral argument"
return 1
fi
G_JOBS=$l_jobs
return 0
}
#########################################################
# Description: fn_check_patch
# Input:
# $1:
# Return: 0-success,1-failed
#########################################################
function fn_check_patch(){
local l_patch=$1
if [ ! -f $1 ];then
echo "error:patch file $1 not exist"
return 1
fi
G_PATCHFILE=$l_patch
}
#########################################################
# Description: fn_check_diffext
# Input:
# $1:
# Return: 0-success,1-failed
#########################################################
function fn_check_diffext()
{
local l_diffext=$1
if [ -z "$l_diffext" ];then
echo "error: diffext is empty, check diffext failed"
return 1
fi
G_DIFFEXT=$l_diffext
return 0
}
#########################################################
# Description: fn_check_kernelsrc
# Input:
# $1:
# Return: 0-success,1-failed
#########################################################
function fn_check_kernelsrc()
{
local l_kernelsrc=$1
if [ ! -d "$l_kernelsrc" ];then
echo "error: kernel src $l_kernelsrc is not exist, check kernel src failed"
return 1
fi
G_KERNEL_SRC=$l_kernelsrc
return 0
}
#########################################################
# Description: fn_check_modulesrc
# Input:
# $1:
# Return: 0-success,1-failed
#########################################################
function fn_check_modulesrc()
{
local l_modulesrc=$1
if [ ! -d "$l_modulesrc" ];then
echo "error: module src $l_modulesrc is not exist, check module src failed"
return 1
fi
echo "$l_modulesrc" | grep -q ^/
if [ $? -ne 0 ];then
echo "error: module src $l_modulesrc must be absolute path, check module src failed"
return 1
fi
G_MODULE_SRC="$l_modulesrc"
return 0
}
#########################################################
# Description: fn_check_makefile
# Input:
# $1:
# Return: 0-success,1-failed
#########################################################
function fn_check_makefile()
{
local l_module_makefile=$1
if [ ! -f "$l_module_makefile" ] && [ "$(basename $l_module_makefile)" = "Makefile" ];then
echo "error: module makefile $l_module_makefile is not exist or makefile name is not Makefile, check module makefile failed"
return 1
fi
echo "$l_module_makefile" | grep -q ^/
if [ $? -ne 0 ];then
echo "error: module makefile $l_module_makefile must be absolute path, check module src failed"
return 1
fi
G_MODULE_MAKEFILE=$l_module_makefile
return 0
}
#########################################################
# Description: fn_check_extra_flags
# Input:
# $1:
# Return: 0-success,1-failed
#########################################################
function fn_check_extra_flags()
{
local l_extra_flags=$1
if [ ! -f "$l_extra_flags" ];then
echo "error: extra flags file $l_extra_flags is not exist, check extra flags failed"
return 1
fi
G_EXT_FLAGS="`readlink -f ${l_extra_flags}`"
cp -a $l_extra_flags $G_KPATCH_FLAGS
if [ $? -ne 0 ];then
echo "error: copy $l_extra_flags to $G_KPATCH_FLAGS failed"
return 1
fi
return 0
}
#########################################################
# Description: verify input param
# Input:
# $@: input param
# Return: 0-success,1-failed
#########################################################
function fn_verify_input()
{
local input_param=$@
if [ $# -lt 1 ]; then
echo "error: missing param,please check it"
fn_do_clean
fn_usage
exit 1
fi
if [ -z "`echo "$input_param" | grep -w "\-i"`" \
-a -z "`echo $input_param | grep -w "\-\-id"`" \
-a $# -gt 1 ];then
echo "error: missing param -i or --id"
fn_do_clean
fn_usage
exit 1
fi
if [ -z "`echo "$input_param" | grep -w "\-d"`" \
-a -z "`echo $input_param | grep -w "\-\-diffext"`" \
-a -z "`echo $input_param | grep -w "\-p"`" \
-a -z "`echo $input_param | grep -w "\-\-patch"`" \
-a $# -gt 1 ];then
echo "error: missing param -d,--diffext or -p,--patch"
fn_do_clean
fn_usage
exit 1
fi
while [ $# -ge 1 ]; do
case "$1" in
-h|--help)
fn_usage
fn_do_clean
exit 0
;;
-j|--jobs)
fn_check_jobs $2
if [ $? -eq 0 ]; then
shift 2
else
fn_do_clean
fn_usage
exit 1
fi
;;
-i|--id)
fn_check_id $2
if [ $? -eq 0 ]; then
shift 2
else
fn_do_clean
fn_usage
exit 1
fi
;;
-d|--diffext)
fn_check_diffext $2
if [ $? -eq 0 ]; then
shift 2
else
fn_do_clean
fn_usage
exit 1
fi
;;
-p|--patch)
fn_check_patch $2
if [ $? -eq 0 ]; then
shift 2
else
fn_do_clean
fn_usage
exit 1
fi
;;
-k|--kernelsrc)
fn_check_kernelsrc $2
if [ $? -eq 0 ]; then
shift 2
else
fn_do_clean
fn_usage
exit 1
fi
;;
-m|--modulesrc)
fn_check_modulesrc $2
if [ $? -eq 0 ]; then
shift 2
else
fn_do_clean
fn_usage
exit 1
fi
;;
-f|--makefile)
fn_check_makefile $2
if [ $? -eq 0 ]; then
shift 2
else
fn_do_clean
fn_usage
exit 1
fi
;;
--extra_flags)
fn_check_extra_flags $2
if [ $? -eq 0 ]; then
shift 2
else
fn_do_clean
fn_usage
exit 1
fi
;;
--no_stack_check)
export NO_STACK_CHECK="yes"
shift 1
;;
--debug_info)
G_DEBUG_INFO="-d"
shift 1
;;
--kallsyms)
if [ "$2" == "" ];then
echo "error: param --kallsyms need file parameter"
fn_do_clean
fn_usage
exit 1
fi
export KALLSYMS=$(readlink -f $2)
shift 2
;;
*)
echo "error: params is invalid,please check it."
fn_do_clean
fn_usage
exit 1
;;
esac
done
return 0
}
#########################################################
# Description: fn_makepatch
# Input:
# Return: 0-success,1-failed
#########################################################
function fn_makepatch()
{
local l_extra_module=
local l_jobs=
local l_ret=0
local existflag=0
G_PATCH_SRC=`readlink -f $G_KERNEL_SRC`
if [ -d "$G_MODULE_SRC" ];then
echo "make out of tree module hotpatch"
G_PATCH_SRC=$G_MODULE_SRC
l_extra_module="-m $G_MODULE_SRC"
USERMODBUILDDIR=$G_MODULE_SRC
fi
if [ -n "$G_JOBS" ];then
l_jobs="--jobs=$G_JOBS"
fi
G_TMP_DIR=/tmp/${G_PREFIX}_${G_HOTPATCH_ID}
mkdir -p $G_TMP_DIR
if [ -z "$G_PATCHFILE" ];then
#generate src patch file from G_DIFFEXT
G_PATCHFILE=$G_TMP_DIR/$G_HOTPATCH_ID.patch
rm -rf $G_PATCHFILE
cd $G_PATCH_SRC &>/dev/null
l_change_file=($(find -L -name "*$G_DIFFEXT" | xargs readlink -f 2>/dev/null| sort | uniq))
echo "detect change files:${l_change_file[@]}"
for file in ${l_change_file[@]};
do
file="./${file#$(readlink -f $G_PATCH_SRC)}"
orig_file=${file%$G_DIFFEXT}
if [ "${orig_file##*.}" == "h" ]; then
existflag=1 && break
fi
diff -u $orig_file $file >> $G_PATCHFILE
done
cd - &>/dev/null
if [ ${existflag} -eq 1 ]; then
echo "error: do not modify the header file"
return 1
fi
if [ -f $G_PATCHFILE ];then
echo "make patch $G_PATCHFILE"
else
echo "no change detected"
return 1
fi
else
cp $G_PATCHFILE $G_TMP_DIR/${G_HOTPATCH_ID}.patch
G_PATCHFILE=$G_TMP_DIR/${G_HOTPATCH_ID}.patch
fi
cd $G_TMP_DIR &>/dev/null
if [ -n "$G_MODULE_MAKEFILE" ];then
USERMODBUILDDIR=$(dirname $G_MODULE_MAKEFILE)
fi
export USERMODBUILDDIR
export USERMODFLAGS=`cat $G_KPATCH_FLAGS`
export NO_PROFILING_CALLS="yes"
export DISABLE_AFTER_LOAD="yes"
export KEEP_JUMP_LABEL="yes"
UNAME_R=$(uname -r)
UNAME_R_ARCH=${UNAME_R##*.}
SKIP_GCC_CHECK=""
if [[ "${UNAME_R_ARCH}" != "$(uname -p)" ]];then
echo "build in cross compile environment, skip gcc check"
SKIP_GCC_CHECK="--skip-gcc-check"
fi
kpatch-build -s $G_PATCH_SRC -c $G_KERNEL_CONFIG -v $G_VMLINUX ${SKIP_GCC_CHECK} -n "${G_PREFIX}_${G_HOTPATCH_ID}" $G_DEBUG_INFO $G_PATCHFILE -R
l_ret=$?
cd - &>/dev/null
if [ $l_ret -eq 0 ] && [ -f "$G_TMP_DIR/$G_HOTPATCH" ];then
cd /tmp &>/dev/null
l_env_file=$G_TMP_DIR/toolenv
if [ -n "`which rpm 2>/dev/null`" ]; then
echo "------------------------------------------------------------------------ " > "${l_env_file}"
echo >> "${l_env_file}"
echo "The kpatch tool version info and release date:" >> "${l_env_file}"
rpm -qi kpatch >> "${l_env_file}"
echo >> "${l_env_file}"
echo "------------------------------------------------------------------------ " >> "${l_env_file}"
else
echo "------------------------------------------------------------------------ " >> "${l_env_file}"
fi
echo >> "${l_env_file}"
echo "The hotpatch build time:" >> "${l_env_file}"
echo "`date '+%Y-%m-%d %H:%M:%S'`" >> "${l_env_file}"
echo >> "${l_env_file}"
echo "------------------------------------------------------------------------ " >> "${l_env_file}"
if [ -f "/etc/EulerLinux.conf" ]; then
echo >> "${l_env_file}"
echo "The euler compile env version info:" >> "${l_env_file}"
cat /etc/EulerLinux.conf >> "${l_env_file}"
echo >> "${l_env_file}"
echo "------------------------------------------------------------------------ " >> "${l_env_file}"
fi
if [ -n "${G_MODULE_SRC}" ]; then
echo >> "${l_env_file}"
echo "The module hotpatch compile path info:" >> "${l_env_file}"
echo "MODULE_SRC=${G_MODULE_SRC}" >> "${l_env_file}"
echo "MODULE_MAKEFILE=${G_MODULE_MAKEFILE}" >> "${l_env_file}"
echo >> "${l_env_file}"
echo "------------------------------------------------------------------------ " >> "${l_env_file}"
fi
if [ -f "${G_EXT_FLAGS}" ]; then
echo >> "${l_env_file}"
echo "The module hotpatch compile flags info:" >> "${l_env_file}"
cat "${G_EXT_FLAGS}" >> "${l_env_file}"
echo >> "${l_env_file}"
echo "------------------------------------------------------------------------ " >> "${l_env_file}"
fi
if [ -n "${G_DEBUG_INFO}" ]; then
echo >> "${l_env_file}"
echo "The debug option info:" >> "${l_env_file}"
echo "${G_DEBUG_INFO}" >> "${l_env_file}"
echo >> "${l_env_file}"
echo "------------------------------------------------------------------------ " >> "${l_env_file}"
fi
tar -czf $G_HOTPATCH_TAR ${G_PREFIX}_${G_HOTPATCH_ID}
mv ${G_HOTPATCH_TAR} ${G_HOTPATCH_DIR}
cd - &>/dev/null
if [ $? -ne 0 ];then
echo "error: move ${G_HOTPATCH} to ${G_KSPLICE_HOTPATCH} failed"
return 1
fi
else
echo "error: invoke kpatch-build shell script to build patch failed"
return 1
fi
}
#########################################################
# Description: main
# Input:
# Return: 0-success,1-failed
#########################################################
function fn_main()
{
local ret=
local pid=
fn_verify_input $@
if [ $? -ne 0 ]; then
fn_do_clean
return 1
fi
fn_makepatch
if [ $? -ne 0 ]; then
fn_do_clean
return 1
fi
fn_do_clean
return 0
}
function fn_prepare()
{
local src_dir=""
kerver=`uname -r`
if [ ! -d /usr/src/linux-$kerver ];then
kerver=${kerver%.x86_64}
kerver=${kerver%.aarch64}
src_dir="kernels"
fi
echo kernel version:$kerver
if [ ! -L kernel-source ];then
if [ -d /arm/arm_kernel ];then
ln -s /arm/arm_kernel/linux-$kerver kernel-source
else
ln -s /usr/src/$src_dir/linux-$kerver kernel-source
cp /lib/modules/`uname -r`/build/Makefile /usr/src/$src_dir/linux-$kerver
fi
fi
if [ ! -L .config ];then
if [ -d /arm/arm_kernel ];then
ln -s /arm/arm_kernel/linux-$kerver/.config .config
else
ln -s /usr/src/$src_dir/linux-$kerver/.config .config
cp /lib/modules/`uname -r`/build/.config /usr/src/$src_dir/linux-$kerver
fi
fi
rm -rf $G_KPATCH_FLAGS
touch $G_KPATCH_FLAGS
}
G_NUM=`pidof -x make_hotpatch | wc -w`
if [ $G_NUM -gt 2 ];then
echo "[$0]someone is making, please try again later."
exit 1
fi
fn_prepare
fn_main $@
exit $?
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/henry-fan/kpatch.git
git@gitee.com:henry-fan/kpatch.git
henry-fan
kpatch
kpatch
master

搜索帮助

344bd9b3 5694891 D2dac590 5694891