From 7e76dba34660d7550027a52806ae6edeeb84fc31 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Wed, 21 May 2014 10:09:11 -0500 Subject: [PATCH 1/4] kpatch: prevent installing a duplicate patch module --- kpatch/kpatch | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kpatch/kpatch b/kpatch/kpatch index 5fcbf8eac..3dad6459e 100755 --- a/kpatch/kpatch +++ b/kpatch/kpatch @@ -184,6 +184,8 @@ case "$1" in [[ -e "$PATCH" ]] || die "$PATCH doesn't exist" [[ ${PATCH: -3} == ".ko" ]] || die "$PATCH isn't a .ko file" + find_module $(basename "$PATCH") && die "$PATCH is already installed" + echo "installing $PATCH to $USERDIR" mkdir -p "$USERDIR" || die "failed to create install directory" cp -f "$PATCH" "$USERDIR" || die "failed to install patch $PATCH" From 6dc6d78627cdd711a10bf6c1008fe584a19dde25 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Wed, 21 May 2014 10:52:59 -0500 Subject: [PATCH 2/4] kpatch: uninstall should only look in user-installed dir --- kpatch/kpatch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kpatch/kpatch b/kpatch/kpatch index 3dad6459e..3b78b9f9f 100755 --- a/kpatch/kpatch +++ b/kpatch/kpatch @@ -197,7 +197,7 @@ case "$1" in "uninstall") [[ "$#" -ne 2 ]] && usage PATCH="$2" - find_module "$PATCH" || die "$PATCH is not installed" + [[ ! -e $USERDIR/$PATCH ]] && die "$PATCH is not installed" echo "uninstalling $PATCH from $USERDIR" rm -f "$USERDIR/$(basename $MODULE)" || die "failed to uninstall patch $PATCH" From 8779d79c50bd57087441193c03fc1ed38a79fa47 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Wed, 21 May 2014 12:16:46 -0500 Subject: [PATCH 3/4] kpatch: get rid of system-installed modules The user-installed vs system-installed dichotomy is confusing. Let's just have "installed". RPM-installed modules can just call "kpatch install" in their post-install step. --- contrib/module-setup.sh | 9 +--- kpatch/kpatch | 117 ++++++++++++++++++++++++---------------- man/kpatch.1 | 4 +- 3 files changed, 75 insertions(+), 55 deletions(-) diff --git a/contrib/module-setup.sh b/contrib/module-setup.sh index b8fd09b28..be38dc0d5 100755 --- a/contrib/module-setup.sh +++ b/contrib/module-setup.sh @@ -7,7 +7,7 @@ # called by dracut check() { - if [[ -e /var/lib/kpatch/$kernel ]] || [[ -e /usr/lib/kpatch/$kernel ]]; then + if [[ -e /var/lib/kpatch/$kernel ]]; then return 0 else return 1 @@ -36,13 +36,6 @@ install() { inst "$i" done fi - if [[ -e /usr/lib/kpatch/$kernel ]]; then - inst_dir /usr/lib/kpatch/$kernel - for i in /usr/lib/kpatch/$kernel/*; do - [[ -e $i ]] || continue - inst "$i" - done - fi # install hook script inst_hook pre-udev 00 "$moddir/kpatch-load-all.sh" diff --git a/kpatch/kpatch b/kpatch/kpatch index 3b78b9f9f..40a847600 100755 --- a/kpatch/kpatch +++ b/kpatch/kpatch @@ -23,9 +23,7 @@ # This is the kpatch user script that manages installing, loading, and # displaying information about kernel patch modules installed on the system. -KERNELRELEASE="$(uname -r)" -SYSDIR="/usr/lib/kpatch/$KERNELRELEASE" -USERDIR="/var/lib/kpatch/$KERNELRELEASE" +INSTALLDIR=/var/lib/kpatch SCRIPTDIR="$(readlink -f $(dirname $(type -p $0)))" usage_cmd() { @@ -38,8 +36,8 @@ usage () { echo "usage: kpatch []" >&2 echo >&2 echo "Valid commands:" >&2 - usage_cmd "install " "install patch module to the initrd to be loaded at boot" - usage_cmd "uninstall " "uninstall patch module from the initrd" + usage_cmd "install [-k|--kver=] " "install patch module to the initrd to be loaded at boot" + usage_cmd "uninstall [-k|--kver=] " "uninstall patch module from the initrd" echo >&2 usage_cmd "load --all" "load all installed patch modules into the running kernel" usage_cmd "load " "load patch module into the running kernel" @@ -65,10 +63,7 @@ __find_module () { MODULE="$1" [[ -f "$MODULE" ]] && return - MODULE="$USERDIR/$1" - [[ -f "$MODULE" ]] && return - - MODULE="$SYSDIR/$1" + MODULE=$INSTALLDIR/$(uname -r)/"$1" [[ -f "$MODULE" ]] && return return 1 @@ -136,23 +131,19 @@ unload_disabled_modules() { done } -echo_patch_name() { - NAME="$(basename $1)" - echo $NAME +get_module_version() { + MODVER=$(modinfo -F vermagic "$1") || return 1 + MODVER=${MODVER/ */} } unset MODULE -[[ "$#" -gt 2 ]] || [[ "$#" -lt 1 ]] && usage +[[ "$#" -lt 1 ]] && usage case "$1" in "load") [[ "$#" -ne 2 ]] && usage case "$2" in "--all") - for i in "$SYSDIR"/*.ko; do - [[ -e "$i" ]] || continue - load_module "$i" || die "failed to load module $i" - done - for i in "$USERDIR"/*.ko; do + for i in "$INSTALLDIR"/$(uname -r)/*.ko; do [[ -e "$i" ]] || continue load_module "$i" || die "failed to load module $i" done @@ -179,31 +170,70 @@ case "$1" in ;; "install") - [[ "$#" -ne 2 ]] && usage - PATCH="$2" - [[ -e "$PATCH" ]] || die "$PATCH doesn't exist" + KVER=$(uname -r) + shift + options=$(getopt -o k: -l "kver:" -- "$@") || die "getopt failed" + eval set -- "$options" + while [[ $# -gt 0 ]]; do + case "$1" in + -k|--kver) + KVER=$2 + shift + ;; + --) + [[ -z "$2" ]] && die "no patch file specified" + PATCH="$2" + ;; + esac + shift + done + + [[ ! -e "$PATCH" ]] && die "$PATCH doesn't exist" [[ ${PATCH: -3} == ".ko" ]] || die "$PATCH isn't a .ko file" - find_module $(basename "$PATCH") && die "$PATCH is already installed" + get_module_version "$PATCH" || die "modinfo failed" + [[ $KVER != $MODVER ]] && die "invalid module version $MODVER for kernel $KVER" - echo "installing $PATCH to $USERDIR" - mkdir -p "$USERDIR" || die "failed to create install directory" - cp -f "$PATCH" "$USERDIR" || die "failed to install patch $PATCH" + [[ -e $INSTALLDIR/$KVER/$(basename "$PATCH") ]] && die "$PATCH is already installed" - echo "installing $PATCH to initramfs" - dracut -f || die "dracut failed" + echo "installing $PATCH ($KVER)" + mkdir -p $INSTALLDIR/$KVER || die "failed to create install directory" + cp -f "$PATCH" $INSTALLDIR/$KVER || die "failed to install patch $PATCH" + + if lsinitrd -k $KVER &> /dev/null; then + echo "rebuilding $KVER initramfs" + dracut -f --kver $KVER || die "dracut failed" + fi ;; "uninstall") - [[ "$#" -ne 2 ]] && usage - PATCH="$2" - [[ ! -e $USERDIR/$PATCH ]] && die "$PATCH is not installed" + KVER=$(uname -r) + shift + options=$(getopt -o k: -l "kver:" -- "$@") || die "getopt failed" + eval set -- "$options" + while [[ $# -gt 0 ]]; do + case "$1" in + -k|--kver) + KVER=$2 + shift + ;; + --) + [[ -z "$2" ]] && die "no patch file specified" + PATCH="$2" + [[ "$PATCH" != $(basename "$PATCH") ]] && die "please supply patch module name without path" + ;; + esac + shift + done - echo "uninstalling $PATCH from $USERDIR" - rm -f "$USERDIR/$(basename $MODULE)" || die "failed to uninstall patch $PATCH" + [[ ! -e $INSTALLDIR/$KVER/"$PATCH" ]] && die "$PATCH is not installed for kernel $KVER" - echo "uninstalling $PATCH from initramfs" - dracut -f || die "dracut failed" + echo "uninstalling $PATCH ($KVER)" + rm -f $INSTALLDIR/$KVER/"$PATCH" || die "failed to uninstall patch $PATCH" + if lsinitrd -k $KVER &> /dev/null; then + echo "rebuilding $KVER initramfs" + dracut -f --kver $KVER || die "dracut failed" + fi ;; "list") @@ -211,20 +241,17 @@ case "$1" in echo "Loaded patch modules:" for module in /sys/kernel/kpatch/patches/*; do if [[ -e $module ]] && [[ $(cat $module/enabled) -eq 1 ]]; then - echo_patch_name $module + echo $(basename "$module") fi done echo "" - echo "System installed patch modules:" - for i in "$SYSDIR"/*.ko; do - [[ -e "$i" ]] || continue - echo_patch_name $i - done - echo "" - echo "User installed patch modules:" - for i in "$USERDIR"/*.ko; do - [[ -e "$i" ]] || continue - echo_patch_name $i + echo "Installed patch modules:" + for kdir in $INSTALLDIR/*; do + [[ -e "$kdir" ]] || continue + for module in $kdir/*; do + [[ -e "$module" ]] || continue + echo "$(basename $module) ($(basename $kdir))" + done done ;; diff --git a/man/kpatch.1 b/man/kpatch.1 index 98b9ed03c..52e858b80 100644 --- a/man/kpatch.1 +++ b/man/kpatch.1 @@ -11,10 +11,10 @@ displaying information about kernel patch modules installed on the system. .SH COMMANDS -install +install [-k|--kver=] install patch module to the initrd to be loaded at boot -uninstall +uninstall [-k|--kver=] uninstall patch module from the initrd load --all From 53f8f1d149ffdf587cfd8f58649abd767f9275a0 Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Wed, 21 May 2014 16:47:43 -0500 Subject: [PATCH 4/4] kpatch: change --kver to --kernel-version --- kpatch/kpatch | 12 ++++++------ man/kpatch.1 | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/kpatch/kpatch b/kpatch/kpatch index 40a847600..9cba0518a 100755 --- a/kpatch/kpatch +++ b/kpatch/kpatch @@ -36,8 +36,8 @@ usage () { echo "usage: kpatch []" >&2 echo >&2 echo "Valid commands:" >&2 - usage_cmd "install [-k|--kver=] " "install patch module to the initrd to be loaded at boot" - usage_cmd "uninstall [-k|--kver=] " "uninstall patch module from the initrd" + usage_cmd "install [-k|--kernel-version=] " "install patch module to the initrd to be loaded at boot" + usage_cmd "uninstall [-k|--kernel-version=] " "uninstall patch module from the initrd" echo >&2 usage_cmd "load --all" "load all installed patch modules into the running kernel" usage_cmd "load " "load patch module into the running kernel" @@ -172,11 +172,11 @@ case "$1" in "install") KVER=$(uname -r) shift - options=$(getopt -o k: -l "kver:" -- "$@") || die "getopt failed" + options=$(getopt -o k: -l "kernel-version:" -- "$@") || die "getopt failed" eval set -- "$options" while [[ $# -gt 0 ]]; do case "$1" in - -k|--kver) + -k|--kernel-version) KVER=$2 shift ;; @@ -209,11 +209,11 @@ case "$1" in "uninstall") KVER=$(uname -r) shift - options=$(getopt -o k: -l "kver:" -- "$@") || die "getopt failed" + options=$(getopt -o k: -l "kernel-version:" -- "$@") || die "getopt failed" eval set -- "$options" while [[ $# -gt 0 ]]; do case "$1" in - -k|--kver) + -k|--kernel-version) KVER=$2 shift ;; diff --git a/man/kpatch.1 b/man/kpatch.1 index 52e858b80..afee613db 100644 --- a/man/kpatch.1 +++ b/man/kpatch.1 @@ -11,10 +11,10 @@ displaying information about kernel patch modules installed on the system. .SH COMMANDS -install [-k|--kver=] +install [-k|--kernel-version=] install patch module to the initrd to be loaded at boot -uninstall [-k|--kver=] +uninstall [-k|--kernel-version=] uninstall patch module from the initrd load --all