35e1f2fc73
The time to run on tests/* data decreased from 34.517s to 30.201s. Do not allow combining of any glob meta characters, either in first or second line. The code is still buggy, it may attempt to combine modalias(abc[def]123) modalias(abc[dXf]123) into modalias(abc[d[eX]f]123) (presumably there won't be any such cases in real modules, but still). Eliminate "| head -n1" - do it with bash string ops. Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
126 lines
4.3 KiB
Bash
Executable File
126 lines
4.3 KiB
Bash
Executable File
#! /bin/bash -efu
|
|
|
|
# heavily based upon find-suggests.ksyms by Andreas Gruenbacher <agruen@suse.de>.
|
|
# with modifications by Michael Brown <Michael_E_Brown@dell.com>
|
|
#
|
|
# -- added module versioning info to modalias() symbols
|
|
# -- removed code which inspects spec files.
|
|
|
|
IFS=$'\n'
|
|
|
|
#
|
|
# Initially, dont generate modalias() lines for kernel package. This needs
|
|
# additional discussion. Would like to eventually add them for
|
|
# completeness, so that we can determine when drivers are folded into
|
|
# mainline kernel.
|
|
#
|
|
is_kernel_package=""
|
|
case "${1:-}" in
|
|
kernel-module-*) ;; # Fedora kernel module package names start with
|
|
# kernel-module.
|
|
kernel*) is_kernel_package=1 ;;
|
|
esac
|
|
|
|
if ! [ -z "$is_kernel_package" ]; then
|
|
cat > /dev/null
|
|
exit 0
|
|
fi
|
|
|
|
# Check for presence of the commands used.
|
|
# "command" is a builtin, faster to use than fork+execing "which" - see
|
|
# https://pubs.opengroup.org/onlinepubs/9699919799/utilities/command.html
|
|
command -v /sbin/modinfo >/dev/null || exit 1
|
|
command -v sed >/dev/null || exit 1
|
|
command -v sort >/dev/null || exit 1
|
|
|
|
print_modaliases() {
|
|
local class="$1" variants="$2" pos="$3"
|
|
if [ -n "$variants" ]; then
|
|
echo "${class:0:pos}[$variants]${class:pos+1}"
|
|
else
|
|
[ -z "$class" ] || echo "$class"
|
|
fi
|
|
}
|
|
|
|
# Try to make "provides" list a bit smaller:
|
|
# find "mergeable" strings a-la
|
|
# modalias(pci:v0000168Cd00000023sv*sd*bc*sc*i*)
|
|
# modalias(pci:v0000168Cd00000024sv*sd*bc*sc*i*)
|
|
# modalias(pci:v0000168Cd00000027sv*sd*bc*sc*i*)
|
|
# modalias(pci:v0000168Cd00000029sv*sd*bc*sc*i*)
|
|
# replace with
|
|
# modalias(pci:v0000168Cd0000002[3479]sv*sd*bc*sc*i*)
|
|
combine_modaliases() {
|
|
local unused_len tag class variants="" pos="" n end xc
|
|
|
|
# Due to set -e, we can exit with exitcode 1 on read EOF
|
|
# and this makes our caller think we failed. "|| return 0" prevents this:
|
|
IFS=' ' read unused_len class || return 0
|
|
|
|
# For each line after the first...
|
|
while IFS=' ' read unused_len tag; do
|
|
if [ -z "$pos" ]; then
|
|
# 2nd line: after "modalias(" prefix, for each char in prev line...
|
|
n=9
|
|
end=${#class}
|
|
else
|
|
# 3rd+ lines: only check the char at the same position
|
|
n=$pos
|
|
end=$((pos + 1))
|
|
fi
|
|
# Search for aaaNbbb,aaaMbbb line pair, where N and M chars differ.
|
|
# sort -u guarantees there are no identical line pairs.
|
|
# We assume that lines will not differ only in " = version" suffix.
|
|
for ((; n < $end; n++)); do
|
|
if [ "${class:0:n}" != "${tag:0:n}" ]; then
|
|
# the prefixes already aren't the same: break
|
|
n=$end
|
|
break
|
|
fi
|
|
# If suffixes differ, go to next char
|
|
[ x"${class:n+1}" != x"${tag:n+1}" ] && continue
|
|
# aaaNbbb = aaaMbbb. If N and M aren't special...
|
|
xc=x"${class:n:1}"
|
|
[ x"[" = "$xc" -o x"]" = "$xc" ] && continue
|
|
[ x"?" = "$xc" -o x"*" = "$xc" ] && continue
|
|
xc=x"${tag:n:1}"
|
|
[ x"[" = "$xc" -o x"]" = "$xc" ] && continue
|
|
[ x"?" = "$xc" -o x"*" = "$xc" ] && continue
|
|
# Add M (and maybe N) to $variants, go to next line
|
|
variants="${variants:-${class:n:1}}${tag:n:1}"
|
|
pos=$n
|
|
break
|
|
done
|
|
if [ $n -eq $end ]; then
|
|
# This line is not mergeable with the previous one(s),
|
|
# print collected merged line and reset the state
|
|
print_modaliases "$class" "$variants" "$pos"
|
|
variants=""
|
|
pos=""
|
|
class=$tag
|
|
fi
|
|
done
|
|
# Print last collected merged line
|
|
print_modaliases "$class" "$variants" "$pos"
|
|
}
|
|
|
|
for module in $(grep -E '/lib/modules/.+\.ko(\.gz|\.bz2|\.xz|\.zst)?$') "$@"; do
|
|
modver=$(/sbin/modinfo -F version "$module")
|
|
# delete possible extra lines because some modules have *two* version tags. *cough*b44*cough*
|
|
modver=${modver%%$'\n'*} # using $'' bashism, avoid running "head -n1" process
|
|
# replace any strange chars with underscores.
|
|
modver=${modver//[^0-9a-zA-Z._]/_}
|
|
# only add version tag if it indeed has a version
|
|
[ -z "$modver" ] || modver=" = $modver"
|
|
|
|
/sbin/modinfo -F alias "$module" \
|
|
| sed -nre "s,[^][0-9a-zA-Z._:*?/-],_,g; s,(.+),modalias(\\1)$modver,p"
|
|
|
|
# Below: combining code can only possibly combine lines of equal length.
|
|
# Prepend line lengths before sort, so that same-length lines end up next
|
|
# to each other. (The lengths are discarded by combine_modaliases).
|
|
done \
|
|
| { while read line; do echo "${#line} $line"; done } \
|
|
| LC_ALL=C sort -u \
|
|
| combine_modaliases
|