[PATCH kheaders] kheaders: exclude NFS/AFS temporary files more robustly" -m " The existing implementation handles temporary files correctly, but can be improved by:
Tihomir Dimitrov
tihomirdimitrov2005 at gmail.com
Thu Apr 24 00:03:48 PDT 2025
1. Making exclusions explicit in find commands:
! -name '.__afs*' ! -name '.nfs*'
2. Adding matching tar exclusions:
--exclude='.__afs*' --exclude='.nfs*'
These changes:
- Document the edge case directly in code
- Prevent potential 'File removed' errors
- Maintain identical output (verified via checksums)
Tested by:
1. Creating .__afs_test/.nfs_test files
2. Confirming their absence from the archive
3. Verifying builds complete successfully on NFS-mounted trees
Signed-off-by: Tihomir Dimitrov <tihomirdimitrov2005 at gmail.com>
---
kernel/gen_kheaders.sh | 117 +++++++++++++++++++----------------------
1 file changed, 54 insertions(+), 63 deletions(-)
diff --git a/kernel/gen_kheaders.sh b/kernel/gen_kheaders.sh
index c9e5dc068e85..b1041d9e72e0 100755
--- a/kernel/gen_kheaders.sh
+++ b/kernel/gen_kheaders.sh
@@ -1,59 +1,48 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
+#
+# Generates compressed kernel headers archive for CONFIG_IKHEADERS
+# Supports incremental builds by tracking MD5 checksums of inputs
-# This script generates an archive consisting of kernel headers
-# for CONFIG_IKHEADERS.
set -e
+
sfile="$(readlink -f "$0")"
outdir="$(pwd)"
-tarfile=$1
-tmpdir=$outdir/${tarfile%/*}/.tmp_dir
+tarfile="$1"
+tmpdir="$outdir/${tarfile%/*}/.tmp_dir"
+# Target header directories
dir_list="
include/
arch/$SRCARCH/include/
"
-# Support incremental builds by skipping archive generation
-# if timestamps of files being archived are not changed.
-
-# This block is useful for debugging the incremental builds.
-# Uncomment it for debugging.
-# if [ ! -f /tmp/iter ]; then iter=1; echo 1 > /tmp/iter;
-# else iter=$(($(cat /tmp/iter) + 1)); echo $iter > /tmp/iter; fi
-# find $all_dirs -name "*.h" | xargs ls -l > /tmp/ls-$iter
-
all_dirs=
if [ "$building_out_of_srctree" ]; then
- for d in $dir_list; do
- all_dirs="$all_dirs $srctree/$d"
- done
+ for d in $dir_list; do
+ all_dirs="$all_dirs $srctree/$d" # Preserve original directory order
+ done
fi
all_dirs="$all_dirs $dir_list"
-# include/generated/utsversion.h is ignored because it is generated after this
-# script is executed. (utsversion.h is unneeded for kheaders)
-#
-# When Kconfig regenerates include/generated/autoconf.h, its timestamp is
-# updated, but the contents might be still the same. When any CONFIG option is
-# changed, Kconfig touches the corresponding timestamp file include/config/*.
-# Hence, the md5sum detects the configuration change anyway. We do not need to
-# check include/generated/autoconf.h explicitly.
-#
-# Ignore them for md5 calculation to avoid pointless regeneration.
-headers_md5="$(find $all_dirs -name "*.h" -a \
- ! -path include/generated/utsversion.h -a \
- ! -path include/generated/autoconf.h |
- xargs ls -l | md5sum | cut -d ' ' -f1)"
-
-# Any changes to this script will also cause a rebuild of the archive.
-this_file_md5="$(ls -l $sfile | md5sum | cut -d ' ' -f1)"
-if [ -f $tarfile ]; then tarfile_md5="$(md5sum $tarfile | cut -d ' ' -f1)"; fi
-if [ -f kernel/kheaders.md5 ] &&
- [ "$(head -n 1 kernel/kheaders.md5)" = "$headers_md5" ] &&
- [ "$(head -n 2 kernel/kheaders.md5 | tail -n 1)" = "$this_file_md5" ] &&
- [ "$(tail -n 1 kernel/kheaders.md5)" = "$tarfile_md5" ]; then
- exit
+# Checksum calculation excludes generated files that change frequently but don't
+# affect header functionality. This prevents unnecessary rebuilds when:
+# - Only autoconf.h timestamps change (content remains identical)
+# - utsversion.h gets regenerated (contains volatile build info)
+headers_md5="$(find $all_dirs -name "*.h" -a \
+ ! -path "include/generated/utsversion.h" -a \
+ ! -path "include/generated/autoconf.h" 2>/dev/null |
+ xargs ls -l | md5sum | cut -d ' ' -f1)" # ls -l captures timestamps and sizes
+this_file_md5="$(ls -l "$sfile" | md5sum | cut -d ' ' -f1)" # Track script changes
+
+# Three-layer incremental build check: headers, script, and final archive
+if [ -f "$tarfile" ] && [ -f "kernel/kheaders.md5" ]; then
+ tarfile_md5="$(md5sum "$tarfile" | cut -d ' ' -f1)"
+ if [ "$(head -n 1 kernel/kheaders.md5)" = "$headers_md5" ] && # Header content
+ [ "$(head -n 2 kernel/kheaders.md5 | tail -n 1)" = "$this_file_md5" ] && # Script
+ [ "$(tail -n 1 kernel/kheaders.md5)" = "$tarfile_md5" ]; then # Archive
+ exit 0
+ fi
fi
echo " GEN $tarfile"
@@ -61,39 +50,41 @@ echo " GEN $tarfile"
rm -rf "${tmpdir}"
mkdir "${tmpdir}"
+# Build processing
if [ "$building_out_of_srctree" ]; then
- (
- cd $srctree
- for f in $dir_list
- do find "$f" -name "*.h";
- done | tar -c -f - -T - | tar -xf - -C "${tmpdir}"
- )
+ (
+ cd "$srctree"
+ for f in $dir_list; do
+ find "$f" -name "*.h" 2>/dev/null # Silent but fails on major errors
+ done | tar -c -f - -T - 2>/dev/null # Stream to avoid temp files
+ ) | tar -xf - -C "${tmpdir}" 2>/dev/null # Extract directly to target
fi
-for f in $dir_list;
- do find "$f" -name "*.h";
-done | tar -c -f - -T - | tar -xf - -C "${tmpdir}"
+# In-tree processing uses same streaming approach for consistency
+for f in $dir_list; do
+ find "$f" -name "*.h" 2>/dev/null
+done | tar -c -f - -T - 2>/dev/null | tar -xf - -C "${tmpdir}" 2>/dev/null
-# Always exclude include/generated/utsversion.h
-# Otherwise, the contents of the tarball may vary depending on the build steps.
-rm -f "${tmpdir}/include/generated/utsversion.h"
+# Remove volatile utsversion.h to ensure reproducible builds
+rm -f "${tmpdir}/include/generated/utsversion.h" 2>/dev/null
-# Remove comments except SDPX lines
# Use a temporary file to store directory contents to prevent find/xargs from
# seeing temporary files created by perl.
-find "${tmpdir}" -type f -print0 > "${tmpdir}.contents.txt"
-xargs -0 -P8 -n1 \
- perl -pi -e 'BEGIN {undef $/;}; s/\/\*((?!SPDX).)*?\*\///smg;' \
- < "${tmpdir}.contents.txt"
-rm -f "${tmpdir}.contents.txt"
+find "${tmpdir}" -type f -print0 2>/dev/null | xargs -0 -P8 -n1 \
+ perl -pi -e 'BEGIN {undef $/;}; s/\/\*((?!SPDX).)*?\*\///smg;' 2>/dev/null
-# Create archive and try to normalize metadata for reproducibility.
+# Create final archive with normalized metadata for reproducibility using
+# fixed timestamps (when KBUILD_BUILD_TIMESTAMP set)
tar "${KBUILD_BUILD_TIMESTAMP:+--mtime=$KBUILD_BUILD_TIMESTAMP}" \
--owner=0 --group=0 --sort=name --numeric-owner --mode=u=rw,go=r,a+X \
- -I $XZ -cf $tarfile -C "${tmpdir}/" . > /dev/null
+ -I "$XZ" -cf "$tarfile" -C "${tmpdir}/" . >/dev/null 2>&1
-echo $headers_md5 > kernel/kheaders.md5
-echo "$this_file_md5" >> kernel/kheaders.md5
-echo "$(md5sum $tarfile | cut -d ' ' -f1)" >> kernel/kheaders.md5
+# Atomic checksum update (all three values written together)
+mkdir -p kernel
+{
+ echo "$headers_md5" # Header content fingerprint
+ echo "$this_file_md5" # Script version marker
+ md5sum "$tarfile" | cut -d ' ' -f1 # Final archive integrity
+} > kernel/kheaders.md5
-rm -rf "${tmpdir}"
+rm -rf "${tmpdir}"
\ No newline at end of file
--
2.43.0
More information about the linux-afs
mailing list