kpatch-build: Add a flexible logger function

Add a logger funcition that can be used to log to both stdout and the
logfile or only to the logfile. This is needed for subsequent patches
where we introduce an alternate debug mode.

Since we're piping to a logger now, we need to set 'pipefail' otherwise
the return status of such a pipeline is always 0 (the exit status of the
logger) and we won't catch any errors.

From the bash manpage:
  The return status of a pipeline is the exit status of the last command,
  unless the pipefail option is enabled

Signed-off-by: Juerg Haefliger <juerg.haefliger@canonical.com>
This commit is contained in:
Juerg Haefliger 2017-11-07 16:23:17 +01:00
parent b5f77d0608
commit b2c00b1215
1 changed files with 32 additions and 18 deletions

View File

@ -34,6 +34,8 @@
# - Builds the patched objects with gcc flags -f[function|data]-sections
# - Runs kpatch tools to create and link the patch kernel module
set -o pipefail
BASE="$PWD"
SCRIPTDIR="$(readlink -f "$(dirname "$(type -p "$0")")")"
ARCH="$(uname -m)"
@ -71,12 +73,24 @@ die() {
exit 1
}
logger() {
local to_stdout=${1:-0}
if [[ "$to_stdout" -eq 1 ]]; then
# Log to both stdout and the logfile
tee -a "$LOGFILE"
else
# Log only to the logfile
cat >> "$LOGFILE"
fi
}
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"
patch -N -p1 --dry-run < "$patch" 2>&1 | logger || die "$patch file failed to apply"
patch -N -p1 < "$patch" 2>&1 | logger || die "$patch file failed to apply"
(( APPLIED_PATCHES++ ))
done
}
@ -364,7 +378,8 @@ usage() {
echo " -t, --target Specify custom kernel build targets" >&2
echo " -n, --name Specify the name of the kpatch module" >&2
echo " -o, --output Specify output folder" >&2
echo " -d, --debug Keep scratch files in /tmp" >&2
echo " -d, --debug Enable 'xtrace' and keep scratch files" >&2
echo " in <CACHEDIR>/tmp" >&2
echo " --skip-cleanup Skip post-build cleanup" >&2
echo " --skip-gcc-check Skip gcc version matching check" >&2
echo " (not recommended)" >&2
@ -545,21 +560,21 @@ else
echo "Downloading kernel source for $ARCHVERSION"
if [[ -z "$SRCRPM" ]]; then
if [[ "$DISTRO" = fedora ]]; then
wget -P "$TEMPDIR" "http://kojipkgs.fedoraproject.org/packages/kernel/$KVER/$KREL/src/kernel-$KVER-$KREL.src.rpm" >> "$LOGFILE" 2>&1 || die
wget -P "$TEMPDIR" "http://kojipkgs.fedoraproject.org/packages/kernel/$KVER/$KREL/src/kernel-$KVER-$KREL.src.rpm" 2>&1 | logger || die
else
rpm -q --quiet yum-utils || die "yum-utils not installed"
yumdownloader --source --destdir "$TEMPDIR" "kernel-$ARCHVERSION" >> "$LOGFILE" 2>&1 || die
yumdownloader --source --destdir "$TEMPDIR" "kernel-$ARCHVERSION" 2>&1 | logger || die
fi
SRCRPM="$TEMPDIR/kernel-$KVER-$KREL.src.rpm"
fi
echo "Unpacking kernel source"
rpm -D "_topdir $RPMTOPDIR" -ivh "$SRCRPM" >> "$LOGFILE" 2>&1 || die
rpmbuild -D "_topdir $RPMTOPDIR" -bp "--target=$(uname -m)" "$RPMTOPDIR"/SPECS/kernel.spec >> "$LOGFILE" 2>&1 ||
rpm -D "_topdir $RPMTOPDIR" -ivh "$SRCRPM" 2>&1 | logger || die
rpmbuild -D "_topdir $RPMTOPDIR" -bp "--target=$(uname -m)" "$RPMTOPDIR"/SPECS/kernel.spec 2>&1 | logger ||
die "rpmbuild -bp failed. you may need to run 'yum-builddep kernel' first."
mv "$RPMTOPDIR"/BUILD/kernel-*/linux-"${ARCHVERSION%.*}"*"${ARCHVERSION##*.}" "$SRCDIR" >> "$LOGFILE" 2>&1 || die
mv "$RPMTOPDIR"/BUILD/kernel-*/linux-"${ARCHVERSION%.*}"*"${ARCHVERSION##*.}" "$SRCDIR" 2>&1 | logger || die
rm -rf "$RPMTOPDIR"
rm -rf "$SRCDIR/.git"
@ -596,7 +611,7 @@ else
cd "$TEMPDIR" || die
echo "Downloading and unpacking the kernel source for $ARCHVERSION"
# Download source deb pkg
(dget -u "$url/${pkgname}/${dscname}" 2>&1) >> "$LOGFILE" || die "dget: Could not fetch/unpack $url/${pkgname}/${dscname}"
(dget -u "$url/${pkgname}/${dscname}" 2>&1) | logger || die "dget: Could not fetch/unpack $url/${pkgname}/${dscname}"
mv "${pkgname}-$KVER" "$SRCDIR" || die
cp "/boot/config-${ARCHVERSION}" "$SRCDIR/.config" || die
if [[ "$ARCHVERSION" == *-* ]]; then
@ -668,12 +683,12 @@ find_special_section_data
echo "Building original kernel"
./scripts/setlocalversion --save-scmversion || die
make mrproper >> "$LOGFILE" 2>&1 || die
make mrproper 2>&1 | logger || die
cp -f "$CONFIGFILE" "$SRCDIR/.config"
unset KPATCH_GCC_TEMPDIR
# $TARGETS used as list, no quotes.
# shellcheck disable=SC2086
CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " make "-j$CPUS" $TARGETS >> "$LOGFILE" 2>&1 || die
CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " make "-j$CPUS" $TARGETS 2>&1 | logger || die
echo "Building patched kernel"
apply_patches
@ -684,8 +699,7 @@ export KPATCH_GCC_TEMPDIR
# shellcheck disable=SC2086
CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " \
KBUILD_MODPOST_WARN=1 \
make "-j$CPUS" $TARGETS >> "$LOGFILE" 2>&1 || die
[[ "${PIPESTATUS[0]}" -eq 0 ]] || die
make "-j$CPUS" $TARGETS 2>&1 | logger || die
grep "undefined reference" "$LOGFILE" | grep -qv kpatch_shadow && die
grep "undefined!" "$LOGFILE" | grep -qv kpatch_shadow && die
@ -751,7 +765,7 @@ for i in $FILES; do
if [[ -e "orig/$i" ]]; then
# create-diff-object orig.o patched.o kernel-object output.o Module.symvers patch-mod-name
"$TOOLSDIR"/create-diff-object "orig/$i" "patched/$i" "$KOBJFILE" \
"output/$i" "$SRCDIR/Module.symvers" "${MODNAME//-/_}" 2>&1 | tee -a "$LOGFILE"
"output/$i" "$SRCDIR/Module.symvers" "${MODNAME//-/_}" 2>&1 | logger 1
check_pipe_status create-diff-object
# create-diff-object returns 3 if no functional change is found
[[ "$rc" -eq 0 ]] || [[ "$rc" -eq 3 ]] || ERROR="$((ERROR + 1))"
@ -798,14 +812,14 @@ fi
cd "$TEMPDIR/output" || die
# $KPATCH_LDFLAGS and result of find used as list, no quotes.
# shellcheck disable=SC2086,SC2046
ld -r $KPATCH_LDFLAGS -o ../patch/tmp_output.o $(find . -name "*.o") >> "$LOGFILE" 2>&1 || die
ld -r $KPATCH_LDFLAGS -o ../patch/tmp_output.o $(find . -name "*.o") 2>&1 | logger || die
if "$KPATCH_MODULE"; then
# Add .kpatch.checksum for kpatch script
md5sum ../patch/tmp_output.o | awk '{printf "%s\0", $1}' > checksum.tmp || die
objcopy --add-section .kpatch.checksum=checksum.tmp --set-section-flags .kpatch.checksum=alloc,load,contents,readonly ../patch/tmp_output.o || die
rm -f checksum.tmp
"$TOOLSDIR"/create-kpatch-module "$TEMPDIR"/patch/tmp_output.o "$TEMPDIR"/patch/output.o 2>&1 | tee -a "$LOGFILE"
"$TOOLSDIR"/create-kpatch-module "$TEMPDIR"/patch/tmp_output.o "$TEMPDIR"/patch/output.o 2>&1 | logger 1
check_pipe_status create-kpatch-module
else
cp "$TEMPDIR"/patch/tmp_output.o "$TEMPDIR"/patch/output.o || die
@ -816,14 +830,14 @@ cd "$TEMPDIR/patch" || die
KPATCH_BUILD="$SRCDIR" KPATCH_NAME="$MODNAME" \
KBUILD_EXTRA_SYMBOLS="$KBUILD_EXTRA_SYMBOLS" \
KPATCH_LDFLAGS="$KPATCH_LDFLAGS" \
make >> "$LOGFILE" 2>&1 || die
make 2>&1 | logger || die
if ! "$KPATCH_MODULE"; then
if [[ -z "$KPATCH_LDFLAGS" ]]; then
extra_flags="--no-klp-arch-sections"
fi
cp "$TEMPDIR/patch/$MODNAME.ko" "$TEMPDIR/patch/tmp.ko" || die
"$TOOLSDIR"/create-klp-module $extra_flags "$TEMPDIR/patch/tmp.ko" "$TEMPDIR/patch/$MODNAME.ko" 2>&1 | tee -a "$LOGFILE"
"$TOOLSDIR"/create-klp-module $extra_flags "$TEMPDIR/patch/tmp.ko" "$TEMPDIR/patch/$MODNAME.ko" 2>&1 | logger 1
check_pipe_status create-klp-module
fi