2323# This is the kpatch user script that manages installing, loading, and
2424# displaying information about kernel patch modules installed on the system.
2525
26- KERNELRELEASE=" $( uname -r) "
27- SYSDIR=" /usr/lib/kpatch/$KERNELRELEASE "
28- USERDIR=" /var/lib/kpatch/$KERNELRELEASE "
26+ INSTALLDIR=/var/lib/kpatch
2927SCRIPTDIR=" $( readlink -f $( dirname $( type -p $0 ) ) ) "
3028
3129usage_cmd () {
@@ -38,8 +36,8 @@ usage () {
3836 echo " usage: kpatch <command> [<args>]" >&2
3937 echo >&2
4038 echo " Valid commands:" >&2
41- usage_cmd " install <module>" " install patch module to the initrd to be loaded at boot"
42- usage_cmd " uninstall <module>" " uninstall patch module from the initrd"
39+ usage_cmd " install [-k|--kernel-version=<kernel version>] <module>" " install patch module to the initrd to be loaded at boot"
40+ usage_cmd " uninstall [-k|--kernel-version=<kernel version>] <module>" " uninstall patch module from the initrd"
4341 echo >&2
4442 usage_cmd " load --all" " load all installed patch modules into the running kernel"
4543 usage_cmd " load <module>" " load patch module into the running kernel"
@@ -65,10 +63,7 @@ __find_module () {
6563 MODULE=" $1 "
6664 [[ -f " $MODULE " ]] && return
6765
68- MODULE=" $USERDIR /$1 "
69- [[ -f " $MODULE " ]] && return
70-
71- MODULE=" $SYSDIR /$1 "
66+ MODULE=$INSTALLDIR /$( uname -r) /" $1 "
7267 [[ -f " $MODULE " ]] && return
7368
7469 return 1
@@ -136,23 +131,19 @@ unload_disabled_modules() {
136131 done
137132}
138133
139- echo_patch_name () {
140- NAME= " $( basename $1 ) "
141- echo $NAME
134+ get_module_version () {
135+ MODVER= $( modinfo -F vermagic " $1 " ) || return 1
136+ MODVER= ${MODVER / */ }
142137}
143138
144139unset MODULE
145- [[ " $# " -gt 2 ]] || [[ " $# " - lt 1 ]] && usage
140+ [[ " $# " -lt 1 ]] && usage
146141case " $1 " in
147142" load" )
148143 [[ " $# " -ne 2 ]] && usage
149144 case " $2 " in
150145 " --all" )
151- for i in " $SYSDIR " /* .ko; do
152- [[ -e " $i " ]] || continue
153- load_module " $i " || die " failed to load module $i "
154- done
155- for i in " $USERDIR " /* .ko; do
146+ for i in " $INSTALLDIR " /$( uname -r) /* .ko; do
156147 [[ -e " $i " ]] || continue
157148 load_module " $i " || die " failed to load module $i "
158149 done
@@ -179,50 +170,88 @@ case "$1" in
179170 ;;
180171
181172" install" )
182- [[ " $# " -ne 2 ]] && usage
183- PATCH=" $2 "
184- [[ -e " $PATCH " ]] || die " $PATCH doesn't exist"
173+ KVER=$( uname -r)
174+ shift
175+ options=$( getopt -o k: -l " kernel-version:" -- " $@ " ) || die " getopt failed"
176+ eval set -- " $options "
177+ while [[ $# -gt 0 ]]; do
178+ case " $1 " in
179+ -k|--kernel-version)
180+ KVER=$2
181+ shift
182+ ;;
183+ --)
184+ [[ -z " $2 " ]] && die " no patch file specified"
185+ PATCH=" $2 "
186+ ;;
187+ esac
188+ shift
189+ done
190+
191+ [[ ! -e " $PATCH " ]] && die " $PATCH doesn't exist"
185192 [[ ${PATCH: -3} == " .ko" ]] || die " $PATCH isn't a .ko file"
186193
187- echo " installing $PATCH to $USERDIR "
188- mkdir -p " $USERDIR " || die " failed to create install directory"
189- cp -f " $PATCH " " $USERDIR " || die " failed to install patch $PATCH "
194+ get_module_version " $PATCH " || die " modinfo failed"
195+ [[ $KVER != $MODVER ]] && die " invalid module version $MODVER for kernel $KVER "
196+
197+ [[ -e $INSTALLDIR /$KVER /$( basename " $PATCH " ) ]] && die " $PATCH is already installed"
190198
191- echo " installing $PATCH to initramfs"
192- dracut -f || die " dracut failed"
199+ echo " installing $PATCH ($KVER )"
200+ mkdir -p $INSTALLDIR /$KVER || die " failed to create install directory"
201+ cp -f " $PATCH " $INSTALLDIR /$KVER || die " failed to install patch $PATCH "
202+
203+ if lsinitrd -k $KVER & > /dev/null; then
204+ echo " rebuilding $KVER initramfs"
205+ dracut -f --kver $KVER || die " dracut failed"
206+ fi
193207 ;;
194208
195209" uninstall" )
196- [[ " $# " -ne 2 ]] && usage
197- PATCH=" $2 "
198- find_module " $PATCH " || die " $PATCH is not installed"
210+ KVER=$( uname -r)
211+ shift
212+ options=$( getopt -o k: -l " kernel-version:" -- " $@ " ) || die " getopt failed"
213+ eval set -- " $options "
214+ while [[ $# -gt 0 ]]; do
215+ case " $1 " in
216+ -k|--kernel-version)
217+ KVER=$2
218+ shift
219+ ;;
220+ --)
221+ [[ -z " $2 " ]] && die " no patch file specified"
222+ PATCH=" $2 "
223+ [[ " $PATCH " != $( basename " $PATCH " ) ]] && die " please supply patch module name without path"
224+ ;;
225+ esac
226+ shift
227+ done
199228
200- echo " uninstalling $PATCH from $USERDIR "
201- rm -f " $USERDIR /$( basename $MODULE ) " || die " failed to uninstall patch $PATCH "
229+ [[ ! -e $INSTALLDIR /$KVER /" $PATCH " ]] && die " $PATCH is not installed for kernel $KVER "
202230
203- echo " uninstalling $PATCH from initramfs"
204- dracut -f || die " dracut failed"
231+ echo " uninstalling $PATCH ($KVER )"
232+ rm -f $INSTALLDIR /$KVER /" $PATCH " || die " failed to uninstall patch $PATCH "
233+ if lsinitrd -k $KVER & > /dev/null; then
234+ echo " rebuilding $KVER initramfs"
235+ dracut -f --kver $KVER || die " dracut failed"
236+ fi
205237 ;;
206238
207239" list" )
208240 [[ " $# " -ne 1 ]] && usage
209241 echo " Loaded patch modules:"
210242 for module in /sys/kernel/kpatch/patches/* ; do
211243 if [[ -e $module ]] && [[ $( cat $module /enabled) -eq 1 ]]; then
212- echo_patch_name $ module
244+ echo $( basename " $ module" )
213245 fi
214246 done
215247 echo " "
216- echo " System installed patch modules:"
217- for i in " $SYSDIR " /* .ko; do
218- [[ -e " $i " ]] || continue
219- echo_patch_name $i
220- done
221- echo " "
222- echo " User installed patch modules:"
223- for i in " $USERDIR " /* .ko; do
224- [[ -e " $i " ]] || continue
225- echo_patch_name $i
248+ echo " Installed patch modules:"
249+ for kdir in $INSTALLDIR /* ; do
250+ [[ -e " $kdir " ]] || continue
251+ for module in $kdir /* ; do
252+ [[ -e " $module " ]] || continue
253+ echo " $( basename $module ) ($( basename $kdir ) )"
254+ done
226255 done
227256 ;;
228257
0 commit comments