Blame split-modules

Bernhard M. Wiedemann 6ebc4a
#!/bin/bash
Bernhard M. Wiedemann 6ebc4a
# 
Bernhard M. Wiedemann 6ebc4a
# given a Module.base and modules.dep, generate list
Bernhard M. Wiedemann 6ebc4a
# of base / supported / unsupported modules
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
set -e
Bernhard M. Wiedemann 6ebc4a
export LC_COLLATE=C
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
usage()
Bernhard M. Wiedemann 6ebc4a
{
Bernhard M. Wiedemann 6ebc4a
	echo "Usage: ${0##*/} -b Module.base [-d dir] [-i] [-e] [-o outdir]"
Bernhard M. Wiedemann 6ebc4a
	echo "  -i    Ignore supported.conf errors"
Bernhard M. Wiedemann 6ebc4a
	echo "  -e    Create the -extra filelist (otherwise, treat all modules as supported)"
Bernhard M. Wiedemann 6ebc4a
}
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
options=$(getopt -o b:d:o:ie -- "$@")
Bernhard M. Wiedemann 6ebc4a
if test $? -ne 0; then
Bernhard M. Wiedemann 6ebc4a
	usage >&2
Bernhard M. Wiedemann 6ebc4a
	exit 1
Bernhard M. Wiedemann 6ebc4a
fi
Bernhard M. Wiedemann 6ebc4a
eval set -- "$options"
Bernhard M. Wiedemann 6ebc4a
opt_builddir=
Bernhard M. Wiedemann 6ebc4a
opt_out=.
Bernhard M. Wiedemann 6ebc4a
opt_dir=.
Bernhard M. Wiedemann 6ebc4a
opt_ignore_errors=false
Bernhard M. Wiedemann 6ebc4a
opt_extra=false
Bernhard M. Wiedemann 6ebc4a
while test $# -gt 0; do
Bernhard M. Wiedemann 6ebc4a
	opt=$1
Bernhard M. Wiedemann 6ebc4a
	shift
Bernhard M. Wiedemann 6ebc4a
	case "$opt" in
Bernhard M. Wiedemann 6ebc4a
	-b | -d | -o)
Bernhard M. Wiedemann 6ebc4a
		arg=$1
Bernhard M. Wiedemann 6ebc4a
		shift
Bernhard M. Wiedemann 6ebc4a
	esac
Bernhard M. Wiedemann 6ebc4a
	case "$opt" in
Bernhard M. Wiedemann 6ebc4a
	-b)
Bernhard M. Wiedemann 6ebc4a
		opt_builddir=$arg ;;
Bernhard M. Wiedemann 6ebc4a
	-d)
Bernhard M. Wiedemann 6ebc4a
		opt_dir=$arg ;;
Bernhard M. Wiedemann 6ebc4a
	-o)
Bernhard M. Wiedemann 6ebc4a
		opt_out=$arg ;;
Bernhard M. Wiedemann 6ebc4a
	-i)
Bernhard M. Wiedemann 6ebc4a
		opt_ignore_errors=true ;;
Bernhard M. Wiedemann 6ebc4a
	-e)
Bernhard M. Wiedemann 6ebc4a
		opt_extra=true ;;
Bernhard M. Wiedemann 6ebc4a
	--)
Bernhard M. Wiedemann 6ebc4a
		break ;;
Bernhard M. Wiedemann 6ebc4a
	*)
Bernhard M. Wiedemann 6ebc4a
		echo "Unknown option $opt" >&2
Bernhard M. Wiedemann 6ebc4a
		exit 1
Bernhard M. Wiedemann 6ebc4a
	esac
Bernhard M. Wiedemann 6ebc4a
done
Bernhard M. Wiedemann 6ebc4a
if test -z "$opt_builddir"; then
Bernhard M. Wiedemann 6ebc4a
	usage >&2
Bernhard M. Wiedemann 6ebc4a
	exit 1
Bernhard M. Wiedemann 6ebc4a
fi
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
trap 'rm -rf "$tmp"' EXIT
Bernhard M. Wiedemann 6ebc4a
tmp=$(mktemp -d)
Bernhard M. Wiedemann 6ebc4a
mkdir "$tmp/empty"
Bernhard M. Wiedemann 6ebc4a
2e84a6
find "$opt_dir" -type f \( -name '*.ko' -o -name '*.ko.xz' -o -name '*.ko.gz' -o -name '*.ko.zst' \) -printf '/%P\n' | \
2e84a6
	awk -F/ '{ n=$NF; gsub(/-/, "_", n); sub(/\.ko(\.xz|\.gz|\.zst)?$/, "", n); print n " " $0; }' | \
Bernhard M. Wiedemann 6ebc4a
	sort >"$tmp/all"
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
err=false
Bernhard M. Wiedemann 6ebc4a
while read mod path; do
Bernhard M. Wiedemann 6ebc4a
	if $opt_extra; then
Bernhard M. Wiedemann 6ebc4a
		support=$(/sbin/modinfo -F supported "$opt_dir/$path")
Bernhard M. Wiedemann 6ebc4a
	else
Bernhard M. Wiedemann 6ebc4a
		support=yes
Bernhard M. Wiedemann 6ebc4a
	fi
Bernhard M. Wiedemann 6ebc4a
	case "$support" in
Bernhard M. Wiedemann 6ebc4a
	yes | external)
Bernhard M. Wiedemann 6ebc4a
		echo "$mod"
Bernhard M. Wiedemann 6ebc4a
		;;
Bernhard M. Wiedemann 6ebc4a
	no)
Bernhard M. Wiedemann 6ebc4a
		;;
Bernhard M. Wiedemann 6ebc4a
	"")
32c425
		echo "warning: $mod not listed in supported.conf" >&2
Bernhard M. Wiedemann 6ebc4a
		;;
Bernhard M. Wiedemann 6ebc4a
	*)
Bernhard M. Wiedemann 6ebc4a
		echo "error: invalid support flag for $mod: $support" >&2
Bernhard M. Wiedemann 6ebc4a
		err=true
Bernhard M. Wiedemann 6ebc4a
		;;
Bernhard M. Wiedemann 6ebc4a
	esac
Bernhard M. Wiedemann 6ebc4a
done <"$tmp/all" | sort -u >"$tmp/supp"
Bernhard M. Wiedemann 6ebc4a
if $err; then
Bernhard M. Wiedemann 6ebc4a
	exit 1
Bernhard M. Wiedemann 6ebc4a
fi
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
modules_dep=$(find "$opt_dir" -type f -name modules.dep)
Bernhard M. Wiedemann 6ebc4a
if test -z "$modules_dep"; then
Bernhard M. Wiedemann 6ebc4a
	echo "Cannot find modules.dep in $opt_dir" >&2
Bernhard M. Wiedemann 6ebc4a
	exit 1
Bernhard M. Wiedemann 6ebc4a
fi
Bernhard M. Wiedemann 6ebc4a
(
Bernhard M. Wiedemann 6ebc4a
	echo '%:
Bernhard M. Wiedemann 6ebc4a
	@echo $@
Bernhard M. Wiedemann 6ebc4a
ifdef EXPLAIN
Bernhard M. Wiedemann 6ebc4a
	@for dep in $^; do echo "$$dep needed by $@"; done >> $(EXPLAIN)
Bernhard M. Wiedemann 6ebc4a
endif
Bernhard M. Wiedemann 6ebc4a
'
2e84a6
	sed -r 's:[^ ]*/([^/]*)\.ko(\.xz|\.gz|\.zst)?\>:\1:g; y/-/_/' "$modules_dep"
Bernhard M. Wiedemann 6ebc4a
) >"$tmp/dep"
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
add_dependent_modules()
Bernhard M. Wiedemann 6ebc4a
{
Bernhard M. Wiedemann 6ebc4a
	xargs -r make $MAKE_ARGS EXPLAIN=$1 -rRs -C "$tmp/empty" -f "$tmp/dep" | sort -u
Bernhard M. Wiedemann 6ebc4a
}
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
# base
bd7477
if test -f "$opt_builddir/Module.base"; then
bd7477
    sed 'y/-/_/' <"$opt_builddir/Module.base" | add_dependent_modules >"$tmp/base"
bd7477
else
bd7477
    touch "$tmp/base"
bd7477
fi
Bernhard M. Wiedemann 6ebc4a
join -j 1 -o 2.2 "$tmp/base" "$tmp/all" >"$opt_out/base-modules"
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
# base firmware
Bernhard M. Wiedemann 6ebc4a
kver=$(make $MAKE_ARGS -s -C "$opt_builddir" kernelrelease)
32c425
fw_dir=/lib/firmware/$kver
32c425
test -d $opt_dir/usr$fw_dir && fw_dir=/usr$fw_dir
32c425
if test -d "$opt_dir$fw_dir"; then
Bernhard M. Wiedemann 6ebc4a
	join <(/sbin/modinfo -F firmware \
Bernhard M. Wiedemann 6ebc4a
		$(sed "s:^:$opt_dir:" "$opt_out/base-modules") | sort) \
32c425
	     <(find "$opt_dir$fw_dir" -type f -printf '%P\n' | sort)
32c425
fi | sed "s:^:$fw_dir:" >"$opt_out/base-firmware"
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
# kmps
Bernhard M. Wiedemann 6ebc4a
for f in "$opt_builddir"/Module.*-kmp; do
bd7477
	test -f "$f" || continue
Bernhard M. Wiedemann 6ebc4a
	kmp=${f##*/Module.}
Bernhard M. Wiedemann 6ebc4a
	sed 'y/-/_/' <"$f" >"$tmp/$kmp"
Bernhard M. Wiedemann 6ebc4a
	join -j 1 -o 2.2 "$tmp/$kmp" "$tmp/all" >"$opt_out/$kmp-modules"
Bernhard M. Wiedemann 6ebc4a
	cat "$tmp/$kmp"
Bernhard M. Wiedemann 6ebc4a
done | sort -u >"$tmp/kmp-all"
Bernhard M. Wiedemann 6ebc4a
join -v1 "$tmp/supp" "$tmp/kmp-all" >"$tmp/supp-main"
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
# main
Bernhard M. Wiedemann 6ebc4a
add_dependent_modules "$tmp/supp-explain" <"$tmp/supp-main" >"$tmp/supp-all"
Bernhard M. Wiedemann 6ebc4a
if ! cmp -s "$tmp/supp-main" "$tmp/supp-all"; then
Bernhard M. Wiedemann 6ebc4a
	# FIXME: Error message not accurate if a supported KMP module is
Bernhard M. Wiedemann 6ebc4a
	# needed by a module in the main package
Bernhard M. Wiedemann 6ebc4a
	echo "The following unsupported modules are used by supported modules:" >&2
Bernhard M. Wiedemann 6ebc4a
	join -j1 -a2 <(sort "$tmp/supp-explain") \
Bernhard M. Wiedemann 6ebc4a
		 <(join -v2 "$tmp/supp-main" "$tmp/supp-all") >&2
Bernhard M. Wiedemann 6ebc4a
	echo "Please fix supported.conf." >&2
Bernhard M. Wiedemann 6ebc4a
	if ! $opt_ignore_errors; then
Bernhard M. Wiedemann 6ebc4a
		exit 1
Bernhard M. Wiedemann 6ebc4a
	fi
Bernhard M. Wiedemann 6ebc4a
fi
Bernhard M. Wiedemann 6ebc4a
join -j 1 -o 2.2 "$tmp/supp-all" "$tmp/all" >"$opt_out/main-modules"
Bernhard M. Wiedemann 6ebc4a
Bernhard M. Wiedemann 6ebc4a
# unsupported
bd7477
join -j 1 -v 2 -o 2.2 <(sort -u "$tmp/supp-all" "$tmp/kmp-all") "$tmp/all" | sort -u > "$opt_out/unsupported-modules"
bd7477
bd7477
# split again to extra and optional
bd7477
if $opt_extra && test -f "$opt_builddir/Module.optional"; then
bd7477
bd7477
    declare -A modmarks wcmarks
bd7477
    wcpaths=()
bd7477
    while read mark path; do
2e84a6
	case $path in
2e84a6
	    *.ko.xz|*.ko.gz|*.ko.zst)
2e84a6
		path=${path%.*};;
2e84a6
	esac
bd7477
	path=${path%.ko}
bd7477
	mod=${path##*/}
bd7477
	modmarks["$mod"]="$mark"
bd7477
	# paths with wildcards need to be verified sequentially, so we keep
bd7477
	# the paths in the array wcpaths and each mark in wcmarks[]
bd7477
	case "$path" in
bd7477
	    *[\*\?\[]*)
bd7477
		wcpaths[${#wcpaths[@]}]="$path"
bd7477
		wcmarks["$path"]="$mark";;
bd7477
	esac
bd7477
    done < "$opt_builddir/Module.optional"
bd7477
bd7477
    while read xpath; do
2eeb6a
	path=$xpath
2e84a6
	case $path in
2e84a6
	    *.ko.xz|*.ko.gz|*.ko.zst)
2e84a6
		path=${path%.*};;
2e84a6
	esac
bd7477
	path=${path%.ko}
bd7477
	mod=${path##*/}
bd7477
	x=${modmarks["$mod"]}
bd7477
	if [ -n "$x" ]; then
bd7477
	    test x"$x" = x"-" && echo "$xpath"
bd7477
	    continue
bd7477
	fi
Bernhard M. Wiedemann 6ebc4a
bd7477
	# unmatched modules must be handled via wildcard
bd7477
	path=${path#/lib/modules/*/kernel/}
bd7477
	for m in "${wcpaths[@]}"; do
bd7477
	    case "$path" in
bd7477
		($m)
bd7477
		    test x${wcmarks["$m"]} = x"-" && echo "$xpath"
bd7477
		    break;;
bd7477
	    esac
bd7477
	done
bd7477
    done < "$opt_out/unsupported-modules" | sort > "$tmp/unsupp-extra"
bd7477
bd7477
    cat "$tmp/supp-all" "$tmp/kmp-all" "$tmp/unsupp-extra" | \
2e84a6
	sed -r 's:[^ ]*/([^/]*)\.ko(\.xz|\.gz|\.zst)?\>:\1:g; y/-/_/' | sort -u > "$tmp/unsupp-extra-all"
bd7477
    add_dependent_modules "$tmp/unsupp-explain" <"$tmp/unsupp-extra-all" >"$tmp/unsupp-extra-dep"
bd7477
    if ! cmp -s "$tmp/unsupp-extra-all" "$tmp/unsupp-extra-dep"; then
bd7477
	echo "The following optional modules are used by extra modules:" >&2
bd7477
	join -j1 -a2 <(sort "$tmp/unsupp-explain") \
bd7477
		 <(join -v2 "$tmp/unsupp-extra-all" "$tmp/unsupp-extra-dep") >&2
bd7477
	echo "Please fix supported.conf." >&2
bd7477
	if ! $opt_ignore_errors; then
bd7477
		exit 1
bd7477
	fi
bd7477
    fi
Bernhard M. Wiedemann 6ebc4a
bd7477
    join -j 1 -v 2 "$tmp/unsupp-extra" "$opt_out/unsupported-modules" > "$opt_out/optional-modules"
bd7477
    mv "$tmp/unsupp-extra" "$opt_out/unsupported-modules"
bd7477
fi
Bernhard M. Wiedemann 6ebc4a
bd7477
exit 0