kpatch-build: allow list of patches on command line

It can be convenient to build a patchset into a single kpatch module, so
teach kpatch-build to accept a list of .patch files on the commandline.

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
This commit is contained in:
Joe Lawrence 2017-09-20 16:30:00 -04:00
parent 8dc25d79d1
commit 139cfb38d4

View File

@ -45,11 +45,12 @@ RPMTOPDIR="$CACHEDIR/buildroot"
VERSIONFILE="$CACHEDIR/version"
TEMPDIR="$CACHEDIR/tmp"
LOGFILE="$CACHEDIR/build.log"
APPLIEDPATCHFILE="kpatch.patch"
DEBUG=0
SKIPCLEANUP=0
SKIPGCCCHECK=0
ARCH_KCFLAGS=""
declare -a PATCH_LIST
APPLIED_PATCHES=0
warn() {
echo "ERROR: $1" >&2
@ -71,15 +72,34 @@ die() {
exit 1
}
apply_patches() {
local patch
for patch in "${PATCH_LIST[@]}"; do
patch -N -p1 --dry-run < "$patch" >> "$LOGFILE" 2>&1 || die "$patch file failed to apply"
patch -N -p1 < "$patch" >> "$LOGFILE" 2>&1 || die "$patch file failed to apply"
(( APPLIED_PATCHES++ ))
done
}
remove_patches() {
local patch
local idx
for (( ; APPLIED_PATCHES>0; APPLIED_PATCHES-- )); do
idx=$(( APPLIED_PATCHES - 1))
patch="${PATCH_LIST[$idx]}"
patch -p1 -R -d "$SRCDIR" < "$patch" &> /dev/null
done
}
cleanup() {
rm -f "$SRCDIR/.scmversion"
if [[ -e "$SRCDIR/$APPLIEDPATCHFILE" ]]; then
patch -p1 -R -d "$SRCDIR" < "$SRCDIR/$APPLIEDPATCHFILE" &> /dev/null
rm -f "$SRCDIR/$APPLIEDPATCHFILE"
# If $SRCDIR was a git repo, make sure git actually sees that
# we've reverted our patch above.
[[ -d $SRCDIR/.git ]] && (cd $SRCDIR && git update-index -q --refresh)
fi
remove_patches
# If $SRCDIR was a git repo, make sure git actually sees that
# we've reverted our patch(es).
[[ -d $SRCDIR/.git ]] && (cd $SRCDIR && git update-index -q --refresh)
# restore original .config and vmlinux if they were removed with mrproper
[[ -e $TEMPDIR/.config ]] && mv -f $TEMPDIR/.config $SRCDIR/
@ -327,7 +347,8 @@ module_name_string() {
}
usage() {
echo "usage: $(basename $0) [options] <patch file>" >&2
echo "usage: $(basename $0) [options] <patch1 ... patchN>" >&2
echo " patchN Input patchfile(s)" >&2
echo " -h, --help Show this help message" >&2
echo " -r, --sourcerpm Specify kernel source RPM" >&2
echo " -s, --sourcedir Specify kernel source directory" >&2
@ -406,16 +427,21 @@ while [[ $# -gt 0 ]]; do
echo "WARNING: Skipping gcc version matching check (not recommended)"
SKIPGCCCHECK=1
;;
--)
[[ -z "$2" ]] && die "no patch file specified"
[[ ! -f "$2" ]] && die "patch file '$2' not found"
PATCHFILE=$(readlink -f "$2")
break
*)
[[ "$1" = "--" ]] && shift && continue
[[ ! -f "$1" ]] && die "patch file '$1' not found"
PATCH_LIST+=($(readlink -f "$1"))
;;
esac
shift
done
if [[ ${#PATCH_LIST[@]} -eq 0 ]]; then
warn "no patch file(s) specified"
usage
exit 1
fi
# ensure cachedir and tempdir are setup properly and cleaned
mkdir -p "$TEMPDIR" || die "Couldn't create $TEMPDIR"
rm -rf "$TEMPDIR"/*
@ -441,12 +467,17 @@ fi
[[ -z $TARGETS ]] && TARGETS="vmlinux modules"
# If no kpatch module name was provided on the command line, derive one
# from the .patch filename
# If no kpatch module name was provided on the command line:
# - For single input .patch, use the patch filename
# - For multiple input .patches, use "patch"
if [[ -z $MODNAME ]] ; then
MODNAME=$(basename "$PATCHFILE")
if [[ "$MODNAME" =~ \.patch$ ]] || [[ "$MODNAME" =~ \.diff$ ]]; then
MODNAME="${MODNAME%.*}"
if [[ ${#PATCH_LIST[@]} -eq 1 ]]; then
MODNAME=$(basename "${PATCH_LIST[0]}")
if [[ "$MODNAME" =~ \.patch$ ]] || [[ "$MODNAME" =~ \.diff$ ]]; then
MODNAME="${MODNAME%.*}"
fi
else
MODNAME="patch"
fi
MODNAME=$(module_name_string "$MODNAME")
@ -604,10 +635,11 @@ fi
# unsupported kernel option checking: CONFIG_DEBUG_INFO_SPLIT
grep -q "CONFIG_DEBUG_INFO_SPLIT=y" "$CONFIGFILE" && die "kernel option 'CONFIG_DEBUG_INFO_SPLIT' not supported"
echo "Testing patch file"
echo "Testing patch file(s)"
cd "$SRCDIR" || die
patch -N -p1 --dry-run < "$PATCHFILE" || die "source patch file failed to apply"
cp "$PATCHFILE" "$APPLIEDPATCHFILE" || die
apply_patches
remove_patches
cp -LR "$DATADIR/patch" "$TEMPDIR" || die
if [[ $ARCH = "ppc64le" ]]; then
@ -627,7 +659,7 @@ unset KPATCH_GCC_TEMPDIR
CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " make "-j$CPUS" $TARGETS >> "$LOGFILE" 2>&1 || die
echo "Building patched kernel"
patch -N -p1 < "$APPLIEDPATCHFILE" >> "$LOGFILE" 2>&1 || die
apply_patches
mkdir -p "$TEMPDIR/orig" "$TEMPDIR/patched"
KPATCH_GCC_TEMPDIR=$TEMPDIR
export KPATCH_GCC_TEMPDIR