From 9eed5d4bac0b43372d98572d923ca84e091c8982 Mon Sep 17 00:00:00 2001 Message-Id: <9eed5d4bac0b43372d98572d923ca84e091c8982.1508328327.git.jpoimboe@redhat.com> From: Josh Poimboeuf Date: Mon, 9 Oct 2017 09:04:46 -0500 Subject: [PATCH] kpatch: add ABI backwards compatibility When running a kernel for a long period of time without rebooting, it's possible that newer versions of the kpatch script may get installed. So new versions of the kpatch script need to support old versions of kpatch.ko. Signed-off-by: Josh Poimboeuf --- kpatch/kpatch | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/kpatch/kpatch b/kpatch/kpatch index ef36087..5998fbc 100755 --- a/kpatch/kpatch +++ b/kpatch/kpatch @@ -27,14 +27,6 @@ INSTALLDIR=/var/lib/kpatch SCRIPTDIR="$(readlink -f $(dirname $(type -p $0)))" VERSION="0.4.0" -# Livepatch is built into the kernel, if it's not present -# we must use kpatch core module. -if [[ -e /sys/kernel/livepatch ]] ; then - SYSFS="/sys/kernel/livepatch" -else - SYSFS="/sys/kernel/kpatch" -fi - usage_cmd() { printf ' %-20s\n %s\n' "$1" "$2" >&2 } @@ -132,6 +124,23 @@ get_module_name () { echo $(readelf -p .gnu.linkonce.this_module $1 | grep '\[.*\]' | awk '{print $3}') } +init_sysfs_var() { + # If the kernel is configured with CONFIG_LIVEPATCH, use that. + # Otherwise, use the kpatch core module (kpatch.ko). + if [[ -e /sys/kernel/livepatch ]] ; then + # livepatch ABI + SYSFS="/sys/kernel/livepatch" + + elif [[ -e /sys/kernel/kpatch/patches ]] ; then + # kpatch pre-0.4 ABI + SYSFS="/sys/kernel/kpatch/patches" + + else + # kpatch 0.4 ABI + SYSFS="/sys/kernel/kpatch" + fi +} + verify_module_checksum () { modname=$(get_module_name $1) [[ -z $modname ]] && return 1 @@ -158,6 +167,10 @@ load_module () { echo "loading core module: $COREMOD" insmod "$COREMOD" || die "failed to load core module" fi + + # Now that the core module has been loaded, set $SYSFS to the + # correct value based on the loaded core module's ABI. + init_sysfs_var fi local modname=$(get_module_name $module) @@ -222,6 +235,12 @@ get_module_version() { } unset MODULE + +# Initialize the $SYSFS var. This only works if the core module has been +# loaded. Otherwise, the value of $SYSFS doesn't matter at this point anyway, +# and we'll have to call this function again after loading it. +init_sysfs_var + [[ "$#" -lt 1 ]] && usage case "$1" in "load") -- 2.13.6