Blob Blame History Raw
From 9eed5d4bac0b43372d98572d923ca84e091c8982 Mon Sep 17 00:00:00 2001
Message-Id: <9eed5d4bac0b43372d98572d923ca84e091c8982.1508328327.git.jpoimboe@redhat.com>
From: Josh Poimboeuf <jpoimboe@redhat.com>
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 <jpoimboe@redhat.com>
---
 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