modalias.prov: speed up, explain and make more correct combining code

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>
This commit is contained in:
Denys Vlasenko 2023-05-07 17:43:27 +02:00
parent c39c0162a0
commit 35e1f2fc73

View File

@ -51,7 +51,7 @@ print_modaliases() {
# replace with
# modalias(pci:v0000168Cd0000002[3479]sv*sd*bc*sc*i*)
combine_modaliases() {
local unused_len tag class variants="" pos="" n
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:
@ -59,26 +59,44 @@ combine_modaliases() {
# For each line after the first...
while IFS=' ' read unused_len tag; do
# For each char in prev line...
for ((n=0; n<${#class}; n++)); do
# If aaaNbbb = aaaMbbb and N isn't "*"
# and N's position is the same as last time...
if [ "*" != "${class:n:1}" -a \
"${class:0:n}" = "${tag:0:n}" -a \
"${class:n+1}" = "${tag:n+1}" ] &&
[ -z "$pos" -o "$n" = "$pos" ]; then
# Add M (and maybe N) to $variants, go to next line
variants="${variants:-${class:n:1}}${tag:n:1}"
pos=$n
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 ${#class} ]; then
# This line is not mergeable, print collected merged line
# and reset the state
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=
variants=""
pos=""
class=$tag
fi
done
@ -87,10 +105,12 @@ combine_modaliases() {
}
for module in $(grep -E '/lib/modules/.+\.ko(\.gz|\.bz2|\.xz|\.zst)?$') "$@"; do
# | head -n1 because some modules have *two* version tags. *cough*b44*cough*
modver=$(/sbin/modinfo -F version "$module"| head -n1)
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 has a version
# only add version tag if it indeed has a version
[ -z "$modver" ] || modver=" = $modver"
/sbin/modinfo -F alias "$module" \