Skip to content

Commit 398103d

Browse files
committed
Allow OOT modules to be built with non-distro kernels
Previously OOT-module builds used `--sourcedir` to specify oot-module source directory which was a bit confusing and also denied users ability to build kpatches agains oot modules built against non-distro kernels. This patch adds `-p/--oot-module-src` option to specify source dir for oot module while keeping `--sourcedir` for kernel source directory specification. I also tried to disambiguate `SRCDIR` in kpatch-build a bit. Now there are 3 variables: - `KERNEL_SRCDIR` - contains path to kernel source directory - `OOT_MODULEL_SRCDIR` - contains path to out-of-tree module source directory - `SRCDIR` - can be set to either of the above and is used for patch-related actions Another attempt at this was done by @omatiusha in dynup#1234 Signed-off-by: Artem Savkov <asavkov@redhat.com>
1 parent a9b82fe commit 398103d

File tree

3 files changed

+67
-56
lines changed

3 files changed

+67
-56
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,7 @@ Yes! There's a few requirements, and the feature is still in its infancy.
569569

570570
1. You need to use the `--oot-module` flag to specify the version of the
571571
module that's currently running on the machine.
572-
2. `--sourcedir` has to be passed with a directory containing the same
572+
2. `--oot-module-src` has to be passed with a directory containing the same
573573
version of code as the running module, all set up and ready to build with a
574574
`make` command. For example, some modules need `autogen.sh` and
575575
`./configure` to have been run with the appropriate flags to match the
@@ -585,7 +585,7 @@ built separately.
585585

586586
***Sample invocation***
587587

588-
`kpatch-build --sourcedir ~/test/ --target default --oot-module /lib/modules/$(uname -r)/extra/test.ko test.patch`
588+
`kpatch-build --oot-module-src ~/test/ --target default --oot-module /lib/modules/$(uname -r)/extra/test.ko test.patch`
589589

590590

591591
Get involved

kpatch-build/kpatch-build

Lines changed: 57 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ SCRIPTDIR="$(readlink -f "$(dirname "$(type -p "$0")")")"
4141
ARCH="$(uname -m)"
4242
CPUS="$(getconf _NPROCESSORS_ONLN)"
4343
CACHEDIR="${CACHEDIR:-$HOME/.kpatch}"
44-
SRCDIR="$CACHEDIR/src"
44+
KERNEL_SRCDIR="$CACHEDIR/src"
4545
RPMTOPDIR="$CACHEDIR/buildroot"
4646
VERSIONFILE="$CACHEDIR/version"
4747
TEMPDIR="$CACHEDIR/tmp"
@@ -152,13 +152,13 @@ cleanup() {
152152
remove_patches
153153

154154
# restore original vmlinux if it was overwritten by sourcedir build
155-
[[ -e "$TEMPDIR/vmlinux" ]] && mv -f "$TEMPDIR/vmlinux" "$SRCDIR/"
155+
[[ -e "$TEMPDIR/vmlinux" ]] && mv -f "$TEMPDIR/vmlinux" "$KERNEL_SRCDIR/"
156156

157157
# restore original link-vmlinux.sh if we updated it for the build
158-
[[ -e "$TEMPDIR/link-vmlinux.sh" ]] && mv -f "$TEMPDIR/link-vmlinux.sh" "$SRCDIR/scripts"
158+
[[ -e "$TEMPDIR/link-vmlinux.sh" ]] && mv -f "$TEMPDIR/link-vmlinux.sh" "$KERNEL_SRCDIR/scripts"
159159

160160
# restore original Makefile.modfinal if we updated it for the build
161-
[[ -e "$TEMPDIR/Makefile.modfinal" ]] && mv -f "$TEMPDIR/Makefile.modfinal" "$SRCDIR/scripts"
161+
[[ -e "$TEMPDIR/Makefile.modfinal" ]] && mv -f "$TEMPDIR/Makefile.modfinal" "$KERNEL_SRCDIR/scripts"
162162

163163
[[ "$DEBUG" -eq 0 ]] && rm -rf "$TEMPDIR"
164164
rm -rf "$RPMTOPDIR"
@@ -540,13 +540,14 @@ usage() {
540540
echo " (can be specified multiple times)" >&2
541541
echo " -e, --oot-module Enable patching out-of-tree module," >&2
542542
echo " specify current version of module" >&2
543+
echo " -p, --oot-module-src Specify out-of-tree module source directory" >&2
543544
echo " -R, --non-replace Disable replace patch (replace is on by default)" >&2
544545
echo " --skip-cleanup Skip post-build cleanup" >&2
545546
echo " --skip-compiler-check Skip compiler version matching check" >&2
546547
echo " (not recommended)" >&2
547548
}
548549

549-
options="$(getopt -o ha:r:s:c:v:j:t:n:o:de:R -l "help,archversion:,sourcerpm:,sourcedir:,config:,vmlinux:,jobs:,target:,name:,output:,oot-module:,debug,skip-gcc-check,skip-compiler-check,skip-cleanup,non-replace" -- "$@")" || die "getopt failed"
550+
options="$(getopt -o ha:r:s:c:v:j:t:n:o:de:p:R -l "help,archversion:,sourcerpm:,sourcedir:,config:,vmlinux:,jobs:,target:,name:,output:,oot-module:,oot-module-src:,debug,skip-gcc-check,skip-compiler-check,skip-cleanup,non-replace" -- "$@")" || die "getopt failed"
550551

551552
eval set -- "$options"
552553

@@ -609,6 +610,11 @@ while [[ $# -gt 0 ]]; do
609610
OOT_MODULE="$(readlink -f "$2")"
610611
shift
611612
;;
613+
-p|--oot-module-src)
614+
[[ ! -d "$2" ]] && die "out-of-tree module source dir '$2' not found"
615+
OOT_MODULE_SRCDIR="$(readlink -f "$2")"
616+
shift
617+
;;
612618
-R|--non-replace)
613619
KLP_REPLACE=0
614620
;;
@@ -657,8 +663,8 @@ if [[ -n "$SRCRPM" ]]; then
657663
ARCHVERSION="${ARCHVERSION#alt-}"
658664
fi
659665

660-
if [[ -n "$OOT_MODULE" ]] && [[ -z "$USERSRCDIR" ]]; then
661-
warn "--oot-module requires --sourcedir"
666+
if [[ -n "$OOT_MODULE" ]] && [[ -z "$OOT_MODULE_SRCDIR" ]]; then
667+
warn "--oot-module requires --oot-module-src"
662668
exit 1
663669
fi
664670

@@ -672,21 +678,30 @@ if [[ -n "$USERSRCDIR" ]]; then
672678
warn "--archversion is incompatible with --sourcedir"
673679
exit 1
674680
fi
675-
SRCDIR="$USERSRCDIR"
681+
KERNEL_SRCDIR="$USERSRCDIR"
676682

677-
if [[ -z "$OOT_MODULE" ]]; then
678-
[[ -z "$VMLINUX" ]] && VMLINUX="$SRCDIR"/vmlinux
679-
[[ ! -e "$VMLINUX" ]] && die "can't find vmlinux"
683+
[[ -z "$VMLINUX" ]] && VMLINUX="$KERNEL_SRCDIR"/vmlinux
684+
[[ ! -e "$VMLINUX" ]] && die "can't find vmlinux"
680685

681-
# Extract the target kernel version from vmlinux in this case.
682-
ARCHVERSION="$(strings "$VMLINUX" | grep -m 1 -e "^Linux version" | awk '{ print($3); }')"
683-
else
684-
ARCHVERSION="$(modinfo -F vermagic "$OOT_MODULE" | awk '{print $1}')"
685-
fi
686+
# Extract the target kernel version from vmlinux in this case.
687+
ARCHVERSION="$(strings "$VMLINUX" | grep -m 1 -e "^Linux version" | awk '{ print($3); }')"
688+
fi
689+
690+
if [[ -n "$OOT_MODULE" ]]; then
691+
ARCHVERSION="$(modinfo -F vermagic "$OOT_MODULE" | awk '{print $1}')"
686692
fi
687693

688694
[[ -z "$ARCHVERSION" ]] && ARCHVERSION="$(uname -r)"
689695

696+
if [[ -n "$OOT_MODULE" ]]; then
697+
if [[ -z "$USERSRCDIR" ]]; then
698+
KERNEL_SRCDIR="/lib/modules/$ARCHVERSION/build/"
699+
fi
700+
SRCDIR="$OOT_MODULE_SRCDIR"
701+
else
702+
SRCDIR="$KERNEL_SRCDIR"
703+
fi
704+
690705
[[ "$SKIPCLEANUP" -eq 0 ]] && trap cleanup EXIT INT TERM HUP
691706

692707
KVER="${ARCHVERSION%%-*}"
@@ -728,18 +743,16 @@ if [[ -n "$USERSRCDIR" ]]; then
728743
echo "Using source directory at $USERSRCDIR"
729744

730745
# save original vmlinux before it gets overwritten by sourcedir build
731-
if [[ -z "$OOT_MODULE" ]] && [[ "$VMLINUX" -ef "$SRCDIR"/vmlinux ]]; then
746+
if [[ "$VMLINUX" -ef "$KERNEL_SRCDIR"/vmlinux ]]; then
732747
cp -f "$VMLINUX" "$TEMPDIR/vmlinux" || die
733748
VMLINUX="$TEMPDIR/vmlinux"
734749
fi
735-
736-
# For external modules, use the running kernel's config
737-
if [[ -n "$OOT_MODULE" ]] && [[ -z "$CONFIGFILE" ]]; then
750+
elif [[ -n "$OOT_MODULE" ]]; then
751+
if [[ -z "${CONFIGFILE}" ]]; then
738752
CONFIGFILE="/boot/config-${ARCHVERSION}"
739753
fi
740-
741-
elif [[ -e "$SRCDIR"/.config ]] && [[ -e "$VERSIONFILE" ]] && [[ "$(cat "$VERSIONFILE")" = "$ARCHVERSION" ]]; then
742-
echo "Using cache at $SRCDIR"
754+
elif [[ -e "$KERNEL_SRCDIR"/.config ]] && [[ -e "$VERSIONFILE" ]] && [[ "$(cat "$VERSIONFILE")" = "$ARCHVERSION" ]]; then
755+
echo "Using cache at $KERNEL_SRCDIR"
743756

744757
else
745758
if [[ "$DISTRO" = fedora ]] || [[ "$DISTRO" = rhel ]] || [[ "$DISTRO" = ol ]] || [[ "$DISTRO" = centos ]]; then
@@ -765,19 +778,19 @@ else
765778
rpmbuild -D "_topdir $RPMTOPDIR" -bp --nodeps "--target=$(uname -m)" "$RPMTOPDIR"/SPECS/kernel$ALT.spec 2>&1 | logger ||
766779
die "rpmbuild -bp failed. you may need to run 'yum-builddep kernel' first."
767780

768-
mv "$RPMTOPDIR"/BUILD/kernel-*/linux-* "$SRCDIR" 2>&1 | logger || die
781+
mv "$RPMTOPDIR"/BUILD/kernel-*/linux-* "$KERNEL_SRCDIR" 2>&1 | logger || die
769782
rm -rf "$RPMTOPDIR"
770-
rm -rf "$SRCDIR/.git"
783+
rm -rf "$KERNEL_SRCDIR/.git"
771784

772785
if [[ "$ARCHVERSION" == *-* ]]; then
773-
sed -i "s/^EXTRAVERSION.*/EXTRAVERSION = -${ARCHVERSION##*-}/" "$SRCDIR/Makefile" || die
786+
sed -i "s/^EXTRAVERSION.*/EXTRAVERSION = -${ARCHVERSION##*-}/" "$KERNEL_SRCDIR/Makefile" || die
774787
fi
775788

776789
echo "$ARCHVERSION" > "$VERSIONFILE" || die
777790

778-
[[ -z "$CONFIGFILE" ]] && CONFIGFILE="$SRCDIR/configs/kernel$ALT-$KVER-$ARCH.config"
791+
[[ -z "$CONFIGFILE" ]] && CONFIGFILE="$KERNEL_SRCDIR/configs/kernel$ALT-$KVER-$ARCH.config"
779792

780-
(cd "$SRCDIR" && make mrproper 2>&1 | logger) || die
793+
(cd "$KERNEL_SRCDIR" && make mrproper 2>&1 | logger) || die
781794

782795
elif [[ "$DISTRO" = ubuntu ]] || [[ "$DISTRO" = debian ]]; then
783796

@@ -806,25 +819,25 @@ else
806819
echo "Downloading and unpacking the kernel source for $ARCHVERSION"
807820
# Download source deb pkg
808821
(dget -u "$url/${pkgname}/${dscname}" 2>&1) | logger || die "dget: Could not fetch/unpack $url/${pkgname}/${dscname}"
809-
mv "${pkgname}-$KVER" "$SRCDIR" || die
822+
mv "${pkgname}-$KVER" "$KERNEL_SRCDIR" || die
810823
[[ -z "$CONFIGFILE" ]] && CONFIGFILE="/boot/config-${ARCHVERSION}"
811824
if [[ "$ARCHVERSION" == *-* ]]; then
812-
echo "-${ARCHVERSION#*-}" > "$SRCDIR/localversion" || die
825+
echo "-${ARCHVERSION#*-}" > "$KERNEL_SRCDIR/localversion" || die
813826
fi
814827
# for some reason the Ubuntu kernel versions don't follow the
815828
# upstream SUBLEVEL; they are always at SUBLEVEL 0
816-
sed -i "s/^SUBLEVEL.*/${sublevel}/" "$SRCDIR/Makefile" || die
829+
sed -i "s/^SUBLEVEL.*/${sublevel}/" "$KERNEL_SRCDIR/Makefile" || die
817830
echo "$ARCHVERSION" > "$VERSIONFILE" || die
818831

819832
else
820833
die "Unsupported distribution"
821834
fi
822835
fi
823836

824-
[[ -z "$CONFIGFILE" ]] && CONFIGFILE="$SRCDIR"/.config
837+
[[ -z "$CONFIGFILE" ]] && CONFIGFILE="$KERNEL_SRCDIR"/.config
825838
[[ ! -e "$CONFIGFILE" ]] && die "can't find config file"
826-
if [[ ! "$CONFIGFILE" -ef "$SRCDIR"/.config ]] ; then
827-
cp -f "$CONFIGFILE" "$SRCDIR/.config" || die
839+
if [[ -z "$OOT_MODULE" && ! "$CONFIGFILE" -ef "$KERNEL_SRCDIR"/.config ]] ; then
840+
cp -f "$CONFIGFILE" "$KERNEL_SRCDIR/.config" || die
828841
fi
829842

830843
# kernel option checking
@@ -887,12 +900,12 @@ grep -q "CONFIG_GCC_PLUGIN_RANDSTRUCT=y" "$CONFIGFILE" && die "kernel option 'CO
887900
# link-vmlinux.sh and Makefile.modfinal since kpatch doesn't care about
888901
# that anyway.
889902
if grep -q "CONFIG_DEBUG_INFO_BTF=y" "$CONFIGFILE" ; then
890-
cp -f "$SRCDIR/scripts/link-vmlinux.sh" "$TEMPDIR/link-vmlinux.sh" || die
891-
sed -i 's/CONFIG_DEBUG_INFO_BTF/DISABLED_FOR_KPATCH_BUILD/g' "$SRCDIR"/scripts/link-vmlinux.sh || die
903+
cp -f "$KERNEL_SRCDIR/scripts/link-vmlinux.sh" "$TEMPDIR/link-vmlinux.sh" || die
904+
sed -i 's/CONFIG_DEBUG_INFO_BTF/DISABLED_FOR_KPATCH_BUILD/g' "$KERNEL_SRCDIR"/scripts/link-vmlinux.sh || die
892905

893-
if [[ -e "$SRCDIR/scripts/Makefile.modfinal" ]]; then
894-
cp -f "$SRCDIR/scripts/Makefile.modfinal" "$TEMPDIR/Makefile.modfinal" || die
895-
sed -i 's/CONFIG_DEBUG_INFO_BTF_MODULES/DISABLED_FOR_KPATCH_BUILD/g' "$SRCDIR"/scripts/Makefile.modfinal || die
906+
if [[ -e "$KERNEL_SRCDIR/scripts/Makefile.modfinal" ]]; then
907+
cp -f "$KERNEL_SRCDIR/scripts/Makefile.modfinal" "$TEMPDIR/Makefile.modfinal" || die
908+
sed -i 's/CONFIG_DEBUG_INFO_BTF_MODULES/DISABLED_FOR_KPATCH_BUILD/g' "$KERNEL_SRCDIR"/scripts/Makefile.modfinal || die
896909
fi
897910
fi
898911

@@ -985,7 +998,7 @@ if [[ ! -e "$TEMPDIR/changed_objs" ]]; then
985998
die "no changed objects found"
986999
fi
9871000

988-
[[ -n "$OOT_MODULE" ]] || grep -q vmlinux "$SRCDIR/Module.symvers" || die "truncated $SRCDIR/Module.symvers file"
1001+
grep -q vmlinux "$KERNEL_SRCDIR/Module.symvers" || die "truncated $KERNEL_SRCDIR/Module.symvers file"
9891002

9901003
if [[ "$CONFIG_MODVERSIONS" -eq 1 ]]; then
9911004
while read -ra sym_line; do
@@ -1050,9 +1063,8 @@ ERROR=0
10501063

10511064
# Prepare OOT module symvers file
10521065
if [[ -n "$OOT_MODULE" ]]; then
1053-
BUILDDIR="/lib/modules/$ARCHVERSION/build/"
1054-
cp -f "$SRCDIR/Module.symvers" "$TEMPDIR/Module.symvers" || die
1055-
awk '{ print $1 "\t" $2 "\t" $3 "\t" $4}' "${BUILDDIR}/Module.symvers" >> "$TEMPDIR/Module.symvers"
1066+
cp -f "$OOT_MODULE_SRCDIR/Module.symvers" "$TEMPDIR/Module.symvers" || die
1067+
awk '{ print $1 "\t" $2 "\t" $3 "\t" $4}' "${KERNEL_SRCDIR}/Module.symvers" >> "$TEMPDIR/Module.symvers"
10561068
fi
10571069

10581070
for i in $FILES; do
@@ -1138,7 +1150,7 @@ if [[ -z "$USERSRCDIR" ]] && [[ "$DISTRO" = ubuntu ]]; then
11381150
# UBUNTU: add UTS_UBUNTU_RELEASE_ABI to utsrelease.h after regenerating it
11391151
UBUNTU_ABI="${ARCHVERSION#*-}"
11401152
UBUNTU_ABI="${UBUNTU_ABI%-*}"
1141-
echo "#define UTS_UBUNTU_RELEASE_ABI $UBUNTU_ABI" >> "$SRCDIR"/include/generated/utsrelease.h
1153+
echo "#define UTS_UBUNTU_RELEASE_ABI $UBUNTU_ABI" >> "$KERNEL_SRCDIR"/include/generated/utsrelease.h
11421154
fi
11431155

11441156
cd "$TEMPDIR/output" || die
@@ -1161,11 +1173,7 @@ else
11611173
fi
11621174

11631175
cd "$TEMPDIR/patch" || die
1164-
if [[ -z "$OOT_MODULE" ]]; then
1165-
KPATCH_BUILD="$SRCDIR"
1166-
else
1167-
KPATCH_BUILD="/lib/modules/$ARCHVERSION/build"
1168-
fi
1176+
KPATCH_BUILD="$SRCDIR"
11691177

11701178
# We no longer need kpatch-cc
11711179
for ((idx=0; idx<${#MAKEVARS[@]}; idx++)); do

man/kpatch-build.1

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ kpatch-build \- build script
66
.SH SYNOPSIS
77
kpatch-build [options] <patch file>
88
.SH DESCRIPTION
9-
This script takes a patch based on the version of the kernel
10-
currently running and creates a kernel module that will replace
11-
modified functions in the kernel such that the patched code takes
9+
This script takes a patch based on the version of the kernel
10+
currently running and creates a kernel module that will replace
11+
modified functions in the kernel such that the patched code takes
1212
effect.
1313

1414
.SH OPTIONS
@@ -21,7 +21,7 @@ effect.
2121

2222
-r|--sourcerpm
2323
Specify kernel source RPM
24-
24+
2525
-s|--sourcedir
2626
Specify kernel source directory
2727

@@ -51,6 +51,9 @@ effect.
5151
Enable patching out-of-tree module,
5252
specify current version of module
5353

54+
-p|--oot-module-src
55+
Specify out-of-tree module source directory
56+
5457
-R|--non-replace
5558
Disable replace flag of KLP
5659
(replace is on by default)
@@ -75,6 +78,6 @@ No known bugs.
7578
.SH AUTHOR
7679
Udo Seidel (udoseidel@gmx.de)
7780
.SH COPYRIGHT
78-
Copyright (C) 2014: Seth Jennings <sjenning@redhat.com>, Copyright (C)
81+
Copyright (C) 2014: Seth Jennings <sjenning@redhat.com>, Copyright (C)
7982
2013,2014: Josh Poimboeuf <jpoimboe@redhat.com>
8083

0 commit comments

Comments
 (0)