Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion kpatch-build/kpatch-build
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ set -o pipefail

BASE="$PWD"
SCRIPTDIR="$(readlink -f "$(dirname "$(type -p "$0")")")"
source "$SCRIPTDIR/kpatch-funcs.sh"
ARCH="$(uname -m)"
TARGET_ARCH="${TARGET_ARCH:-$ARCH}"
CPUS="$(getconf _NPROCESSORS_ONLN)"
Expand Down Expand Up @@ -1082,7 +1083,7 @@ else
elif [[ "$DISTRO" = photon ]]; then
mv "$RPMTOPDIR"/BUILD/linux-"$KVER" "$KERNEL_SRCDIR" 2>&1 | logger || die
else
mv "$RPMTOPDIR"/BUILD/kernel-*/linux-* "$KERNEL_SRCDIR" 2>&1 | logger || die
find_rpm_linux_srcdir
fi

rm -rf "$RPMTOPDIR"
Expand Down
51 changes: 51 additions & 0 deletions kpatch-build/kpatch-funcs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/bin/bash
#
# Shared helper functions for kpatch-build (and tests).
#
# Copyright (C) 2014 Seth Jennings <sjenning@redhat.com>
# Copyright (C) 2013,2014 Josh Poimboeuf <jpoimboe@redhat.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA,
# 02110-1301, USA.

# Find and move the linux source directory from an RPM BUILD tree.
# Handles both traditional flat layout (Fedora < 42, RHEL, CentOS):
# BUILD/kernel-6.12.0/linux-6.12.0-100.fc41.x86_64/
# and nested layout (Fedora 42+):
# BUILD/kernel-6.14.0-build/kernel-6.14/linux-6.14.0-63.fc42.x86_64/
#
# Uses: RPMTOPDIR, KERNEL_SRCDIR (must be set by caller)
find_rpm_linux_srcdir() {
shopt -s nullglob
local dirs=( "$RPMTOPDIR"/BUILD/kernel-*/linux-* )
shopt -u nullglob

if [[ ${#dirs[@]} -eq 1 ]]; then
mv "${dirs[0]}" "$KERNEL_SRCDIR" 2>&1 | logger || die
elif [[ ${#dirs[@]} -gt 1 ]]; then
die "Multiple linux-* directories found in BUILD: ${dirs[*]}"
else
local found
found=$(find "$RPMTOPDIR/BUILD" -maxdepth 3 -type d -name "linux-*" \
! -path "*/configs/*")
if [[ -z "$found" ]]; then
die "Could not find linux source directory under $RPMTOPDIR/BUILD"
elif [[ $(echo "$found" | wc -l) -gt 1 ]]; then
die "Multiple linux source directories under $RPMTOPDIR/BUILD: $found"
else
mv "$found" "$KERNEL_SRCDIR" 2>&1 | logger || die
fi
fi
}
69 changes: 69 additions & 0 deletions test/unit/test-fedora-source-nesting.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/bin/bash
# Test find_rpm_linux_srcdir() from kpatch-build.
#
# Verifies source directory detection across RPM BUILD layouts:
# Flat: BUILD/kernel-6.12.0/linux-6.12.0-100.fc41.x86_64/ (Fedora <42, RHEL, CentOS)
# Nested: BUILD/kernel-6.14.0-build/kernel-6.14/linux-6.14.0-63.fc42.x86_64/ (Fedora 42+)
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"

# Stub kpatch-build helpers so die doesn't exit and logger doesn't need a logfile.
die() { echo "die: $*" >&2; return 1; }
logger() { cat >/dev/null; }

source "$SCRIPT_DIR/kpatch-build/kpatch-funcs.sh"

TESTDIR=$(mktemp -d)
trap 'rm -rf "$TESTDIR"' EXIT
ERRORS=0

# Create a BUILD tree, run find_rpm_linux_srcdir, check result.
# $1 = test name
# $2 = expected: "ok" (source moved) or "fail" (die called)
# $3... = paths to create under BUILD/
assert_layout() {
local name="$1" expect="$2"; shift 2
local dir="$TESTDIR/$name"
local rc=0

mkdir -p "$dir/BUILD" "$dir/dest"
for p in "$@"; do mkdir -p "$dir/BUILD/$p"; done

RPMTOPDIR="$dir" KERNEL_SRCDIR="$dir/dest/linux" \
find_rpm_linux_srcdir 2>/dev/null || rc=$?

case "$expect" in
ok) [[ $rc -eq 0 && -d "$dir/dest/linux" ]] || { echo "FAIL $name"; ((ERRORS++)); return; } ;;
fail) [[ $rc -ne 0 ]] || { echo "FAIL $name — expected error"; ((ERRORS++)); return; } ;;
esac
echo "ok $name"
}

# Flat layout: Fedora 41 / RHEL / CentOS
assert_layout "flat-fc41-x86_64" ok "kernel-6.12.0/linux-6.12.0-100.fc41.x86_64"
assert_layout "flat-fc41-aarch64" ok "kernel-6.12.0/linux-6.12.0-100.fc41.aarch64"
assert_layout "flat-rhel9" ok "kernel-5.14.0/linux-5.14.0-362.el9.x86_64"

# Nested layout: Fedora 42+
assert_layout "nested-fc42" ok "kernel-6.14.0-build/kernel-6.14/linux-6.14.0-63.fc42.x86_64"
assert_layout "nested-fc42-arm" ok "kernel-6.14.0-build/kernel-6.14/linux-6.14.0-63.fc42.aarch64"

# configs/linux-* dirs must be ignored by the nested search
assert_layout "nested-with-configs" ok "kernel-6.14.0-build/configs/linux-extra" \
"kernel-6.14.0-build/kernel-6.14/linux-6.14.0-63.fc42.x86_64"

# Error: ambiguous (multiple matches)
assert_layout "multi-flat" fail "kernel-6.14.0/linux-6.14.0-aaa" \
"kernel-6.14.0/linux-6.14.0-bbb"
assert_layout "multi-nested" fail "kernel-6.14.0-build/kernel-6.14/linux-aaa" \
"kernel-6.14.0-build/kernel-6.14/linux-bbb"

# Error: nothing to find
assert_layout "empty-build" fail
assert_layout "no-linux-dir" fail "kernel-6.14.0-build/kernel-6.14/sources"
assert_layout "too-deep" fail "a/b/c/d/linux-6.14.0"

echo ""
[[ $ERRORS -gt 0 ]] && { echo "$ERRORS test(s) failed"; exit 1; }
echo "All tests passed."