mirror_linux-firmware/copy-firmware.sh
Maxim Cournoyer 51f770404a
copy-firmware: Fix 'No such file or directory' error.
Attempting to clear the PARALLEL_ARGS_FILE variable when it was not
set would cause the above error message.  Clear it only when we know
we are using it.  This bug was only triggered when using the 'deb'
target, as it invokes the copy-firmware.sh script without any '-j'
argument, while the other install targets end up passing '-j1' when
not using parallel compression.

* copy-firmware.sh [NUM_JOBS > 1]: Only clear the content of
PARALLEL_ARGS_FILE when this condition is met.

Reported-by: Christophe Guillain <jean-christophe@guillain.net>
Signed-off-by: Maxim Cournoyer <maxim.cournoyer@gmail.com>
2025-02-04 10:28:32 +09:00

150 lines
4.0 KiB
Bash
Executable File

#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
#
# Copy firmware files based on WHENCE list
#
verbose=:
# shellcheck disable=SC2209
compress=cat
compext=
destdir=
num_jobs=1
err() {
printf "ERROR: %s\n" "$*"
exit 1
}
warn() {
printf "WARNING: %s\n" "$*"
}
has_gnu_parallel() {
if command -v parallel > /dev/null; then
if parallel --version | grep -Fqi 'gnu parallel'; then
return 0
fi
fi
return 1
}
while test $# -gt 0; do
case $1 in
-v | --verbose)
# shellcheck disable=SC2209
verbose=echo
shift
;;
-j*)
num_jobs=$(echo "$1" | sed 's/-j//')
if [ "$num_jobs" -gt 1 ] && ! has_gnu_parallel; then
err "the GNU parallel command is required to use -j"
fi
parallel_args_file=$(mktemp)
trap 'rm -f $parallel_args_file' EXIT INT QUIT TERM
shift
;;
--xz)
if test "$compext" = ".zst"; then
err "cannot mix XZ and ZSTD compression"
fi
compress="xz --compress --quiet --stdout --check=crc32"
compext=".xz"
shift
;;
--zstd)
if test "$compext" = ".xz"; then
err "cannot mix XZ and ZSTD compression"
fi
# shellcheck disable=SC2209
compress="zstd --compress --quiet --stdout"
compext=".zst"
shift
;;
*)
if test -n "$destdir"; then
err "unknown command-line options: $*"
fi
destdir="$1"
shift
;;
esac
done
if test -z "$destdir"; then
err "destination directory was not specified"
fi
if test -d "$destdir"; then
find "$destdir" -type d -empty >/dev/null || warn "destination folder is not empty."
fi
if test -e .git/config; then
$verbose "Checking that WHENCE file is formatted properly"
./check_whence.py || err "check_whence.py has detected errors."
fi
# shellcheck disable=SC2162 # file/folder name can include escaped symbols
grep -E '^(RawFile|File):' WHENCE | sed -E -e 's/^(RawFile|File): */\1 /;s/"//g' | while read k f; do
install -d "$destdir/$(dirname "$f")"
$verbose "copying/compressing file $f$compext"
if test "$compress" != "cat" && test "$k" = "RawFile"; then
$verbose "compression will be skipped for file $f"
if [ "$num_jobs" -gt 1 ]; then
echo "cat \"$f\" > \"$destdir/$f\"" >> "$parallel_args_file"
else
cat "$f" > "$destdir/$f"
fi
else
if [ "$num_jobs" -gt 1 ]; then
echo "$compress \"$f\" > \"$destdir/$f$compext\"" >> "$parallel_args_file"
else
$compress "$f" > "$destdir/$f$compext"
fi
fi
done
if [ "$num_jobs" -gt 1 ]; then
parallel -j"$num_jobs" -a "$parallel_args_file"
echo > "$parallel_args_file" # prepare for next run
fi
# shellcheck disable=SC2162 # file/folder name can include escaped symbols
grep -E '^Link:' WHENCE | sed -e 's/^Link: *//g;s/-> //g' | while read l t; do
directory="$destdir/$(dirname "$l")"
install -d "$directory"
target="$(cd "$directory" && realpath -m -s "$t")"
if test -e "$target"; then
$verbose "creating link $l -> $t"
if [ "$num_jobs" -gt 1 ]; then
echo "ln -s \"$t\" \"$destdir/$l\"" >> "$parallel_args_file"
else
ln -s "$t" "$destdir/$l"
fi
else
$verbose "creating link $l$compext -> $t$compext"
if [ "$num_jobs" -gt 1 ]; then
echo "ln -s \"$t$compext\" \"$destdir/$l$compext\"" >> "$parallel_args_file"
else
ln -s "$t$compext" "$destdir/$l$compext"
fi
fi
done
if [ "$num_jobs" -gt 1 ]; then
parallel -j"$num_jobs" -a "$parallel_args_file"
fi
# Verify no broken symlinks
if test "$(find "$destdir" -xtype l | wc -l)" -ne 0 ; then
err "Broken symlinks found:\n$(find "$destdir" -xtype l)"
fi
exit 0
# vim: et sw=4 sts=4 ts=4