kpatch: patches not modules

Be more consistent with the patch metaphor (as opposed to modules):

- change load/unload to apply/remove
- strip "kpatch-" prefix from the module name, so that patch name "foo"
  corresponds to module "kpatch-foo.ko"
This commit is contained in:
Josh Poimboeuf 2014-02-14 11:39:23 -06:00
parent 244d963f89
commit 5947e79e30
2 changed files with 63 additions and 51 deletions

View File

@ -47,7 +47,7 @@ die() {
}
if [[ "$#" -ne 1 ]]; then
echo "usage: $0 PATCH" >&2
echo "usage: $0 patchfile" >&2
exit 2
fi

View File

@ -1,8 +1,7 @@
#!/bin/bash
# This is the primary kpatch user script that manages loading, unloading
# and displaying information on the patches that are installed on the
# system.
# This is the primary kpatch user script that manages building, applying, and
# displaying information about kernel patch modules installed on the system.
# TODO: add kernelrelease option to manage releases other than the
# currently running one
@ -15,13 +14,13 @@ TOOLSDIR=/usr/local/libexec/kpatch
usage () {
echo "usage:" >&2
echo "kpatch enable MODULE" >&2
echo "kpatch disable MODULE" >&2
echo "kpatch load [--all | MODULE]" >&2
echo "kpatch unload MODULE" >&2
echo "kpatch enable PATCH" >&2
echo "kpatch disable PATCH" >&2
echo "kpatch apply [--all | PATCH]" >&2
echo "kpatch remove PATCH" >&2
echo "kpatch list" >&2
echo "kpatch info MODULE" >&2
echo "kpatch build PATCH" >&2
echo "kpatch info PATCH" >&2
echo "kpatch build PATCH.patch" >&2
exit 1
}
@ -34,74 +33,87 @@ die() {
exit 1
}
# return full module path in DIR
find_patch () {
[[ -f "$USERDIR/$1" ]] && DIR="$USERDIR" && return
[[ -f "$SYSDIR/$1" ]] && DIR="$SYSDIR" && return
__find_module () {
MODULE="$USERDIR/$1"
[[ -f "$MODULE" ]] && return
MODULE="$SYSDIR/$1"
[[ -f "$MODULE" ]] && return
return 1
}
# takes full path to patch module
load_patch () {
NAME=$(basename $1)
NAME=${NAME%.*}
# Given a patch name, find the corresponding module and return its full path in
# $MODULE. For a given module kpatch-foo.ko, we allow foo or kpatch-foo or
# kpatch-foo.ko as input.
find_module () {
arg=$1
__find_module "kpatch-$arg.ko" || __find_module "$arg.ko" || __find_module "${arg}"
}
load_module () {
/usr/sbin/insmod "$1"
}
# takes only the module filename
unload_patch () {
NAME="$(basename $1)"
/usr/sbin/rmmod "${NAME%.*}"
unload_module () {
/usr/sbin/rmmod "$(basename $1)"
}
unset DIR
module_enabled() {
[[ -e "$ENABLEDDIR/$(basename $1)" ]]
}
echo_patch_name() {
NAME="$(basename $1)"
NAME="${NAME%.ko}"
NAME="${NAME#kpatch-}"
echo $NAME
}
unset MODULE
[[ "$#" -gt 2 ]] || [[ "$#" -lt 1 ]] && usage
case "$1" in
"enable")
[[ "$#" -ne 2 ]] && usage
PATCH=$2
MODFILE="$PATCH.ko"
find_patch "$MODFILE" || die "$PATCH is not installed"
[[ -e "$ENABLEDDIR/$MODFILE" ]] && die "patch $2 is already enabled"
PATCH="$2"
find_module "$PATCH" || die "$PATCH is not installed"
module_enabled $MODULE && die "$PATCH is already enabled"
mkdir -p $ENABLEDDIR
ln -s "$DIR/$MODFILE" "$ENABLEDDIR/$MODFILE" || die "failed to enable patch $PATCH"
ln -s "$MODULE" "$ENABLEDDIR" || die "failed to enable patch $PATCH"
;;
"disable")
[[ "$#" -ne 2 ]] && usage
PATCH=$2
MODFILE="$PATCH.ko"
find_patch "$MODFILE" || die "$PATCH is not installed"
[[ ! -e "$ENABLEDDIR/$MODFILE" ]] && die "$PATCH is already disabled"
rm -f "$ENABLEDDIR/$MODFILE" || die "failed to disable patch $PATCH"
PATCH="$2"
find_module "$PATCH" || die "$PATCH is not installed"
module_enabled $MODULE || die "$PATCH is already disabled"
rm -f "$ENABLEDDIR/$(basename $MODULE)" || die "failed to disable patch $PATCH"
;;
"load")
"apply")
[[ "$#" -ne 2 ]] && usage
case "$2" in
"--all")
for i in "$ENABLEDDIR"/*.ko; do
[[ -e "$i" ]] || continue
load_patch "$i" || die "failed to load patch $PATCH"
load_module "$i" || die "failed to load module $i"
done
;;
*)
PATCH="$2"
MODFILE="$PATCH.ko"
find_patch "$MODFILE" || die "$PATCH is not installed"
load_patch "$DIR/$MODFILE" || die "failed to load patch $PATCH"
find_module "$PATCH" || die "$PATCH is not installed"
load_module "$MODULE" || die "failed to load patch $PATCH"
;;
esac
;;
"unload")
"remove")
[[ "$#" -ne 2 ]] && usage
case "$2" in
PATCH="$2"
case "$PATCH" in
*)
PATCH="$2"
MODFILE="$PATCH.ko"
find_patch "$MODFILE" || die "$PATCH is not installed"
unload_patch "$PATCH" || die "failed to unload patch $PATCH"
find_module "$PATCH" || die "$PATCH is not installed"
unload_module "$MODULE" || die "failed to unload patch $PATCH"
;;
esac
;;
@ -111,34 +123,34 @@ case "$1" in
echo "System patches:"
for i in "$SYSDIR"/*.ko; do
[[ -e "$i" ]] || continue
echo "$(basename ${i%.*})"
echo_patch_name $i
done
echo ""
echo "User patches:"
for i in "$USERDIR"/*.ko; do
[[ -e "$i" ]] || continue
echo "$(basename ${i%.*})"
echo_patch_name $i
done
echo ""
echo "Enabled patches:"
for i in "$ENABLEDDIR"/*.ko; do
[[ -e "$i" ]] || continue
echo "$(basename ${i%.*})"
echo_patch_name $i
done
;;
"info")
[[ "$#" -ne 2 ]] && usage
PATCH="$2"
MODFILE="$PATCH.ko"
find_patch "$MODFILE" || die "$PATCH is not installed"
find_module "$PATCH" || die "$PATCH is not installed"
echo "Patch information for $PATCH:"
/usr/sbin/modinfo "$DIR/$MODFILE"
/usr/sbin/modinfo "$MODULE" || die "failed to get info for patch $PATCH"
;;
"build")
[[ "$#" -ne 2 ]] && usage
"$TOOLSDIR/kpatch-build" "$2" || die "kpatch build failed"
shift
"$TOOLSDIR/kpatch-build" "$@" || die "kpatch build failed"
;;
*)