From 5947e79e30515abafbd38e42aad6c3bf28f09809 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Fri, 14 Feb 2014 11:39:23 -0600 Subject: [PATCH] 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" --- kpatch-build/kpatch-build | 2 +- kpatch/kpatch | 112 +++++++++++++++++++++----------------- 2 files changed, 63 insertions(+), 51 deletions(-) diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build index ff27f7e..03fb1e6 100755 --- a/kpatch-build/kpatch-build +++ b/kpatch-build/kpatch-build @@ -47,7 +47,7 @@ die() { } if [[ "$#" -ne 1 ]]; then - echo "usage: $0 PATCH" >&2 + echo "usage: $0 patchfile" >&2 exit 2 fi diff --git a/kpatch/kpatch b/kpatch/kpatch index 010c66f..22b69d7 100755 --- a/kpatch/kpatch +++ b/kpatch/kpatch @@ -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" ;; *)