mirror of
https://github.com/dynup/kpatch
synced 2025-04-17 04:25:57 +00:00
kpatch, kpatch-build, kpatch-gcc: quote all variables
Without proper quoting kpatch fails if the argument contains spaces, the other scripts might be affected as well. Not all new quotes are strictly necessary but they were added for consistency with the existing code and to prevent copy & paste errors in the future. There's one conversion which is not straight-forward: - grepname=$grepname\\\.o + grepname="$grepname\.o" There are different quoting rules with and without the double quotes.
This commit is contained in:
parent
9017bfd32d
commit
08fa04bb0d
@ -35,7 +35,7 @@
|
||||
# - Runs kpatch tools to create and link the patch kernel module
|
||||
|
||||
BASE="$PWD"
|
||||
SCRIPTDIR="$(readlink -f $(dirname $(type -p $0)))"
|
||||
SCRIPTDIR="$(readlink -f "$(dirname "$(type -p "$0")")")"
|
||||
ARCH="$(uname -m)"
|
||||
ARCHVERSION="$(uname -r)"
|
||||
CPUS="$(getconf _NPROCESSORS_ONLN)"
|
||||
@ -57,13 +57,13 @@ warn() {
|
||||
}
|
||||
|
||||
die() {
|
||||
if [[ -z $1 ]]; then
|
||||
if [[ -z "$1" ]]; then
|
||||
msg="kpatch build failed"
|
||||
else
|
||||
msg="$1"
|
||||
fi
|
||||
|
||||
if [[ -e $LOGFILE ]]; then
|
||||
if [[ -e "$LOGFILE" ]]; then
|
||||
warn "$msg. Check $LOGFILE for more details."
|
||||
else
|
||||
warn "$msg."
|
||||
@ -99,11 +99,11 @@ cleanup() {
|
||||
remove_patches
|
||||
# If $SRCDIR was a git repo, make sure git actually sees that
|
||||
# we've reverted our patch(es).
|
||||
[[ -d $SRCDIR/.git ]] && (cd $SRCDIR && git update-index -q --refresh)
|
||||
[[ -d "$SRCDIR/.git" ]] && (cd "$SRCDIR" && git update-index -q --refresh)
|
||||
|
||||
# restore original .config and vmlinux if they were removed with mrproper
|
||||
[[ -e $TEMPDIR/.config ]] && mv -f $TEMPDIR/.config $SRCDIR/
|
||||
[[ -e $TEMPDIR/vmlinux ]] && mv -f $TEMPDIR/vmlinux $SRCDIR/
|
||||
[[ -e "$TEMPDIR/.config" ]] && mv -f "$TEMPDIR/.config" "$SRCDIR/"
|
||||
[[ -e "$TEMPDIR/vmlinux" ]] && mv -f "$TEMPDIR/vmlinux" "$SRCDIR/"
|
||||
|
||||
[[ "$DEBUG" -eq 0 ]] && rm -rf "$TEMPDIR"
|
||||
rm -rf "$RPMTOPDIR"
|
||||
@ -118,7 +118,7 @@ clean_cache() {
|
||||
|
||||
check_pipe_status() {
|
||||
rc="${PIPESTATUS[0]}"
|
||||
if [[ $rc = 139 ]]; then
|
||||
if [[ "$rc" = 139 ]]; then
|
||||
# There doesn't seem to be a consistent/portable way of
|
||||
# accessing the last executed command in bash, so just
|
||||
# pass in the script name for now..
|
||||
@ -140,11 +140,11 @@ find_dirs() {
|
||||
if [[ -e "$SCRIPTDIR/create-diff-object" ]]; then
|
||||
# git repo
|
||||
TOOLSDIR="$SCRIPTDIR"
|
||||
DATADIR="$(readlink -f $SCRIPTDIR/../kmod)"
|
||||
DATADIR="$(readlink -f "$SCRIPTDIR/../kmod")"
|
||||
elif [[ -e "$SCRIPTDIR/../libexec/kpatch/create-diff-object" ]]; then
|
||||
# installation path
|
||||
TOOLSDIR="$(readlink -f $SCRIPTDIR/../libexec/kpatch)"
|
||||
DATADIR="$(readlink -f $SCRIPTDIR/../share/kpatch)"
|
||||
TOOLSDIR="$(readlink -f "$SCRIPTDIR/../libexec/kpatch")"
|
||||
DATADIR="$(readlink -f "$SCRIPTDIR/../share/kpatch")"
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
@ -157,10 +157,10 @@ find_core_symvers() {
|
||||
SYMVERSFILE="$DATADIR/core/Module.symvers"
|
||||
elif [[ -e "$SCRIPTDIR/../libexec/kpatch/create-diff-object" ]]; then
|
||||
# installation path
|
||||
if [[ -e $SCRIPTDIR/../lib/kpatch/$ARCHVERSION/Module.symvers ]]; then
|
||||
SYMVERSFILE="$(readlink -f $SCRIPTDIR/../lib/kpatch/$ARCHVERSION/Module.symvers)"
|
||||
if [[ -e "$SCRIPTDIR/../lib/kpatch/$ARCHVERSION/Module.symvers" ]]; then
|
||||
SYMVERSFILE="$(readlink -f "$SCRIPTDIR/../lib/kpatch/$ARCHVERSION/Module.symvers")"
|
||||
elif [[ -e /lib/modules/$ARCHVERSION/extra/kpatch/Module.symvers ]]; then
|
||||
SYMVERSFILE="$(readlink -f /lib/modules/$ARCHVERSION/extra/kpatch/Module.symvers)"
|
||||
SYMVERSFILE="$(readlink -f "/lib/modules/$ARCHVERSION/extra/kpatch/Module.symvers")"
|
||||
fi
|
||||
fi
|
||||
|
||||
@ -169,9 +169,9 @@ find_core_symvers() {
|
||||
|
||||
gcc_version_check() {
|
||||
# ensure gcc version matches that used to build the kernel
|
||||
local gccver=$(gcc --version |head -n1 |cut -d' ' -f3-)
|
||||
local kgccver=$(readelf -p .comment $VMLINUX |grep GCC: | tr -s ' ' | cut -d ' ' -f6-)
|
||||
if [[ $gccver != $kgccver ]]; then
|
||||
local gccver="$(gcc --version |head -n1 |cut -d' ' -f3-)"
|
||||
local kgccver="$(readelf -p .comment "$VMLINUX" |grep GCC: | tr -s ' ' | cut -d ' ' -f6-)"
|
||||
if [[ "$gccver" != "$kgccver" ]]; then
|
||||
warn "gcc/kernel version mismatch"
|
||||
echo "gcc version: $gccver"
|
||||
echo "kernel version: $kgccver"
|
||||
@ -186,12 +186,12 @@ gcc_version_check() {
|
||||
# <linux>/arch/powerpc/tools/gcc-check-mprofile-kernel.sh
|
||||
#
|
||||
# Postpone the check to the kernel build instead of duplicating it here.
|
||||
if [[ $ARCH = "ppc64le" ]]; then
|
||||
if [[ "$ARCH" = "ppc64le" ]]; then
|
||||
return
|
||||
else
|
||||
# ensure gcc version is >= 4.8
|
||||
gccver=$(echo $gccver |cut -d'.' -f1,2)
|
||||
if [[ $gccver < 4.8 ]]; then
|
||||
gccver="$(echo "$gccver" |cut -d'.' -f1,2)"
|
||||
if [[ "$gccver" < 4.8 ]]; then
|
||||
warn "gcc >= 4.8 required"
|
||||
return 1
|
||||
fi
|
||||
@ -201,7 +201,7 @@ gcc_version_check() {
|
||||
}
|
||||
|
||||
find_special_section_data_ppc64le() {
|
||||
SPECIAL_VARS=$(readelf -wi "$VMLINUX" |
|
||||
SPECIAL_VARS="$(readelf -wi "$VMLINUX" |
|
||||
gawk --non-decimal-data '
|
||||
BEGIN { f = b = e = 0 }
|
||||
|
||||
@ -221,25 +221,25 @@ find_special_section_data_ppc64le() {
|
||||
e == 1 {printf("export EX_STRUCT_SIZE=%d\n", $4); e = 2}
|
||||
|
||||
# Bail out once we have everything
|
||||
f == 2 && b == 2 && e == 2 {exit}')
|
||||
f == 2 && b == 2 && e == 2 {exit}')"
|
||||
|
||||
[[ -n $SPECIAL_VARS ]] && eval "$SPECIAL_VARS"
|
||||
[[ -n "$SPECIAL_VARS" ]] && eval "$SPECIAL_VARS"
|
||||
|
||||
[[ -z $FIXUP_STRUCT_SIZE ]] && die "can't find special struct fixup_entry size"
|
||||
[[ -z $BUG_STRUCT_SIZE ]] && die "can't find special struct bug_entry size"
|
||||
[[ -z $EX_STRUCT_SIZE ]] && die "can't find special struct exception_table_entry size"
|
||||
[[ -z "$FIXUP_STRUCT_SIZE" ]] && die "can't find special struct fixup_entry size"
|
||||
[[ -z "$BUG_STRUCT_SIZE" ]] && die "can't find special struct bug_entry size"
|
||||
[[ -z "$EX_STRUCT_SIZE" ]] && die "can't find special struct exception_table_entry size"
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
find_special_section_data() {
|
||||
if [[ $ARCH = "ppc64le" ]]; then
|
||||
if [[ "$ARCH" = "ppc64le" ]]; then
|
||||
find_special_section_data_ppc64le
|
||||
return
|
||||
fi
|
||||
|
||||
[[ $CONFIG_PARAVIRT -eq 0 ]] && AWK_OPTIONS="-vskip_p=1"
|
||||
SPECIAL_VARS=$(readelf -wi "$VMLINUX" |
|
||||
[[ "$CONFIG_PARAVIRT" -eq 0 ]] && AWK_OPTIONS="-vskip_p=1"
|
||||
SPECIAL_VARS="$(readelf -wi "$VMLINUX" |
|
||||
gawk --non-decimal-data $AWK_OPTIONS '
|
||||
BEGIN { a = b = p = e = 0 }
|
||||
|
||||
@ -262,64 +262,64 @@ find_special_section_data() {
|
||||
e == 1 {printf("export EX_STRUCT_SIZE=%d\n", $4); e = 2}
|
||||
|
||||
# Bail out once we have everything
|
||||
a == 2 && b == 2 && (p == 2 || skip_p) && e == 2 {exit}')
|
||||
a == 2 && b == 2 && (p == 2 || skip_p) && e == 2 {exit}')"
|
||||
|
||||
[[ -n $SPECIAL_VARS ]] && eval "$SPECIAL_VARS"
|
||||
[[ -n "$SPECIAL_VARS" ]] && eval "$SPECIAL_VARS"
|
||||
|
||||
[[ -z $ALT_STRUCT_SIZE ]] && die "can't find special struct alt_instr size"
|
||||
[[ -z $BUG_STRUCT_SIZE ]] && die "can't find special struct bug_entry size"
|
||||
[[ -z $EX_STRUCT_SIZE ]] && die "can't find special struct paravirt_patch_site size"
|
||||
[[ -z $PARA_STRUCT_SIZE && $CONFIG_PARAVIRT -ne 0 ]] && die "can't find special struct paravirt_patch_site size"
|
||||
[[ -z "$ALT_STRUCT_SIZE" ]] && die "can't find special struct alt_instr size"
|
||||
[[ -z "$BUG_STRUCT_SIZE" ]] && die "can't find special struct bug_entry size"
|
||||
[[ -z "$EX_STRUCT_SIZE" ]] && die "can't find special struct paravirt_patch_site size"
|
||||
[[ -z "$PARA_STRUCT_SIZE" && "$CONFIG_PARAVIRT" -ne 0 ]] && die "can't find special struct paravirt_patch_site size"
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
find_parent_obj() {
|
||||
dir=$(dirname $1)
|
||||
absdir=$(readlink -f $dir)
|
||||
pwddir=$(readlink -f .)
|
||||
pdir=${absdir#$pwddir/}
|
||||
file=$(basename $1)
|
||||
grepname=${1%.o}
|
||||
grepname=$grepname\\\.o
|
||||
if [[ $DEEP_FIND -eq 1 ]]; then
|
||||
dir="$(dirname "$1")"
|
||||
absdir="$(readlink -f "$dir")"
|
||||
pwddir="$(readlink -f .)"
|
||||
pdir="${absdir#$pwddir/}"
|
||||
file="$(basename "$1")"
|
||||
grepname="${1%.o}"
|
||||
grepname="$grepname\.o"
|
||||
if [[ "$DEEP_FIND" -eq 1 ]]; then
|
||||
num=0
|
||||
if [[ -n $last_deep_find ]]; then
|
||||
parent=$(grep -l $grepname $last_deep_find/.*.cmd | grep -v $pdir/.${file}.cmd |head -n1)
|
||||
num=$(grep -l $grepname $last_deep_find/.*.cmd | grep -v $pdir/.${file}.cmd |wc -l)
|
||||
if [[ -n "$last_deep_find" ]]; then
|
||||
parent="$(grep -l "$grepname" "$last_deep_find"/.*.cmd | grep -v "$pdir/.${file}.cmd" |head -n1)"
|
||||
num="$(grep -l "$grepname" "$last_deep_find"/.*.cmd | grep -v "$pdir/.${file}.cmd" |wc -l)"
|
||||
fi
|
||||
if [[ $num -eq 0 ]]; then
|
||||
parent=$(find * -name ".*.cmd" | xargs grep -l $grepname | grep -v $pdir/.${file}.cmd |head -n1)
|
||||
num=$(find * -name ".*.cmd" | xargs grep -l $grepname | grep -v $pdir/.${file}.cmd | wc -l)
|
||||
[[ $num -eq 1 ]] && last_deep_find=$(dirname $parent)
|
||||
if [[ "$num" -eq 0 ]]; then
|
||||
parent="$(find * -name ".*.cmd" | xargs grep -l "$grepname" | grep -v "$pdir/.${file}.cmd" |head -n1)"
|
||||
num="$(find * -name ".*.cmd" | xargs grep -l "$grepname" | grep -v "$pdir/.${file}.cmd" | wc -l)"
|
||||
[[ "$num" -eq 1 ]] && last_deep_find="$(dirname "$parent")"
|
||||
fi
|
||||
else
|
||||
parent=$(grep -l $grepname $dir/.*.cmd | grep -v $dir/.${file}.cmd |head -n1)
|
||||
num=$(grep -l $grepname $dir/.*.cmd | grep -v $dir/.${file}.cmd | wc -l)
|
||||
parent="$(grep -l "$grepname" "$dir"/.*.cmd | grep -v "$dir/.${file}.cmd" |head -n1)"
|
||||
num="$(grep -l "$grepname" "$dir"/.*.cmd | grep -v "$dir/.${file}.cmd" | wc -l)"
|
||||
fi
|
||||
|
||||
[[ $num -eq 0 ]] && PARENT="" && return
|
||||
[[ $num -gt 1 ]] && ERROR_IF_DIFF="two parent matches for $1"
|
||||
[[ "$num" -eq 0 ]] && PARENT="" && return
|
||||
[[ "$num" -gt 1 ]] && ERROR_IF_DIFF="two parent matches for $1"
|
||||
|
||||
dir=$(dirname $parent)
|
||||
PARENT=$(basename $parent)
|
||||
PARENT=${PARENT#.}
|
||||
PARENT=${PARENT%.cmd}
|
||||
PARENT=$dir/$PARENT
|
||||
[[ ! -e $PARENT ]] && die "ERROR: can't find parent $PARENT for $1"
|
||||
dir="$(dirname "$parent")"
|
||||
PARENT="$(basename "$parent")"
|
||||
PARENT="${PARENT#.}"
|
||||
PARENT="${PARENT%.cmd}"
|
||||
PARENT="$dir/$PARENT"
|
||||
[[ ! -e "$PARENT" ]] && die "ERROR: can't find parent $PARENT for $1"
|
||||
}
|
||||
|
||||
find_kobj() {
|
||||
arg=$1
|
||||
KOBJFILE=$arg
|
||||
arg="$1"
|
||||
KOBJFILE="$arg"
|
||||
DEEP_FIND=0
|
||||
ERROR_IF_DIFF=
|
||||
while true; do
|
||||
find_parent_obj $KOBJFILE
|
||||
[[ -n $PARENT ]] && DEEP_FIND=0
|
||||
if [[ -z $PARENT ]]; then
|
||||
[[ $KOBJFILE = *.ko ]] && return
|
||||
case $KOBJFILE in
|
||||
find_parent_obj "$KOBJFILE"
|
||||
[[ -n "$PARENT" ]] && DEEP_FIND=0
|
||||
if [[ -z "$PARENT" ]]; then
|
||||
[[ "$KOBJFILE" = *.ko ]] && return
|
||||
case "$KOBJFILE" in
|
||||
*/built-in.o|\
|
||||
arch/x86/lib/lib.a|\
|
||||
arch/x86/kernel/head*.o|\
|
||||
@ -329,13 +329,13 @@ find_kobj() {
|
||||
KOBJFILE=vmlinux
|
||||
return
|
||||
esac
|
||||
if [[ $DEEP_FIND -eq 0 ]]; then
|
||||
if [[ "$DEEP_FIND" -eq 0 ]]; then
|
||||
DEEP_FIND=1
|
||||
continue;
|
||||
fi
|
||||
die "invalid ancestor $KOBJFILE for $arg"
|
||||
fi
|
||||
KOBJFILE=$PARENT
|
||||
KOBJFILE="$PARENT"
|
||||
done
|
||||
}
|
||||
|
||||
@ -343,11 +343,11 @@ find_kobj() {
|
||||
# is replaced with '-'. Also truncate to 48 chars so the full name fits in the
|
||||
# kernel's 56-byte module name array.
|
||||
module_name_string() {
|
||||
echo ${1//[^a-zA-Z0-9_-]/-} |cut -c 1-48
|
||||
echo "${1//[^a-zA-Z0-9_-]/-}" |cut -c 1-48
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "usage: $(basename $0) [options] <patch1 ... patchN>" >&2
|
||||
echo "usage: $(basename "$0") [options] <patch1 ... patchN>" >&2
|
||||
echo " patchN Input patchfile(s)" >&2
|
||||
echo " -h, --help Show this help message" >&2
|
||||
echo " -r, --sourcerpm Specify kernel source RPM" >&2
|
||||
@ -363,7 +363,7 @@ usage() {
|
||||
echo " (not recommended)" >&2
|
||||
}
|
||||
|
||||
options=$(getopt -o hr:s:c:v:j:t:n:o:d -l "help,sourcerpm:,sourcedir:,config:,vmlinux:,jobs:,target:,name:,output:,debug,skip-gcc-check,skip-cleanup" -- "$@") || die "getopt failed"
|
||||
options="$(getopt -o hr:s:c:v:j:t:n:o:d -l "help,sourcerpm:,sourcedir:,config:,vmlinux:,jobs:,target:,name:,output:,debug,skip-gcc-check,skip-cleanup" -- "$@")" || die "getopt failed"
|
||||
|
||||
eval set -- "$options"
|
||||
|
||||
@ -375,25 +375,25 @@ while [[ $# -gt 0 ]]; do
|
||||
;;
|
||||
-r|--sourcerpm)
|
||||
[[ ! -f "$2" ]] && die "source rpm '$2' not found"
|
||||
SRCRPM=$(readlink -f "$2")
|
||||
SRCRPM="$(readlink -f "$2")"
|
||||
shift
|
||||
rpmname=$(basename "$SRCRPM")
|
||||
ARCHVERSION=${rpmname%.src.rpm}.$(uname -m)
|
||||
ARCHVERSION=${ARCHVERSION#kernel-}
|
||||
rpmname="$(basename "$SRCRPM")"
|
||||
ARCHVERSION="${rpmname%.src.rpm}.$(uname -m)"
|
||||
ARCHVERSION="${ARCHVERSION#kernel-}"
|
||||
;;
|
||||
-s|--sourcedir)
|
||||
[[ ! -d "$2" ]] && die "source dir '$2' not found"
|
||||
USERSRCDIR=$(readlink -f "$2")
|
||||
USERSRCDIR="$(readlink -f "$2")"
|
||||
shift
|
||||
;;
|
||||
-c|--config)
|
||||
[[ ! -f "$2" ]] && die "config file '$2' not found"
|
||||
CONFIGFILE=$(readlink -f "$2")
|
||||
CONFIGFILE="$(readlink -f "$2")"
|
||||
shift
|
||||
;;
|
||||
-v|--vmlinux)
|
||||
[[ ! -f "$2" ]] && die "vmlinux file '$2' not found"
|
||||
VMLINUX=$(readlink -f "$2")
|
||||
VMLINUX="$(readlink -f "$2")"
|
||||
shift
|
||||
;;
|
||||
-j|--jobs)
|
||||
@ -406,12 +406,12 @@ while [[ $# -gt 0 ]]; do
|
||||
shift
|
||||
;;
|
||||
-n|--name)
|
||||
MODNAME=$(module_name_string "$2")
|
||||
MODNAME="$(module_name_string "$2")"
|
||||
shift
|
||||
;;
|
||||
-o|--output)
|
||||
[[ ! -d "$2" ]] && die "output dir '$2' not found"
|
||||
BASE=$(readlink -f "$2")
|
||||
BASE="$(readlink -f "$2")"
|
||||
shift
|
||||
;;
|
||||
-d|--debug)
|
||||
@ -430,7 +430,7 @@ while [[ $# -gt 0 ]]; do
|
||||
*)
|
||||
[[ "$1" = "--" ]] && shift && continue
|
||||
[[ ! -f "$1" ]] && die "patch file '$1' not found"
|
||||
PATCH_LIST+=($(readlink -f "$1"))
|
||||
PATCH_LIST+=("$(readlink -f "$1")")
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
@ -447,50 +447,50 @@ mkdir -p "$TEMPDIR" || die "Couldn't create $TEMPDIR"
|
||||
rm -rf "$TEMPDIR"/*
|
||||
rm -f "$LOGFILE"
|
||||
|
||||
if [[ -n $USERSRCDIR ]]; then
|
||||
if [[ -n "$USERSRCDIR" ]]; then
|
||||
SRCDIR="$USERSRCDIR"
|
||||
|
||||
[[ -z $VMLINUX ]] && VMLINUX="$SRCDIR"/vmlinux
|
||||
[[ -z "$VMLINUX" ]] && VMLINUX="$SRCDIR"/vmlinux
|
||||
[[ ! -e "$VMLINUX" ]] && die "can't find vmlinux"
|
||||
|
||||
# Extract the target kernel version from vmlinux in this case.
|
||||
ARCHVERSION=$(strings "$VMLINUX" | grep -e "^Linux version" | awk '{ print($3); }')
|
||||
ARCHVERSION="$(strings "$VMLINUX" | grep -e "^Linux version" | awk '{ print($3); }')"
|
||||
fi
|
||||
|
||||
[[ $SKIPCLEANUP -eq 0 ]] && trap cleanup EXIT INT TERM HUP
|
||||
[[ "$SKIPCLEANUP" -eq 0 ]] && trap cleanup EXIT INT TERM HUP
|
||||
|
||||
KVER=${ARCHVERSION%%-*}
|
||||
if [[ $ARCHVERSION =~ - ]]; then
|
||||
KREL=${ARCHVERSION##*-}
|
||||
KREL=${KREL%.*}
|
||||
KVER="${ARCHVERSION%%-*}"
|
||||
if [[ "$ARCHVERSION" =~ - ]]; then
|
||||
KREL="${ARCHVERSION##*-}"
|
||||
KREL="${KREL%.*}"
|
||||
fi
|
||||
|
||||
[[ -z $TARGETS ]] && TARGETS="vmlinux modules"
|
||||
[[ -z "$TARGETS" ]] && TARGETS="vmlinux modules"
|
||||
|
||||
source /etc/os-release
|
||||
DISTRO=$ID
|
||||
if [[ $DISTRO = fedora ]] || [[ $DISTRO = rhel ]] || [[ $DISTRO = ol ]] || [[ $DISTRO = centos ]]; then
|
||||
[[ -z $VMLINUX ]] && VMLINUX=/usr/lib/debug/lib/modules/$ARCHVERSION/vmlinux
|
||||
DISTRO="$ID"
|
||||
if [[ "$DISTRO" = fedora ]] || [[ "$DISTRO" = rhel ]] || [[ "$DISTRO" = ol ]] || [[ "$DISTRO" = centos ]]; then
|
||||
[[ -z "$VMLINUX" ]] && VMLINUX="/usr/lib/debug/lib/modules/$ARCHVERSION/vmlinux"
|
||||
[[ -e "$VMLINUX" ]] || die "kernel-debuginfo-$ARCHVERSION not installed"
|
||||
|
||||
export PATH=/usr/lib64/ccache:$PATH
|
||||
export PATH="/usr/lib64/ccache:$PATH"
|
||||
|
||||
elif [[ $DISTRO = ubuntu ]] || [[ $DISTRO = debian ]]; then
|
||||
[[ -z $VMLINUX ]] && VMLINUX=/usr/lib/debug/boot/vmlinux-$ARCHVERSION
|
||||
elif [[ "$DISTRO" = ubuntu ]] || [[ "$DISTRO" = debian ]]; then
|
||||
[[ -z "$VMLINUX" ]] && VMLINUX="/usr/lib/debug/boot/vmlinux-$ARCHVERSION"
|
||||
|
||||
if [[ $DISTRO = ubuntu ]]; then
|
||||
if [[ "$DISTRO" = ubuntu ]]; then
|
||||
[[ -e "$VMLINUX" ]] || die "linux-image-$ARCHVERSION-dbgsym not installed"
|
||||
|
||||
elif [[ $DISTRO = debian ]]; then
|
||||
elif [[ "$DISTRO" = debian ]]; then
|
||||
[[ -e "$VMLINUX" ]] || die "linux-image-$ARCHVERSION-dbg not installed"
|
||||
fi
|
||||
|
||||
export PATH=/usr/lib/ccache:$PATH
|
||||
export PATH="/usr/lib/ccache:$PATH"
|
||||
fi
|
||||
|
||||
find_dirs || die "can't find supporting tools"
|
||||
|
||||
if [[ $SKIPGCCCHECK -eq 0 ]]; then
|
||||
if [[ "$SKIPGCCCHECK" -eq 0 ]]; then
|
||||
gcc_version_check || die
|
||||
fi
|
||||
|
||||
@ -498,13 +498,13 @@ if [[ -n "$USERSRCDIR" ]]; then
|
||||
echo "Using source directory at $USERSRCDIR"
|
||||
|
||||
# save vmlinux before it gets removed with mrproper
|
||||
[[ "$VMLINUX" -ef "$SRCDIR"/vmlinux ]] && cp -f "$VMLINUX" $TEMPDIR/vmlinux && VMLINUX=$TEMPDIR/vmlinux
|
||||
[[ "$VMLINUX" -ef "$SRCDIR"/vmlinux ]] && cp -f "$VMLINUX" "$TEMPDIR/vmlinux" && VMLINUX="$TEMPDIR/vmlinux"
|
||||
|
||||
elif [[ -e "$SRCDIR"/.config ]] && [[ -e "$VERSIONFILE" ]] && [[ $(cat "$VERSIONFILE") = $ARCHVERSION ]]; then
|
||||
elif [[ -e "$SRCDIR"/.config ]] && [[ -e "$VERSIONFILE" ]] && [[ "$(cat "$VERSIONFILE")" = "$ARCHVERSION" ]]; then
|
||||
echo "Using cache at $SRCDIR"
|
||||
|
||||
else
|
||||
if [[ $DISTRO = fedora ]] || [[ $DISTRO = rhel ]] || [[ $DISTRO = ol ]] || [[ $DISTRO = centos ]]; then
|
||||
if [[ "$DISTRO" = fedora ]] || [[ "$DISTRO" = rhel ]] || [[ "$DISTRO" = ol ]] || [[ "$DISTRO" = centos ]]; then
|
||||
|
||||
echo "Fedora/Red Hat distribution detected"
|
||||
rpm -q --quiet rpmdevtools || die "rpmdevtools not installed"
|
||||
@ -513,8 +513,8 @@ else
|
||||
|
||||
echo "Downloading kernel source for $ARCHVERSION"
|
||||
if [[ -z "$SRCRPM" ]]; then
|
||||
if [[ $DISTRO = fedora ]]; then
|
||||
wget -P $TEMPDIR http://kojipkgs.fedoraproject.org/packages/kernel/$KVER/$KREL/src/kernel-$KVER-$KREL.src.rpm >> "$LOGFILE" 2>&1 || die
|
||||
if [[ "$DISTRO" = fedora ]]; then
|
||||
wget -P "$TEMPDIR" "http://kojipkgs.fedoraproject.org/packages/kernel/$KVER/$KREL/src/kernel-$KVER-$KREL.src.rpm" >> "$LOGFILE" 2>&1 || die
|
||||
else
|
||||
rpm -q --quiet yum-utils || die "yum-utils not installed"
|
||||
yumdownloader --source --destdir "$TEMPDIR" "kernel-$ARCHVERSION" >> "$LOGFILE" 2>&1 || die
|
||||
@ -536,37 +536,37 @@ else
|
||||
echo "-${ARCHVERSION##*-}" > "$SRCDIR/localversion" || die
|
||||
fi
|
||||
|
||||
echo $ARCHVERSION > "$VERSIONFILE" || die
|
||||
echo "$ARCHVERSION" > "$VERSIONFILE" || die
|
||||
|
||||
elif [[ $DISTRO = ubuntu ]] || [[ $DISTRO = debian ]]; then
|
||||
elif [[ "$DISTRO" = ubuntu ]] || [[ "$DISTRO" = debian ]]; then
|
||||
|
||||
echo "Debian/Ubuntu distribution detected"
|
||||
|
||||
if [[ $DISTRO = ubuntu ]]; then
|
||||
if [[ "$DISTRO" = ubuntu ]]; then
|
||||
|
||||
# url may be changed for a different mirror
|
||||
url="http://archive.ubuntu.com/ubuntu/pool/main/l"
|
||||
sublevel="SUBLEVEL = 0"
|
||||
UBUNTU_KERNEL=1
|
||||
|
||||
elif [[ $DISTRO = debian ]]; then
|
||||
elif [[ "$DISTRO" = debian ]]; then
|
||||
|
||||
# url may be changed for a different mirror
|
||||
url="http://ftp.debian.org/debian/pool/main/l"
|
||||
sublevel="SUBLEVEL ="
|
||||
fi
|
||||
|
||||
pkgname="$(dpkg-query -W -f='${Source}' linux-image-$ARCHVERSION)"
|
||||
pkgver="$(dpkg-query -W -f='${Version}' linux-image-$ARCHVERSION)"
|
||||
pkgname="$(dpkg-query -W -f='${Source}' "linux-image-$ARCHVERSION")"
|
||||
pkgver="$(dpkg-query -W -f='${Version}' "linux-image-$ARCHVERSION")"
|
||||
dscname="${pkgname}_${pkgver}.dsc"
|
||||
|
||||
clean_cache
|
||||
|
||||
cd $TEMPDIR
|
||||
cd "$TEMPDIR"
|
||||
echo "Downloading and unpacking the kernel source for $ARCHVERSION"
|
||||
# Download source deb pkg
|
||||
(dget -u "$url/${pkgname}/${dscname}" 2>&1) >> "$LOGFILE" || die "dget: Could not fetch/unpack $url/${pkgname}/${dscname}"
|
||||
mv ${pkgname}-$KVER "$SRCDIR" || die
|
||||
mv "${pkgname}-$KVER" "$SRCDIR" || die
|
||||
cp "/boot/config-${ARCHVERSION}" "$SRCDIR/.config" || die
|
||||
if [[ "$ARCHVERSION" == *-* ]]; then
|
||||
echo "-${ARCHVERSION#*-}" > "$SRCDIR/localversion" || die
|
||||
@ -574,7 +574,7 @@ else
|
||||
# for some reason the Ubuntu kernel versions don't follow the
|
||||
# upstream SUBLEVEL; they are always at SUBLEVEL 0
|
||||
sed -i "s/^SUBLEVEL.*/${sublevel}/" "$SRCDIR/Makefile" || die
|
||||
echo $ARCHVERSION > "$VERSIONFILE" || die
|
||||
echo "$ARCHVERSION" > "$VERSIONFILE" || die
|
||||
|
||||
else
|
||||
die "Unsupported distribution"
|
||||
@ -582,9 +582,9 @@ else
|
||||
fi
|
||||
|
||||
# save .config before it gets removed with mrproper
|
||||
[[ -z $CONFIGFILE ]] && CONFIGFILE="$SRCDIR"/.config
|
||||
[[ -z "$CONFIGFILE" ]] && CONFIGFILE="$SRCDIR"/.config
|
||||
[[ ! -e "$CONFIGFILE" ]] && die "can't find config file"
|
||||
[[ "$CONFIGFILE" -ef "$SRCDIR"/.config ]] && cp -f "$CONFIGFILE" $TEMPDIR && CONFIGFILE="$TEMPDIR"/.config
|
||||
[[ "$CONFIGFILE" -ef "$SRCDIR"/.config ]] && cp -f "$CONFIGFILE" "$TEMPDIR" && CONFIGFILE="$TEMPDIR"/.config
|
||||
|
||||
# Build variables - Set some defaults, then adjust features
|
||||
# according to .config and kernel version
|
||||
@ -596,10 +596,10 @@ KPATCH_MODULE=true
|
||||
grep -q "CONFIG_DEBUG_INFO=y" "$CONFIGFILE" || die "kernel doesn't have 'CONFIG_DEBUG_INFO' enabled"
|
||||
if grep -q "CONFIG_LIVEPATCH=y" "$CONFIGFILE"; then
|
||||
# The kernel supports livepatch.
|
||||
if version_gte ${ARCHVERSION//-*/} 4.7.0; then
|
||||
if version_gte "${ARCHVERSION//-*/}" 4.7.0; then
|
||||
# Use new .klp.rela. sections
|
||||
KPATCH_MODULE=false
|
||||
if version_gte ${ARCHVERSION//-*/} 4.9.0; then
|
||||
if version_gte "${ARCHVERSION//-*/}" 4.9.0; then
|
||||
KPATCH_LDFLAGS="--unique=.parainstructions --unique=.altinstructions"
|
||||
fi
|
||||
fi
|
||||
@ -626,7 +626,7 @@ remove_patches
|
||||
|
||||
cp -LR "$DATADIR/patch" "$TEMPDIR" || die
|
||||
|
||||
if [[ $ARCH = "ppc64le" ]]; then
|
||||
if [[ "$ARCH" = "ppc64le" ]]; then
|
||||
ARCH_KCFLAGS="-mcmodel=large"
|
||||
fi
|
||||
|
||||
@ -645,7 +645,7 @@ CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " make "-j$CPUS" $TARGETS >> "$LOGFILE" 2>&1
|
||||
echo "Building patched kernel"
|
||||
apply_patches
|
||||
mkdir -p "$TEMPDIR/orig" "$TEMPDIR/patched"
|
||||
KPATCH_GCC_TEMPDIR=$TEMPDIR
|
||||
KPATCH_GCC_TEMPDIR="$TEMPDIR"
|
||||
export KPATCH_GCC_TEMPDIR
|
||||
CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " \
|
||||
KBUILD_MODPOST_WARN=1 \
|
||||
@ -660,7 +660,7 @@ fi
|
||||
|
||||
for i in $(cat "$TEMPDIR/changed_objs")
|
||||
do
|
||||
mkdir -p "$TEMPDIR/patched/$(dirname $i)" || die
|
||||
mkdir -p "$TEMPDIR/patched/$(dirname "$i")" || die
|
||||
cp -f "$SRCDIR/$i" "$TEMPDIR/patched/$i" || die
|
||||
done
|
||||
|
||||
@ -669,9 +669,9 @@ echo "Extracting new and modified ELF sections"
|
||||
# - For single input .patch, use the patch filename
|
||||
# - For multiple input .patches, use "patch"
|
||||
# - Prefix with "kpatch" or "livepatch" accordingly
|
||||
if [[ -z $MODNAME ]] ; then
|
||||
if [[ ${#PATCH_LIST[@]} -eq 1 ]]; then
|
||||
MODNAME=$(basename "${PATCH_LIST[0]}")
|
||||
if [[ -z "$MODNAME" ]] ; then
|
||||
if [[ "${#PATCH_LIST[@]}" -eq 1 ]]; then
|
||||
MODNAME="$(basename "${PATCH_LIST[0]}")"
|
||||
if [[ "$MODNAME" =~ \.patch$ ]] || [[ "$MODNAME" =~ \.diff$ ]]; then
|
||||
MODNAME="${MODNAME%.*}"
|
||||
fi
|
||||
@ -679,13 +679,13 @@ if [[ -z $MODNAME ]] ; then
|
||||
MODNAME="patch"
|
||||
fi
|
||||
|
||||
if $KPATCH_MODULE; then
|
||||
if "$KPATCH_MODULE"; then
|
||||
MODNAME="kpatch-$MODNAME"
|
||||
else
|
||||
MODNAME="livepatch-$MODNAME"
|
||||
fi
|
||||
|
||||
MODNAME=$(module_name_string "$MODNAME")
|
||||
MODNAME="$(module_name_string "$MODNAME")"
|
||||
fi
|
||||
FILES="$(cat "$TEMPDIR/changed_objs")"
|
||||
cd "$TEMPDIR"
|
||||
@ -697,55 +697,55 @@ for i in $FILES; do
|
||||
# In RHEL 7 based kernels, copy_user_64.o misuses the .fixup section,
|
||||
# which confuses create-diff-object. It's fine to skip it, it's an
|
||||
# assembly file anyway.
|
||||
[[ $DISTRO = rhel ]] || [[ $DISTRO = centos ]] || [[ $DISTRO = ol ]] && \
|
||||
[[ $i = arch/x86/lib/copy_user_64.o ]] && continue
|
||||
[[ "$DISTRO" = rhel ]] || [[ "$DISTRO" = centos ]] || [[ "$DISTRO" = ol ]] && \
|
||||
[[ "$i" = arch/x86/lib/copy_user_64.o ]] && continue
|
||||
|
||||
[[ $i = usr/initramfs_data.o ]] && continue
|
||||
[[ "$i" = usr/initramfs_data.o ]] && continue
|
||||
|
||||
mkdir -p "output/$(dirname $i)"
|
||||
mkdir -p "output/$(dirname "$i")"
|
||||
cd "$SRCDIR"
|
||||
find_kobj $i
|
||||
if [[ $KOBJFILE = vmlinux ]]; then
|
||||
KOBJFILE=$VMLINUX
|
||||
find_kobj "$i"
|
||||
if [[ "$KOBJFILE" = vmlinux ]]; then
|
||||
KOBJFILE="$VMLINUX"
|
||||
else
|
||||
KOBJFILE="$TEMPDIR/module/$KOBJFILE"
|
||||
fi
|
||||
cd $TEMPDIR
|
||||
cd "$TEMPDIR"
|
||||
if [[ -e "orig/$i" ]]; then
|
||||
# create-diff-object orig.o patched.o kernel-object output.o Module.symvers patch-mod-name
|
||||
"$TOOLSDIR"/create-diff-object "orig/$i" "patched/$i" "$KOBJFILE" \
|
||||
"output/$i" "$SRCDIR/Module.symvers" "${MODNAME//-/_}" 2>&1 |tee -a "$LOGFILE"
|
||||
check_pipe_status create-diff-object
|
||||
# create-diff-object returns 3 if no functional change is found
|
||||
[[ $rc -eq 0 ]] || [[ $rc -eq 3 ]] || ERROR=$(expr $ERROR "+" 1)
|
||||
if [[ $rc -eq 0 ]]; then
|
||||
[[ -n $ERROR_IF_DIFF ]] && die $ERROR_IF_DIFF
|
||||
[[ "$rc" -eq 0 ]] || [[ "$rc" -eq 3 ]] || ERROR="$(expr $ERROR "+" 1)"
|
||||
if [[ "$rc" -eq 0 ]]; then
|
||||
[[ -n "$ERROR_IF_DIFF" ]] && die "$ERROR_IF_DIFF"
|
||||
CHANGED=1
|
||||
objnames[${#objnames[@]}]=$KOBJFILE
|
||||
objnames[${#objnames[@]}]="$KOBJFILE"
|
||||
fi
|
||||
else
|
||||
cp -f "patched/$i" "output/$i"
|
||||
objnames[${#objnames[@]}]=$KOBJFILE
|
||||
objnames[${#objnames[@]}]="$KOBJFILE"
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $ERROR -ne 0 ]]; then
|
||||
if [[ "$ERROR" -ne 0 ]]; then
|
||||
die "$ERROR error(s) encountered"
|
||||
fi
|
||||
|
||||
if [[ $CHANGED -eq 0 ]]; then
|
||||
if [[ "$CHANGED" -eq 0 ]]; then
|
||||
die "no functional changes found"
|
||||
fi
|
||||
|
||||
echo -n "Patched objects:"
|
||||
for i in $(echo "${objnames[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ')
|
||||
do
|
||||
echo -n " $(basename $i)"
|
||||
echo -n " $(basename "$i")"
|
||||
done
|
||||
echo
|
||||
|
||||
export KCFLAGS="-I$DATADIR/patch $ARCH_KCFLAGS"
|
||||
if $KPATCH_MODULE; then
|
||||
if "$KPATCH_MODULE"; then
|
||||
export KCPPFLAGS="-D__KPATCH_MODULE__"
|
||||
fi
|
||||
|
||||
@ -753,25 +753,25 @@ echo "Building patch module: $MODNAME.ko"
|
||||
cd "$SRCDIR"
|
||||
make prepare >> "$LOGFILE" 2>&1 || die
|
||||
|
||||
if [[ ! -z $UBUNTU_KERNEL ]]; then
|
||||
if [[ ! -z "$UBUNTU_KERNEL" ]]; then
|
||||
# UBUNTU: add UTS_UBUNTU_RELEASE_ABI to utsrelease.h after regenerating it
|
||||
UBUNTU_ABI=${ARCHVERSION#*-}
|
||||
UBUNTU_ABI=${UBUNTU_ABI%-*}
|
||||
UBUNTU_ABI="${ARCHVERSION#*-}"
|
||||
UBUNTU_ABI="${UBUNTU_ABI%-*}"
|
||||
echo "#define UTS_UBUNTU_RELEASE_ABI "$UBUNTU_ABI"" >> "$SRCDIR"/include/generated/utsrelease.h
|
||||
fi
|
||||
|
||||
cd "$TEMPDIR/output"
|
||||
ld -r $KPATCH_LDFLAGS -o ../patch/tmp_output.o $(find . -name "*.o") >> "$LOGFILE" 2>&1 || die
|
||||
|
||||
if $KPATCH_MODULE; then
|
||||
if "$KPATCH_MODULE"; then
|
||||
# Add .kpatch.checksum for kpatch script
|
||||
md5sum ../patch/tmp_output.o | awk '{printf "%s\0", $1}' > checksum.tmp || die
|
||||
objcopy --add-section .kpatch.checksum=checksum.tmp --set-section-flags .kpatch.checksum=alloc,load,contents,readonly ../patch/tmp_output.o || die
|
||||
rm -f checksum.tmp
|
||||
"$TOOLSDIR"/create-kpatch-module $TEMPDIR/patch/tmp_output.o $TEMPDIR/patch/output.o 2>&1 |tee -a "$LOGFILE"
|
||||
"$TOOLSDIR"/create-kpatch-module "$TEMPDIR"/patch/tmp_output.o "$TEMPDIR"/patch/output.o 2>&1 |tee -a "$LOGFILE"
|
||||
check_pipe_status create-kpatch-module
|
||||
else
|
||||
cp $TEMPDIR/patch/tmp_output.o $TEMPDIR/patch/output.o || die
|
||||
cp "$TEMPDIR"/patch/tmp_output.o "$TEMPDIR"/patch/output.o || die
|
||||
fi
|
||||
|
||||
cd "$TEMPDIR/patch"
|
||||
@ -781,12 +781,12 @@ KBUILD_EXTRA_SYMBOLS="$KBUILD_EXTRA_SYMBOLS" \
|
||||
KPATCH_LDFLAGS="$KPATCH_LDFLAGS" \
|
||||
make >> "$LOGFILE" 2>&1 || die
|
||||
|
||||
if ! $KPATCH_MODULE; then
|
||||
if ! "$KPATCH_MODULE"; then
|
||||
if [[ -z "$KPATCH_LDFLAGS" ]]; then
|
||||
extra_flags="--no-klp-arch-sections"
|
||||
fi
|
||||
cp $TEMPDIR/patch/$MODNAME.ko $TEMPDIR/patch/tmp.ko || die
|
||||
"$TOOLSDIR"/create-klp-module $extra_flags $TEMPDIR/patch/tmp.ko $TEMPDIR/patch/$MODNAME.ko 2>&1 |tee -a "$LOGFILE"
|
||||
cp "$TEMPDIR/patch/$MODNAME.ko" "$TEMPDIR/patch/tmp.ko" || die
|
||||
"$TOOLSDIR"/create-klp-module $extra_flags "$TEMPDIR/patch/tmp.ko" "$TEMPDIR/patch/$MODNAME.ko" 2>&1 |tee -a "$LOGFILE"
|
||||
check_pipe_status create-klp-module
|
||||
fi
|
||||
|
||||
|
@ -14,13 +14,13 @@ declare -a args=("$@")
|
||||
if [[ "$TOOLCHAINCMD" = "gcc" ]] ; then
|
||||
while [ "$#" -gt 0 ]; do
|
||||
if [ "$1" = "-o" ]; then
|
||||
obj=$2
|
||||
obj="$2"
|
||||
|
||||
# skip copying the temporary .o files created by
|
||||
# recordmcount.pl
|
||||
[[ $obj = */.tmp_mc_*.o ]] && break;
|
||||
[[ "$obj" = */.tmp_mc_*.o ]] && break;
|
||||
|
||||
[[ $obj = */.tmp_*.o ]] && obj=${obj/.tmp_/}
|
||||
[[ "$obj" = */.tmp_*.o ]] && obj="${obj/.tmp_/}"
|
||||
case "$obj" in
|
||||
*.mod.o|\
|
||||
*built-in.o|\
|
||||
@ -43,8 +43,8 @@ if [[ "$TOOLCHAINCMD" = "gcc" ]] ; then
|
||||
break
|
||||
;;
|
||||
*.o)
|
||||
mkdir -p "$KPATCH_GCC_TEMPDIR/orig/$(dirname $obj)"
|
||||
[[ -e $obj ]] && cp -f "$obj" "$KPATCH_GCC_TEMPDIR/orig/$obj"
|
||||
mkdir -p "$KPATCH_GCC_TEMPDIR/orig/$(dirname "$obj")"
|
||||
[[ -e "$obj" ]] && cp -f "$obj" "$KPATCH_GCC_TEMPDIR/orig/$obj"
|
||||
echo "$obj" >> "$KPATCH_GCC_TEMPDIR/changed_objs"
|
||||
break
|
||||
;;
|
||||
@ -58,10 +58,10 @@ if [[ "$TOOLCHAINCMD" = "gcc" ]] ; then
|
||||
elif [[ "$TOOLCHAINCMD" = "ld" ]] ; then
|
||||
while [ "$#" -gt 0 ]; do
|
||||
if [ "$1" = "-o" ]; then
|
||||
obj=$2
|
||||
obj="$2"
|
||||
case "$obj" in
|
||||
*.ko)
|
||||
mkdir -p "$KPATCH_GCC_TEMPDIR/module/$(dirname $obj)"
|
||||
mkdir -p "$KPATCH_GCC_TEMPDIR/module/$(dirname "$obj")"
|
||||
cp -f "$obj" "$KPATCH_GCC_TEMPDIR/module/$obj"
|
||||
break
|
||||
;;
|
||||
|
110
kpatch/kpatch
110
kpatch/kpatch
@ -24,7 +24,7 @@
|
||||
# displaying information about kernel patch modules installed on the system.
|
||||
|
||||
INSTALLDIR=/var/lib/kpatch
|
||||
SCRIPTDIR="$(readlink -f $(dirname $(type -p $0)))"
|
||||
SCRIPTDIR="$(readlink -f "$(dirname "$(type -p "$0")")")"
|
||||
VERSION="0.4.0"
|
||||
|
||||
# Livepatch is built into the kernel, if it's not present
|
||||
@ -74,14 +74,14 @@ __find_module () {
|
||||
MODULE="$1"
|
||||
[[ -f "$MODULE" ]] && return
|
||||
|
||||
MODULE=$INSTALLDIR/$(uname -r)/"$1"
|
||||
MODULE="$INSTALLDIR/$(uname -r)/$1"
|
||||
[[ -f "$MODULE" ]] && return
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
mod_name () {
|
||||
MODNAME="$(basename $1)"
|
||||
MODNAME="$(basename "$1")"
|
||||
MODNAME="${MODNAME%.ko}"
|
||||
MODNAME="${MODNAME//-/_}"
|
||||
}
|
||||
@ -93,9 +93,9 @@ find_module () {
|
||||
mod_name "$MODULE"
|
||||
return
|
||||
else
|
||||
for i in $INSTALLDIR/$(uname -r)/*; do
|
||||
for i in "$INSTALLDIR/$(uname -r)"/*; do
|
||||
mod_name "$i"
|
||||
if [[ $MODNAME == $arg ]]; then
|
||||
if [[ "$MODNAME" == "$arg" ]]; then
|
||||
MODULE="$i"
|
||||
return
|
||||
fi
|
||||
@ -129,19 +129,19 @@ core_loaded () {
|
||||
}
|
||||
|
||||
get_module_name () {
|
||||
echo $(readelf -p .gnu.linkonce.this_module $1 | grep '\[.*\]' | awk '{print $3}')
|
||||
echo "$(readelf -p .gnu.linkonce.this_module "$1" | grep '\[.*\]' | awk '{print $3}')"
|
||||
}
|
||||
|
||||
verify_module_checksum () {
|
||||
modname=$(get_module_name $1)
|
||||
[[ -z $modname ]] && return 1
|
||||
modname="$(get_module_name "$1")"
|
||||
[[ -z "$modname" ]] && return 1
|
||||
|
||||
checksum=$(readelf -p .kpatch.checksum $1 | grep '\[.*\]' | awk '{print $3}')
|
||||
checksum="$(readelf -p .kpatch.checksum "$1" | grep '\[.*\]' | awk '{print $3}')"
|
||||
|
||||
# Fail checksum match only if both exist and diverge
|
||||
if [[ ! -z $checksum ]] && [[ -e "$SYSFS/${modname}/checksum" ]] ; then
|
||||
sysfs_checksum=$(cat $SYSFS/${modname}/checksum)
|
||||
[[ $checksum == $sysfs_checksum ]] || return 1
|
||||
if [[ ! -z "$checksum" ]] && [[ -e "$SYSFS/${modname}/checksum" ]] ; then
|
||||
sysfs_checksum="$(cat "$SYSFS/${modname}/checksum")"
|
||||
[[ "$checksum" == "$sysfs_checksum" ]] || return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
@ -160,13 +160,13 @@ load_module () {
|
||||
fi
|
||||
fi
|
||||
|
||||
local modname=$(get_module_name $module)
|
||||
local modname="$(get_module_name "$module")"
|
||||
local moddir="$SYSFS/$modname"
|
||||
if [[ -d $moddir ]] ; then
|
||||
if [[ $(cat "${moddir}/enabled") -eq 0 ]]; then
|
||||
if verify_module_checksum $module; then # same checksum
|
||||
if [[ -d "$moddir" ]] ; then
|
||||
if [[ "$(cat "${moddir}/enabled")" -eq 0 ]]; then
|
||||
if verify_module_checksum "$module"; then # same checksum
|
||||
echo "module already loaded, re-enabling"
|
||||
echo 1 > ${moddir}/enabled || die "failed to re-enable module $modname"
|
||||
echo 1 > "${moddir}/enabled" || die "failed to re-enable module $modname"
|
||||
return
|
||||
else
|
||||
die "error: cannot re-enable patch module $modname, cannot verify checksum match"
|
||||
@ -179,10 +179,10 @@ load_module () {
|
||||
echo "loading patch module: $module"
|
||||
local i=0
|
||||
while true; do
|
||||
out=$(insmod "$module" 2>&1)
|
||||
[[ -z $out ]] && break
|
||||
echo $out 1>&2
|
||||
[[ ! $out =~ "Device or resource busy" ]] &&
|
||||
out="$(insmod "$module" 2>&1)"
|
||||
[[ -z "$out" ]] && break
|
||||
echo "$out" 1>&2
|
||||
[[ ! "$out" =~ "Device or resource busy" ]] &&
|
||||
die "failed to load module $module"
|
||||
|
||||
# "Device or resource busy" means the activeness safety check
|
||||
@ -205,20 +205,20 @@ unload_module () {
|
||||
PATCH="${PATCH%.ko}"
|
||||
ENABLED="$SYSFS/$PATCH/enabled"
|
||||
[[ -e "$ENABLED" ]] || die "patch module $1 is not loaded"
|
||||
if [[ $(cat "$ENABLED") -eq 1 ]]; then
|
||||
if [[ "$(cat "$ENABLED")" -eq 1 ]]; then
|
||||
echo "disabling patch module: $PATCH"
|
||||
echo 0 > $ENABLED || die "can't disable $PATCH"
|
||||
echo 0 > "$ENABLED" || die "can't disable $PATCH"
|
||||
fi
|
||||
|
||||
echo "unloading patch module: $PATCH"
|
||||
# ignore any error here because rmmod can fail if the module used
|
||||
# KPATCH_FORCE_UNSAFE.
|
||||
rmmod $PATCH 2> /dev/null || return 0
|
||||
rmmod "$PATCH" 2> /dev/null || return 0
|
||||
}
|
||||
|
||||
get_module_version() {
|
||||
MODVER=$(modinfo -F vermagic "$1") || return 1
|
||||
MODVER=${MODVER/ */}
|
||||
MODVER="$(modinfo -F vermagic "$1")" || return 1
|
||||
MODVER="${MODVER/ */}"
|
||||
}
|
||||
|
||||
unset MODULE
|
||||
@ -228,7 +228,7 @@ case "$1" in
|
||||
[[ "$#" -ne 2 ]] && usage
|
||||
case "$2" in
|
||||
"--all")
|
||||
for i in "$INSTALLDIR"/$(uname -r)/*.ko; do
|
||||
for i in "$INSTALLDIR/$(uname -r)"/*.ko; do
|
||||
[[ -e "$i" ]] || continue
|
||||
load_module "$i" || die "failed to load module $i"
|
||||
done
|
||||
@ -245,26 +245,26 @@ case "$1" in
|
||||
[[ "$#" -ne 2 ]] && usage
|
||||
case "$2" in
|
||||
"--all")
|
||||
for module in $SYSFS/*; do
|
||||
[[ -e $module ]] || continue
|
||||
unload_module $(basename $module) || die "failed to unload module $module"
|
||||
for module in "$SYSFS"/*; do
|
||||
[[ -e "$module" ]] || continue
|
||||
unload_module "$(basename "$module")" || die "failed to unload module $module"
|
||||
done
|
||||
;;
|
||||
*)
|
||||
unload_module "$(basename $2)" || die "failed to unload module $2"
|
||||
unload_module "$(basename "$2")" || die "failed to unload module $2"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
||||
"install")
|
||||
KVER=$(uname -r)
|
||||
KVER="$(uname -r)"
|
||||
shift
|
||||
options=$(getopt -o k: -l "kernel-version:" -- "$@") || die "getopt failed"
|
||||
options="$(getopt -o k: -l "kernel-version:" -- "$@")" || die "getopt failed"
|
||||
eval set -- "$options"
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-k|--kernel-version)
|
||||
KVER=$2
|
||||
KVER="$2"
|
||||
shift
|
||||
;;
|
||||
--)
|
||||
@ -276,75 +276,75 @@ case "$1" in
|
||||
done
|
||||
|
||||
[[ ! -e "$PATCH" ]] && die "$PATCH doesn't exist"
|
||||
[[ ${PATCH: -3} == ".ko" ]] || die "$PATCH isn't a .ko file"
|
||||
[[ "${PATCH: -3}" == ".ko" ]] || die "$PATCH isn't a .ko file"
|
||||
|
||||
get_module_version "$PATCH" || die "modinfo failed"
|
||||
[[ $KVER != $MODVER ]] && die "invalid module version $MODVER for kernel $KVER"
|
||||
[[ "$KVER" != "$MODVER" ]] && die "invalid module version $MODVER for kernel $KVER"
|
||||
|
||||
[[ -e $INSTALLDIR/$KVER/$(basename "$PATCH") ]] && die "$PATCH is already installed"
|
||||
[[ -e "$INSTALLDIR/$KVER/$(basename "$PATCH")" ]] && die "$PATCH is already installed"
|
||||
|
||||
echo "installing $PATCH ($KVER)"
|
||||
mkdir -p $INSTALLDIR/$KVER || die "failed to create install directory"
|
||||
cp -f "$PATCH" $INSTALLDIR/$KVER || die "failed to install module $PATCH"
|
||||
mkdir -p "$INSTALLDIR/$KVER" || die "failed to create install directory"
|
||||
cp -f "$PATCH" "$INSTALLDIR/$KVER" || die "failed to install module $PATCH"
|
||||
systemctl enable kpatch.service
|
||||
;;
|
||||
|
||||
"uninstall")
|
||||
KVER=$(uname -r)
|
||||
KVER="$(uname -r)"
|
||||
shift
|
||||
options=$(getopt -o k: -l "kernel-version:" -- "$@") || die "getopt failed"
|
||||
options="$(getopt -o k: -l "kernel-version:" -- "$@")" || die "getopt failed"
|
||||
eval set -- "$options"
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-k|--kernel-version)
|
||||
KVER=$2
|
||||
KVER="$2"
|
||||
shift
|
||||
;;
|
||||
--)
|
||||
[[ -z "$2" ]] && die "no module file specified"
|
||||
PATCH="$2"
|
||||
[[ "$PATCH" != $(basename "$PATCH") ]] && die "please supply patch module name without path"
|
||||
[[ "$PATCH" != "$(basename "$PATCH")" ]] && die "please supply patch module name without path"
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
MODULE=$INSTALLDIR/$KVER/"$PATCH"
|
||||
MODULE="$INSTALLDIR/$KVER/$PATCH"
|
||||
if [[ ! -f "$MODULE" ]]; then
|
||||
mod_name "$PATCH"
|
||||
PATCHNAME=$MODNAME
|
||||
for i in $INSTALLDIR/$KVER/*; do
|
||||
PATCHNAME="$MODNAME"
|
||||
for i in "$INSTALLDIR/$KVER"/*; do
|
||||
mod_name "$i"
|
||||
if [[ $MODNAME == $PATCHNAME ]]; then
|
||||
if [[ "$MODNAME" == "$PATCHNAME" ]]; then
|
||||
MODULE="$i"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
[[ ! -e $MODULE ]] && die "$PATCH is not installed for kernel $KVER"
|
||||
[[ ! -e "$MODULE" ]] && die "$PATCH is not installed for kernel $KVER"
|
||||
|
||||
|
||||
echo "uninstalling $PATCH ($KVER)"
|
||||
rm -f $MODULE || die "failed to uninstall module $PATCH"
|
||||
rm -f "$MODULE" || die "failed to uninstall module $PATCH"
|
||||
;;
|
||||
|
||||
"list")
|
||||
[[ "$#" -ne 1 ]] && usage
|
||||
echo "Loaded patch modules:"
|
||||
for module in $SYSFS/*; do
|
||||
if [[ -e $module ]] && [[ $(cat $module/enabled) -eq 1 ]]; then
|
||||
echo $(basename "$module")
|
||||
for module in "$SYSFS"/*; do
|
||||
if [[ -e "$module" ]] && [[ "$(cat "$module/enabled")" -eq 1 ]]; then
|
||||
echo "$(basename "$module")"
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
echo "Installed patch modules:"
|
||||
for kdir in $INSTALLDIR/*; do
|
||||
for kdir in "$INSTALLDIR"/*; do
|
||||
[[ -e "$kdir" ]] || continue
|
||||
for module in $kdir/*; do
|
||||
for module in "$kdir"/*; do
|
||||
[[ -e "$module" ]] || continue
|
||||
mod_name "$module"
|
||||
echo "$MODNAME ($(basename $kdir))"
|
||||
echo "$MODNAME ($(basename "$kdir"))"
|
||||
done
|
||||
done
|
||||
;;
|
||||
|
Loading…
Reference in New Issue
Block a user