Merge pull request #50 from jpoimboe/sourcedir-option

kpatch-build: remove "kpatch build" wrapper and add --sourcedir option
This commit is contained in:
Seth Jennings 2014-03-11 15:03:35 -05:00
commit 3acf30c0c8
5 changed files with 77 additions and 48 deletions

View File

@ -4,6 +4,7 @@ CC = gcc
INSTALL = /usr/bin/install
PREFIX ?= /usr/local
BINDIR = $(DESTDIR)$(PREFIX)/bin
SBINDIR = $(DESTDIR)$(PREFIX)/sbin
MODULESDIR = $(DESTDIR)$(PREFIX)/lib/modules
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.*
Install the dependencies for the "kpatch build" command:
Install the dependencies for the "kpatch-build" command:
sudo yum install rpmdevtools pesign
sudo yum-builddep kernel
@ -48,7 +48,7 @@ Quick start
-----------
*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.*
Load the kpatch core module:
@ -62,7 +62,7 @@ Make a source patch against the kernel tree:
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
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.
### 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
which uses a collection of utilities: `create-diff-object`,
`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
patches for safety before applying them.
- 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
schedule(), will fail to apply at runtime.
- 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
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

View File

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

View File

@ -38,12 +38,11 @@
BASE="$PWD"
LOGFILE="/tmp/kpatch-build-$(date +%s).log"
TOOLSDIR="$(readlink -f $(dirname $0))"
SCRIPTDIR="$(readlink -f $(dirname $0))"
ARCHVERSION="$(uname -r)"
DISTROVERSION="${ARCHVERSION%*.*}"
LOCALVERSION="-${ARCHVERSION##*-}"
CPUS="$(grep -c ^processor /proc/cpuinfo)"
LOCALVERSION="$(uname -r)"
LOCALVERSION="-${LOCALVERSION##*-}"
CACHEDIR="$HOME/.kpatch"
SRCDIR="$CACHEDIR/$ARCHVERSION/src"
OBJDIR="$CACHEDIR/$ARCHVERSION/obj"
@ -63,25 +62,57 @@ die() {
find_data_dir() {
# git repo
DATADIR="$(readlink -f $TOOLSDIR/../kmod)"
DATADIR="$(readlink -f $SCRIPTDIR/../kmod)"
[[ -e "$DATADIR" ]] && return
# installation path
DATADIR="$(readlink -f $TOOLSDIR/../../share/kpatch)"
DATADIR="$(readlink -f $SCRIPTDIR/../share/kpatch)"
[[ -e "$DATADIR" ]] && return
return 1
}
if [[ "$#" -ne 1 ]]; then
echo "usage: $0 patchfile" >&2
exit 2
fi
find_tools_dir() {
#git repo
TOOLSDIR="$SCRIPTDIR"
[[ -e "$TOOLSDIR/create-diff-object" ]] && return
PATCHFILE="$(readlink -f $1)"
if [[ ! -f "$PATCHFILE" ]]; then
echo "ERROR: patch file $PATCHFILE not found" >&2
exit 3
#installation path
TOOLSDIR="$(readlink -f $SCRIPTDIR/../libexec/kpatch)"
[[ -e "$TOOLSDIR/create-diff-object" ]] && return
return 1
}
usage() {
echo "usage: $0 [-s|--sourcedir <dir>] <patch file>" >&2
}
while [[ "$#" -gt 0 ]]; do
case "$1" in
-h|--help)
usage
exit 0
;;
-s|--sourcedir)
shift
[[ "$#" -eq 0 ]] && die "no source dir specified"
USERSRCDIR="$(readlink -f $1)"
[[ ! -d "$USERSRCDIR" ]] && die "source dir $1 not found"
shift
;;
*)
[[ -n "$PATCHFILE" ]] && die "bad argument: $1"
PATCHFILE="$(readlink -f $1)"
[[ ! -f "$PATCHFILE" ]] && die "patch file $1 not found"
shift
;;
esac
done
if [[ -z "$PATCHFILE" ]]; then
usage
exit 1
fi
PATCHNAME="$(basename $PATCHFILE)"
@ -91,10 +122,29 @@ fi
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
if [[ -d "$SRCDIR" ]]; then
echo "Using cache at $SRCDIR"
if [[ -d "$SRCDIR" ]] || [[ -n "$USERSRCDIR" ]]; then
if [[ -n "$USERSRCDIR" ]]; then
SRCDIR="$CACHEDIR/src"
OBJDIR="$CACHEDIR/obj"
OBJDIR2="$CACHEDIR/obj2"
rm -rf "$CACHEDIR"
mkdir -p "$CACHEDIR"
mkdir -p "$OBJDIR" "$OBJDIR2"
cp "$USERSRCDIR/.config" "$OBJDIR" || die "source dir is missing a .config file"
echo "Copying source to $SRCDIR"
cp -a "$USERSRCDIR" "$SRCDIR" || die "copy failed"
else
echo "Using cache at $SRCDIR"
fi
cd "$SRCDIR" || die
if [[ -f "$APPLIEDPATCHFILE" ]]; then
patch -R -p1 < "$APPLIEDPATCHFILE" >> "$LOGFILE" 2>&1 || die "the kpatch cache is corrupted. \"rm -rf $CACHEDIR\" and try again"
@ -125,8 +175,6 @@ echo "Building original kernel"
make mrproper >> "$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 "$OBJDIR/vmlinux" "$TEMPDIR" || die

View File

@ -20,7 +20,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA,
# 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.
# TODO: add kernelrelease option to manage releases other than the
@ -35,8 +35,6 @@ usage () {
echo "usage: kpatch <command> [<args>]" >&2
echo >&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' "uninstall <hotpatch>" "uninstall hotpatch module from the kpatch DB" >&2
echo >&2
@ -94,20 +92,6 @@ echo_patch_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
[[ "$#" -gt 2 ]] || [[ "$#" -lt 1 ]] && usage
case "$1" in
@ -196,12 +180,6 @@ case "$1" in
/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")
usage
;;