make kpatch-build a first class script

kpatch-build is outgrowing the kpatch script and probably is a better
fit as its own utility instead of being wrapped by kpatch.  Install
kpatch-build into /usr/local/bin, remove the kpatch wrapper around it,
and update the README accordingly.
This commit is contained in:
Josh Poimboeuf 2014-03-10 09:24:40 -05:00
parent 9e69a53206
commit 2d728c4f0d
5 changed files with 31 additions and 38 deletions

View File

@ -4,6 +4,7 @@ CC = gcc
INSTALL = /usr/bin/install INSTALL = /usr/bin/install
PREFIX ?= /usr/local PREFIX ?= /usr/local
BINDIR = $(DESTDIR)$(PREFIX)/bin
SBINDIR = $(DESTDIR)$(PREFIX)/sbin SBINDIR = $(DESTDIR)$(PREFIX)/sbin
MODULESDIR = $(DESTDIR)$(PREFIX)/lib/modules MODULESDIR = $(DESTDIR)$(PREFIX)/lib/modules
LIBEXECDIR = $(DESTDIR)$(PREFIX)/libexec/kpatch LIBEXECDIR = $(DESTDIR)$(PREFIX)/libexec/kpatch

View File

@ -27,7 +27,7 @@ Install the dependencies for compiling kpatch:
*NOTE: Ensure you have elfutils-0.158 or newer.* *NOTE: Ensure you have elfutils-0.158 or newer.*
Install the dependencies for the "kpatch build" command: Install the dependencies for the "kpatch-build" command:
sudo yum install rpmdevtools pesign sudo yum install rpmdevtools pesign
sudo yum-builddep kernel sudo yum-builddep kernel
@ -48,7 +48,7 @@ Quick start
----------- -----------
*NOTE: While kpatch is designed to work with any recent Linux *NOTE: While kpatch is designed to work with any recent Linux
kernel on any distribution, the "kpatch build" command currently kernel on any distribution, the "kpatch-build" command currently
only works on Fedora.* only works on Fedora.*
Load the kpatch core module: Load the kpatch core module:
@ -62,7 +62,7 @@ Make a source patch against the kernel tree:
Build the hot patch kernel module: Build the hot patch kernel module:
kpatch build /path/to/foo.patch kpatch-build /path/to/foo.patch
This outputs a hot patch module named `kpatch-foo.ko` in the current This outputs a hot patch module named `kpatch-foo.ko` in the current
directory. Now apply it to the running kernel: directory. Now apply it to the running kernel:
@ -98,9 +98,9 @@ ones. It has four main components:
even after a reboot into the same version of the kernel. even after a reboot into the same version of the kernel.
### kpatch build ### kpatch-build
The "kpatch build" command converts a source-level diff patch file to a hot The "kpatch-build" command converts a source-level diff patch file to a hot
patch kernel module. Most of its work is performed by the kpatch-build script patch kernel module. Most of its work is performed by the kpatch-build script
which uses a collection of utilities: `create-diff-object`, which uses a collection of utilities: `create-diff-object`,
`add-patch-section`, and `link-vmlinux-syms`. `add-patch-section`, and `link-vmlinux-syms`.
@ -149,7 +149,7 @@ Limitations
are safe to apply. It's the user's responsibility to analyze any such are safe to apply. It's the user's responsibility to analyze any such
patches for safety before applying them. patches for safety before applying them.
- Patches which change the contents of static data structures are not currently - Patches which change the contents of static data structures are not currently
supported. kpatch build will detect such changes and report an error. supported. kpatch-build will detect such changes and report an error.
- Patches to functions which are always in the call stack of a task, such as - Patches to functions which are always in the call stack of a task, such as
schedule(), will fail to apply at runtime. schedule(), will fail to apply at runtime.
- Patches which change functions that are only called in the kernel init path - Patches which change functions that are only called in the kernel init path
@ -256,7 +256,7 @@ http://www.youtube.com/watch?v=WeSmG-XirC4
This demonstration completes each step in the previous section in a manual This demonstration completes each step in the previous section in a manual
fashion. However, from a end-user perspective, most of these steps are hidden fashion. However, from a end-user perspective, most of these steps are hidden
by the "kpatch build" command. by the "kpatch-build" command.
Get involved Get involved

View File

@ -13,7 +13,9 @@ all: $(TARGETS)
install: all install: all
$(INSTALL) -d $(LIBEXECDIR) $(INSTALL) -d $(LIBEXECDIR)
$(INSTALL) $(TARGETS) kpatch-build $(LIBEXECDIR) $(INSTALL) $(TARGETS) $(LIBEXECDIR)
$(INSTALL) -d $(BINDIR)
$(INSTALL) kpatch-build $(BINDIR)
clean: clean:
$(RM) $(TARGETS) $(RM) $(TARGETS)

View File

@ -38,12 +38,11 @@
BASE="$PWD" BASE="$PWD"
LOGFILE="/tmp/kpatch-build-$(date +%s).log" LOGFILE="/tmp/kpatch-build-$(date +%s).log"
TOOLSDIR="$(readlink -f $(dirname $0))" SCRIPTDIR="$(readlink -f $(dirname $0))"
ARCHVERSION="$(uname -r)" ARCHVERSION="$(uname -r)"
DISTROVERSION="${ARCHVERSION%*.*}" DISTROVERSION="${ARCHVERSION%*.*}"
LOCALVERSION="-${ARCHVERSION##*-}"
CPUS="$(grep -c ^processor /proc/cpuinfo)" CPUS="$(grep -c ^processor /proc/cpuinfo)"
LOCALVERSION="$(uname -r)"
LOCALVERSION="-${LOCALVERSION##*-}"
CACHEDIR="$HOME/.kpatch" CACHEDIR="$HOME/.kpatch"
SRCDIR="$CACHEDIR/$ARCHVERSION/src" SRCDIR="$CACHEDIR/$ARCHVERSION/src"
OBJDIR="$CACHEDIR/$ARCHVERSION/obj" OBJDIR="$CACHEDIR/$ARCHVERSION/obj"
@ -63,16 +62,28 @@ die() {
find_data_dir() { find_data_dir() {
# git repo # git repo
DATADIR="$(readlink -f $TOOLSDIR/../kmod)" DATADIR="$(readlink -f $SCRIPTDIR/../kmod)"
[[ -e "$DATADIR" ]] && return [[ -e "$DATADIR" ]] && return
# installation path # installation path
DATADIR="$(readlink -f $TOOLSDIR/../../share/kpatch)" DATADIR="$(readlink -f $SCRIPTDIR/../share/kpatch)"
[[ -e "$DATADIR" ]] && return [[ -e "$DATADIR" ]] && return
return 1 return 1
} }
find_tools_dir() {
#git repo
TOOLSDIR="$SCRIPTDIR"
[[ -e "$TOOLSDIR/create-diff-object" ]] && return
#installation path
TOOLSDIR="$(readlink -f $SCRIPTDIR/../libexec/kpatch)"
[[ -e "$TOOLSDIR/create-diff-object" ]] && return
return 1
}
if [[ "$#" -ne 1 ]]; then if [[ "$#" -ne 1 ]]; then
echo "usage: $0 patchfile" >&2 echo "usage: $0 patchfile" >&2
exit 2 exit 2
@ -91,6 +102,9 @@ fi
TEMPDIR="$(mktemp -d)" || die "mktemp failed" TEMPDIR="$(mktemp -d)" || die "mktemp failed"
find_data_dir || (echo "can't find data dir" >&2 && die)
find_tools_dir || (echo "can't find tools dir" >&2 && die)
trap "rm -rf $TEMPDIR" EXIT INT TERM trap "rm -rf $TEMPDIR" EXIT INT TERM
if [[ -d "$SRCDIR" ]]; then if [[ -d "$SRCDIR" ]]; then
@ -125,8 +139,6 @@ echo "Building original kernel"
make mrproper >> "$LOGFILE" 2>&1 || die make mrproper >> "$LOGFILE" 2>&1 || die
make "-j$CPUS" vmlinux "O=$OBJDIR" >> "$LOGFILE" 2>&1 || die make "-j$CPUS" vmlinux "O=$OBJDIR" >> "$LOGFILE" 2>&1 || die
find_data_dir || (echo "can't find data dir" >&2 && die)
cp -LR "$DATADIR/patch" "$TEMPDIR" || die cp -LR "$DATADIR/patch" "$TEMPDIR" || die
cp "$OBJDIR/vmlinux" "$TEMPDIR" || die cp "$OBJDIR/vmlinux" "$TEMPDIR" || die

View File

@ -20,7 +20,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA, # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA,
# 02110-1301, USA. # 02110-1301, USA.
# This is the primary kpatch user script that manages building, applying, and # This is the kpatch user script that manages installing, applying, and
# displaying information about kernel patch modules installed on the system. # displaying information about kernel patch modules installed on the system.
# TODO: add kernelrelease option to manage releases other than the # TODO: add kernelrelease option to manage releases other than the
@ -35,8 +35,6 @@ usage () {
echo "usage: kpatch <command> [<args>]" >&2 echo "usage: kpatch <command> [<args>]" >&2
echo >&2 echo >&2
echo "Valid commands:" >&2 echo "Valid commands:" >&2
printf ' %-20s %s\n' "build <file>" "build hotpatch module from source diff patch file" >&2
echo >&2
printf ' %-20s %s\n' "install <file>" "install hotpatch module to the kpatch DB" >&2 printf ' %-20s %s\n' "install <file>" "install hotpatch module to the kpatch DB" >&2
printf ' %-20s %s\n' "uninstall <hotpatch>" "uninstall hotpatch module from the kpatch DB" >&2 printf ' %-20s %s\n' "uninstall <hotpatch>" "uninstall hotpatch module from the kpatch DB" >&2
echo >&2 echo >&2
@ -94,20 +92,6 @@ echo_patch_name() {
echo $NAME echo $NAME
} }
find_kpatch_build() {
SCRIPTDIR="$(readlink -f $(dirname $0))"
# git repo
KPATCHBUILD="$(readlink -f $SCRIPTDIR/../kpatch-build/kpatch-build)"
[[ -e "$KPATCHBUILD" ]] && return
# installation path
KPATCHBUILD="$(readlink -f $SCRIPTDIR/../libexec/kpatch/kpatch-build)"
[[ -e "$KPATCHBUILD" ]] && return
return 1
}
unset MODULE unset MODULE
[[ "$#" -gt 2 ]] || [[ "$#" -lt 1 ]] && usage [[ "$#" -gt 2 ]] || [[ "$#" -lt 1 ]] && usage
case "$1" in case "$1" in
@ -196,12 +180,6 @@ case "$1" in
/usr/sbin/modinfo "$MODULE" || die "failed to get info for patch $PATCH" /usr/sbin/modinfo "$MODULE" || die "failed to get info for patch $PATCH"
;; ;;
"build")
find_kpatch_build || die "kpatch-build is not installed"
shift
"$KPATCHBUILD" "$@" || die "kpatch build failed"
;;
"help"|"-h"|"--help") "help"|"-h"|"--help")
usage usage
;; ;;