mirror of
https://git.proxmox.com/git/mirror_linux-firmware
synced 2025-05-01 12:45:57 +00:00

The copy-firmware.sh script can use the "parallel" command to parallelize some operations, but it needs the GNU version of parallel. There is another, simpler version of parallel that is part of the moreutils package, but that version confuses the has_gnu_parallel() function. So first test to make sure that the --version parameter is even recognized before trying to use it. If in the future, moreutils parallel adds support for --version, this script should still work because that version should never report "GNU parallel". Signed-off-by: Timur Tabi <ttabi@nvidia.com>
175 lines
4.8 KiB
Bash
Executable File
175 lines
4.8 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
|
|
|
|
usage() {
|
|
echo "Usage: $0 [-v] [-jN] [--xz|--zstd] <destination directory>"
|
|
}
|
|
|
|
err() {
|
|
printf "ERROR: %s\n" "$*"
|
|
usage
|
|
exit 1
|
|
}
|
|
|
|
warn() {
|
|
printf "WARNING: %s\n" "$*"
|
|
}
|
|
|
|
has_gnu_parallel() {
|
|
if command -v parallel > /dev/null; then
|
|
# The moreutils package comes with a simpler version of "parallel"
|
|
# that does not support the --version or -a options. Check for
|
|
# that first. In some distros, installing the "parallel" package
|
|
# will replace the moreutils version with the GNU version.
|
|
if ! parallel --version > /dev/null 2>&1; then
|
|
return 1
|
|
fi
|
|
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//')
|
|
num_jobs=${num_jobs:-1}
|
|
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
|
|
;;
|
|
|
|
-h|--help)
|
|
usage
|
|
exit 1
|
|
;;
|
|
|
|
-*)
|
|
# Ignore anything else that begins with - because that confuses
|
|
# the "test" command below
|
|
warn "ignoring option $1"
|
|
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
|