209 lines
6.7 KiB
Diff
209 lines
6.7 KiB
Diff
|
|
From c27f1093cd47c48e2f403c4ffb29bf066ce0bea5 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||
|
|
Date: Fri, 2 Nov 2018 17:24:24 +0000
|
||
|
|
Subject: [PATCH 1002/1015] kpatch-build: support third party module make
|
||
|
|
hotpatch
|
||
|
|
|
||
|
|
support out of tree module to make hotpatch.
|
||
|
|
|
||
|
|
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||
|
|
---
|
||
|
|
kpatch-build/kpatch-build | 76 ++++++++++++++++++++++++++++++++++++---------
|
||
|
|
kpatch-build/kpatch-gcc | 5 +++
|
||
|
|
2 files changed, 66 insertions(+), 15 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
|
||
|
|
index a76913f..ccef86d 100755
|
||
|
|
--- a/kpatch-build/kpatch-build
|
||
|
|
+++ b/kpatch-build/kpatch-build
|
||
|
|
@@ -102,7 +102,11 @@ remove_patches() {
|
||
|
|
for (( ; APPLIED_PATCHES>0; APPLIED_PATCHES-- )); do
|
||
|
|
idx=$(( APPLIED_PATCHES - 1))
|
||
|
|
patch="${PATCH_LIST[$idx]}"
|
||
|
|
- patch -p1 -R -d "$SRCDIR" < "$patch" &> /dev/null
|
||
|
|
+ if [ -n "$USERMODDIR" ];then
|
||
|
|
+ patch -p1 -R -d "$USERMODDIR" < "$patch" &> /dev/null
|
||
|
|
+ else
|
||
|
|
+ patch -p1 -R -d "$SRCDIR" < "$patch" &> /dev/null
|
||
|
|
+ fi
|
||
|
|
done
|
||
|
|
|
||
|
|
# If $SRCDIR was a git repo, make sure git actually sees that
|
||
|
|
@@ -318,8 +322,8 @@ find_parent_obj() {
|
||
|
|
num="$(grep -l "$grepname" "$last_deep_find"/.*.cmd | grep -Fvc "$pdir/.${file}.cmd")"
|
||
|
|
fi
|
||
|
|
if [[ "$num" -eq 0 ]]; then
|
||
|
|
- parent="$(find ./* -name ".*.cmd" -print0 | xargs -0 grep -l "$grepname" | grep -Fv "$pdir/.${file}.cmd" | cut -c3- | head -n1)"
|
||
|
|
- num="$(find ./* -name ".*.cmd" -print0 | xargs -0 grep -l "$grepname" | grep -Fvc "$pdir/.${file}.cmd")"
|
||
|
|
+ parent="$(find . -name ".*.cmd" -print0 | xargs -0 grep -l "$grepname" | grep -Fv "$pdir/.${file}.cmd" | cut -c3- | head -n1)"
|
||
|
|
+ num="$(find . -name ".*.cmd" -print0 | xargs -0 grep -l "$grepname" | grep -Fvc "$pdir/.${file}.cmd")"
|
||
|
|
[[ "$num" -eq 1 ]] && last_deep_find="$(dirname "$parent")"
|
||
|
|
fi
|
||
|
|
else
|
||
|
|
@@ -335,6 +339,9 @@ find_parent_obj() {
|
||
|
|
PARENT="${PARENT#.}"
|
||
|
|
PARENT="${PARENT%.cmd}"
|
||
|
|
PARENT="$dir/$PARENT"
|
||
|
|
+ if [ -n "$USERMODDIR" ];then
|
||
|
|
+ PARENT="$(readlink -f "$PARENT")"
|
||
|
|
+ fi
|
||
|
|
[[ ! -e "$PARENT" ]] && die "ERROR: can't find parent $PARENT for $1"
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -397,7 +404,7 @@ usage() {
|
||
|
|
echo " (not recommended)" >&2
|
||
|
|
}
|
||
|
|
|
||
|
|
-options="$(getopt -o ha:r:s:c:v:j:t:n:o:d -l "help,archversion:,sourcerpm:,sourcedir:,config:,vmlinux:,jobs:,target:,name:,output:,debug,skip-gcc-check,skip-cleanup" -- "$@")" || die "getopt failed"
|
||
|
|
+options="$(getopt -o ha:r:s:c:v:j:t:n:o:dm:b: -l "help,archversion:,sourcerpm:,sourcedir:,config:,vmlinux:,jobs:,target:,name:,output:,debug,skip-gcc-check,skip-cleanup,moduledir,builddir" -- "$@")" || die "getopt failed"
|
||
|
|
|
||
|
|
eval set -- "$options"
|
||
|
|
|
||
|
|
@@ -463,6 +470,16 @@ while [[ $# -gt 0 ]]; do
|
||
|
|
echo "WARNING: Skipping gcc version matching check (not recommended)"
|
||
|
|
SKIPGCCCHECK=1
|
||
|
|
;;
|
||
|
|
+ -m|--moduledir)
|
||
|
|
+ USERMODDIR=$(readlink -f "$2")
|
||
|
|
+ shift
|
||
|
|
+ [[ ! -d "$USERMODDIR" ]] && die "module dir $USERMODDIR not found"
|
||
|
|
+ ;;
|
||
|
|
+ -b|--builddir)
|
||
|
|
+ BUILDDIR=$(readlink -f "$2")
|
||
|
|
+ shift
|
||
|
|
+ [[ ! -d "$BUILDDIR" ]] && die "kernel develop dir $BUILDDIR not found"
|
||
|
|
+ ;;
|
||
|
|
*)
|
||
|
|
[[ "$1" = "--" ]] && shift && continue
|
||
|
|
[[ ! -f "$1" ]] && die "patch file '$1' not found"
|
||
|
|
@@ -528,7 +545,7 @@ if [[ "$ARCHVERSION" =~ - ]]; then
|
||
|
|
fi
|
||
|
|
[[ "$ARCHVERSION" =~ .el7a. ]] && ALT="-alt"
|
||
|
|
|
||
|
|
-[[ -z "$TARGETS" ]] && TARGETS="vmlinux modules"
|
||
|
|
+[[ -z "$USERMODDIR" ]] && [[ -z "$TARGETS" ]] && TARGETS="vmlinux modules"
|
||
|
|
|
||
|
|
# Don't check external file.
|
||
|
|
# shellcheck disable=SC1091
|
||
|
|
@@ -691,7 +708,11 @@ fi
|
||
|
|
grep -q "CONFIG_DEBUG_INFO_SPLIT=y" "$CONFIGFILE" && die "kernel option 'CONFIG_DEBUG_INFO_SPLIT' not supported"
|
||
|
|
|
||
|
|
echo "Testing patch file(s)"
|
||
|
|
-cd "$SRCDIR" || die
|
||
|
|
+if [ -z "$USERMODDIR" ];then
|
||
|
|
+ cd "$SRCDIR" || die
|
||
|
|
+else
|
||
|
|
+ cd $USERMODDIR || die
|
||
|
|
+fi
|
||
|
|
apply_patches
|
||
|
|
remove_patches
|
||
|
|
|
||
|
|
@@ -709,15 +730,23 @@ find_special_section_data
|
||
|
|
if [[ $DEBUG -ge 4 ]]; then
|
||
|
|
export KPATCH_GCC_DEBUG=1
|
||
|
|
fi
|
||
|
|
-
|
||
|
|
-echo "Building original kernel"
|
||
|
|
-./scripts/setlocalversion --save-scmversion || die
|
||
|
|
+if [ -z "$USERMODDIR" ];then
|
||
|
|
+ echo "Building original kernel"
|
||
|
|
+ ./scripts/setlocalversion --save-scmversion || die
|
||
|
|
+else
|
||
|
|
+ echo "Building original module"
|
||
|
|
+fi
|
||
|
|
unset KPATCH_GCC_TEMPDIR
|
||
|
|
# $TARGETS used as list, no quotes.
|
||
|
|
# shellcheck disable=SC2086
|
||
|
|
CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " make "-j$CPUS" $TARGETS 2>&1 | logger || die
|
||
|
|
|
||
|
|
-echo "Building patched kernel"
|
||
|
|
+sleep 1
|
||
|
|
+if [ -z "$USERMODDIR" ];then
|
||
|
|
+ echo "Building patched kernel"
|
||
|
|
+else
|
||
|
|
+ echo "Building patched module"
|
||
|
|
+fi
|
||
|
|
apply_patches
|
||
|
|
mkdir -p "$TEMPDIR/orig" "$TEMPDIR/patched"
|
||
|
|
KPATCH_GCC_TEMPDIR="$TEMPDIR"
|
||
|
|
@@ -739,14 +768,22 @@ if [[ ! -e "$TEMPDIR/changed_objs" ]]; then
|
||
|
|
die "no changed objects found"
|
||
|
|
fi
|
||
|
|
|
||
|
|
-grep -q vmlinux "$SRCDIR/Module.symvers" || die "truncated $SRCDIR/Module.symvers file"
|
||
|
|
+SYMVERS="$SRCDIR/Module.symvers"
|
||
|
|
+if [ ! -f "$SYMVERS" -a -n "$BUILDDIR" ];then
|
||
|
|
+ SYMVERS="$BUILDDIR/Module.symvers"
|
||
|
|
+fi
|
||
|
|
+grep -q vmlinux "$SYMVERS" || die "truncated $SYMVERS file"
|
||
|
|
|
||
|
|
# Read as words, no quotes.
|
||
|
|
# shellcheck disable=SC2013
|
||
|
|
for i in $(cat "$TEMPDIR/changed_objs")
|
||
|
|
do
|
||
|
|
mkdir -p "$TEMPDIR/patched/$(dirname "$i")" || die
|
||
|
|
- cp -f "$SRCDIR/$i" "$TEMPDIR/patched/$i" || die
|
||
|
|
+ if [ -z "$USERMODDIR" ];then
|
||
|
|
+ cp -f "$SRCDIR/$i" "$TEMPDIR/patched/$i" || die
|
||
|
|
+ else
|
||
|
|
+ cp -f "$i" "$TEMPDIR/patched/$i" || die
|
||
|
|
+ fi
|
||
|
|
done
|
||
|
|
|
||
|
|
echo "Extracting new and modified ELF sections"
|
||
|
|
@@ -788,7 +825,11 @@ for i in $FILES; do
|
||
|
|
[[ "$i" = usr/initramfs_data.o ]] && continue
|
||
|
|
|
||
|
|
mkdir -p "output/$(dirname "$i")"
|
||
|
|
- cd "$SRCDIR" || die
|
||
|
|
+ if [ -z "$USERMODDIR" ];then
|
||
|
|
+ cd "$SRCDIR" || die
|
||
|
|
+ else
|
||
|
|
+ cd $USERMODDIR || die
|
||
|
|
+ fi
|
||
|
|
find_kobj "$i"
|
||
|
|
cd "$TEMPDIR" || die
|
||
|
|
if [[ -e "orig/$i" ]]; then
|
||
|
|
@@ -808,7 +849,7 @@ for i in $FILES; do
|
||
|
|
# create-diff-object orig.o patched.o parent-name parent-symtab
|
||
|
|
# Module.symvers patch-mod-name output.o
|
||
|
|
"$TOOLSDIR"/create-diff-object "orig/$i" "patched/$i" "$KOBJFILE_NAME" \
|
||
|
|
- "$SYMTAB" "$SRCDIR/Module.symvers" "${MODNAME//-/_}" \
|
||
|
|
+ "$SYMTAB" "$SYMVERS" "${MODNAME//-/_}" \
|
||
|
|
"output/$i" 2>&1 | logger 1
|
||
|
|
check_pipe_status create-diff-object
|
||
|
|
# create-diff-object returns 3 if no functional change is found
|
||
|
|
@@ -871,7 +912,12 @@ fi
|
||
|
|
|
||
|
|
cd "$TEMPDIR/patch" || die
|
||
|
|
|
||
|
|
-KPATCH_BUILD="$SRCDIR" KPATCH_NAME="$MODNAME" \
|
||
|
|
+if [ -z "$BUILDDIR" ];then
|
||
|
|
+ KPATCH_BUILDIR="$SRCDIR"
|
||
|
|
+else
|
||
|
|
+ KPATCH_BUILDIR="$BUILDDIR"
|
||
|
|
+fi
|
||
|
|
+KPATCH_BUILD="$KPATCH_BUILDIR" KPATCH_NAME="$MODNAME" \
|
||
|
|
KBUILD_EXTRA_SYMBOLS="$KBUILD_EXTRA_SYMBOLS" \
|
||
|
|
KPATCH_LDFLAGS="$KPATCH_LDFLAGS" \
|
||
|
|
make 2>&1 | logger || die
|
||
|
|
diff --git a/kpatch-build/kpatch-gcc b/kpatch-build/kpatch-gcc
|
||
|
|
index 2d56da1..21f7e2e 100755
|
||
|
|
--- a/kpatch-build/kpatch-gcc
|
||
|
|
+++ b/kpatch-build/kpatch-gcc
|
||
|
|
@@ -23,6 +23,11 @@ if [[ "$TOOLCHAINCMD" = "gcc" ]] ; then
|
||
|
|
[[ "$obj" = */.tmp_mc_*.o ]] && break;
|
||
|
|
|
||
|
|
[[ "$obj" = */.tmp_*.o ]] && obj="${obj/.tmp_/}"
|
||
|
|
+
|
||
|
|
+ if [[ $obj =~ \/\.[0-9]+\.o ]]; then
|
||
|
|
+ break;
|
||
|
|
+ fi
|
||
|
|
+
|
||
|
|
case "$obj" in
|
||
|
|
*.mod.o|\
|
||
|
|
*built-in.o|\
|
||
|
|
--
|
||
|
|
1.7.5.4
|
||
|
|
|