livepatch: kpatch: Add the config file to customize the load order

Support loading livepatched kernel modules as the specific order instead
of the original way which was alphabetical order.

TestPlan:
PASS: build-pkgs -c -p kpatch
PASS: build-image
PASS: Install the iso image both for std and lowlatency then login
PASS: 'kpatch install [rt-]livepatch-meminfo-string-example.ko' and
      'kpatch load --all' with adding the content in the config file
      /etc/kpatch-load.conf

Story: 2009221
Task: 44580

Signed-off-by: Zhixiong Chi <zhixiong.chi@windriver.com>
Change-Id: Ib4ec9d3d43d95afc2e381614da0cd5c45c9f1b02
This commit is contained in:
Zhixiong Chi 2022-10-30 22:53:19 -07:00
parent 6c1979d4a4
commit 5446b0a065
3 changed files with 161 additions and 0 deletions

View File

@ -2,4 +2,5 @@ usr/sbin/kpatch
usr/share/man/man1/kpatch.1*
usr/lib/systemd/system/kpatch.service lib/systemd/system/
etc/init/kpatch.conf
etc/kpatch-load.conf
var/lib/kpatch/*

View File

@ -0,0 +1,159 @@
From 458e83d02810ee2697b509bf4ea30c570a5151ed Mon Sep 17 00:00:00 2001
From: Zhixiong Chi <zhixiong.chi@windriver.com>
Date: Wed, 26 Oct 2022 00:58:41 -0700
Subject: [PATCH] kpatch: Support the customized order for module load
With adding the configfile, now we can use customized order to load
the livepatched kernel modules instead of the original alphabetical
order when the command 'kpatch load --all' is executed.
If the configfile is empty, then the behavior is still to load the
module as the original style(alphabetical order).
The first column in the config file is the module to be loaded.
The second column is the dependency which must be loaded first, and
it can be ignored if the dependency is null.
Signed-off-by: Zhixiong Chi <zhixiong.chi@windriver.com>
---
Makefile.inc | 1 +
contrib/Makefile | 3 ++
contrib/kpatch-load.conf | 5 ++++
kpatch/kpatch | 59 ++++++++++++++++++++++++++++++++++++----
4 files changed, 63 insertions(+), 5 deletions(-)
create mode 100644 contrib/kpatch-load.conf
diff --git a/Makefile.inc b/Makefile.inc
index 259127c..8280182 100644
--- a/Makefile.inc
+++ b/Makefile.inc
@@ -15,6 +15,7 @@ LIBEXECDIR = $(DESTDIR)$(PREFIX)/$(LIBEXEC)/kpatch
DATADIR = $(DESTDIR)$(PREFIX)/share/kpatch
MANDIR = $(DESTDIR)$(PREFIX)/share/man/man1
SYSTEMDDIR = $(DESTDIR)$(PREFIX)/lib/systemd/system
+SYSCONFDIR = $(DESTDIR)/etc
UPSTARTDIR = $(DESTDIR)/etc/init
LOCALSTATEDIR = $(DESTDIR)/var
diff --git a/contrib/Makefile b/contrib/Makefile
index 0b0eeeb..1e43b39 100644
--- a/contrib/Makefile
+++ b/contrib/Makefile
@@ -9,9 +9,12 @@ install: all
$(INSTALL) -d $(UPSTARTDIR)
$(INSTALL) -m 0644 kpatch.conf $(UPSTARTDIR)
sed -i 's~PREFIX~$(PREFIX)~' $(UPSTARTDIR)/kpatch.conf
+ $(INSTALL) -d $(SYSCONFDIR)
+ $(INSTALL) -m 0644 kpatch-load.conf $(SYSCONFDIR)
uninstall:
$(RM) $(SYSTEMDDIR)/kpatch.service
$(RM) $(UPSTARTDIR)/kpatch.conf
+ $(RM) $(SYSCONFDIR)/kpatch-load.conf
clean:
diff --git a/contrib/kpatch-load.conf b/contrib/kpatch-load.conf
new file mode 100644
index 0000000..fdaebb0
--- /dev/null
+++ b/contrib/kpatch-load.conf
@@ -0,0 +1,5 @@
+# Please write the whole filename including .ko
+# InstallMod Dependmod1,Dependmod2
+# eg: abc.ko
+# eg: abc.ko def.ko
+# eg: abc.ko def.ko,ghi.ko
diff --git a/kpatch/kpatch b/kpatch/kpatch
index e4624f5..4b65892 100755
--- a/kpatch/kpatch
+++ b/kpatch/kpatch
@@ -23,7 +23,8 @@
# This is the kpatch user script that manages installing, loading, and
# displaying information about kernel patch modules installed on the system.
-INSTALLDIR=/var/lib/kpatch
+INSTALLDIR="/var/lib/kpatch"
+CONFIGFILE="/etc/kpatch-load.conf"
SCRIPTDIR="$(readlink -f "$(dirname "$(type -p "$0")")")"
VERSION="0.9.5"
POST_ENABLE_WAIT=15 # seconds
@@ -67,6 +68,15 @@ warn() {
echo "kpatch: $*" >&2
}
+warn_load() {
+ local tty_specific_colour_on tty_specific_colour_off
+ if [[ -t 2 ]] ; then
+ tty_specific_colour_on=$'\033[1;33m'
+ tty_specific_colour_off=$'\033[0m'
+ fi
+ echo "${tty_specific_colour_on}kpatch: $*${tty_specific_colour_off}" >&2
+}
+
die() {
warn "$@"
exit 1
@@ -443,6 +453,18 @@ get_module_version() {
MODVER="${MODVER/ */}"
}
+is_installed() {
+ local RDEPS=$1
+ for item in "${RDEPS[@]}"; do
+ item="${item%*.ko}"
+ if ! lsmod | awk '{print $1}' | grep -q "${item//-/_}"; then
+ warn_load "Module Dependency: ${item} Is Not Loaded!"
+ return 1
+ fi
+ done
+ return 0
+}
+
unset MODULE
# Initialize the $SYSFS var. This only works if the core module has been
@@ -456,10 +478,37 @@ case "$1" in
[[ "$#" -ne 2 ]] && usage
case "$2" in
"--all")
- for i in "$INSTALLDIR/$(uname -r)"/*.ko; do
- [[ -e "$i" ]] || continue
- load_module "$i" || die "failed to load module $i"
- done
+ [[ -e "${CONFIGFILE}" ]] || die "Kpatch modules load configfile ${CONFIGFILE} could NOT be found!"
+ if [[ -n $(awk '{if(!NF || /^#/){next}}1' "${CONFIGFILE}") ]]; then
+ awk '{if(!NF || /^#/){next}}1' "${CONFIGFILE}" | while read -r line; do
+ INSTALLMOD=${line%% *}
+ RDEPSMODS=${line#*.ko}
+ RDEPS_ARRAY=$(echo "${RDEPSMODS}" | tr ',' ' ')
+
+ if [[ "${INSTALLMOD: -3}" != ".ko" ]]; then
+ warn_load "Module ${INSTALLMOD} missing .ko filename suffix"
+ continue
+ fi
+
+ if [[ ! -e "${INSTALLDIR}/$(uname -r)/${INSTALLMOD}" ]]; then
+ warn_load "Skipping ${INSTALLMOD}, cannot find it in ${INSTALLDIR}/$(uname -r)/"
+ continue
+ fi
+
+ if [[ "${RDEPS_ARRAY}" ]] && ! is_installed "${RDEPS_ARRAY}"; then
+ warn_load "Skipping load of ${INSTALLMOD} due to missing dependency module(s)"
+ continue
+ fi
+
+ MOD_FULLPATH="${INSTALLDIR}/$(uname -r)/${INSTALLMOD}"
+ load_module "${MOD_FULLPATH}" || die "Failed to load module ${MOD_FULLPATH}"
+ done
+ else
+ for i in "${INSTALLDIR}/$(uname -r)"/*.ko; do
+ [[ -e "${i}" ]] || continue
+ load_module "${i}" || die "Failed to load module ${i}"
+ done
+ fi
;;
*)
PATCH="$2"
--
2.25.1

View File

@ -2,3 +2,4 @@
0002-kpatch-Add-the-signature-for-livepatch-kernel-module.patch
0003-kpatch-Adjust-the-kpatch-build-to-support-the-multik.patch
0004-kpatch-Fix-the-build-failure-when-the-cache-src-dire.patch
0005-kpatch-Support-the-customized-order-for-module-load.patch