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 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,25 +62,57 @@ 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
} }
if [[ "$#" -ne 1 ]]; then find_tools_dir() {
echo "usage: $0 patchfile" >&2 #git repo
exit 2 TOOLSDIR="$SCRIPTDIR"
fi [[ -e "$TOOLSDIR/create-diff-object" ]] && return
PATCHFILE="$(readlink -f $1)" #installation path
if [[ ! -f "$PATCHFILE" ]]; then TOOLSDIR="$(readlink -f $SCRIPTDIR/../libexec/kpatch)"
echo "ERROR: patch file $PATCHFILE not found" >&2 [[ -e "$TOOLSDIR/create-diff-object" ]] && return
exit 3
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 fi
PATCHNAME="$(basename $PATCHFILE)" PATCHNAME="$(basename $PATCHFILE)"
@ -91,10 +122,29 @@ 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" ]] || [[ -n "$USERSRCDIR" ]]; then
echo "Using cache at $SRCDIR" 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 cd "$SRCDIR" || die
if [[ -f "$APPLIEDPATCHFILE" ]]; then if [[ -f "$APPLIEDPATCHFILE" ]]; then
patch -R -p1 < "$APPLIEDPATCHFILE" >> "$LOGFILE" 2>&1 || die "the kpatch cache is corrupted. \"rm -rf $CACHEDIR\" and try again" 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 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
;; ;;