Justin Vreeland 794d92
#!/bin/bash
Justin Vreeland 794d92
#
Justin Vreeland 794d92
# This script takes the merged config files and processes them through oldconfig
Justin Vreeland 794d92
# and listnewconfig
Justin Vreeland 794d92
#
Justin Vreeland 1fc083
# Globally disable suggestion of appending '|| exit' or '|| return' to cd/pushd/popd commands
Justin Vreeland 1fc083
# shellcheck disable=SC2164
Justin Vreeland 794d92
Justin Vreeland 794d92
usage()
Justin Vreeland 794d92
{
Justin Vreeland 794d92
	# alphabetical order please
Justin Vreeland 794d92
	echo "process_configs.sh [ options ] package_name kernel_version"
Justin Vreeland 794d92
	echo "     -a: report all errors, equivalent to [-c -n -w -i]"
Justin Vreeland 794d92
	echo "     -c: error on mismatched config options"
Justin Vreeland 794d92
	echo "     -i: continue on error"
Justin Vreeland 794d92
	echo "     -n: error on unset config options"
Justin Vreeland 794d92
	echo "     -t: test run, do not overwrite original config"
Justin Vreeland 794d92
	echo "     -w: error on misconfigured config options"
Justin Vreeland 794d92
	echo "     -z: commit new configs to pending directory"
Justin Vreeland 1fc083
	echo ""
Justin Vreeland 1fc083
	echo "     A special CONFIG file tag, process_configs_known_broken can be added as a"
Justin Vreeland 1fc083
	echo "     comment to any CONFIG file.  This tag indicates that there is no way to "
Justin Vreeland 1fc083
	echo "     fix a CONFIG's entry.  This tag should only be used in extreme cases"
Justin Vreeland 1fc083
	echo "     and is not to be used as a workaround to solve CONFIG problems."
Justin Vreeland 794d92
	exit 1
Justin Vreeland 794d92
}
Justin Vreeland 794d92
Justin Vreeland 794d92
die()
Justin Vreeland 794d92
{
Justin Vreeland 794d92
	echo "$1"
Justin Vreeland 794d92
	exit 1
Justin Vreeland 794d92
}
Justin Vreeland 794d92
Justin Vreeland 794d92
# stupid function to find top of tree to do kernel make configs
Justin Vreeland 794d92
switch_to_toplevel()
Justin Vreeland 794d92
{
Justin Vreeland 794d92
	path="$(pwd)"
Justin Vreeland 794d92
	while test -n "$path"
Justin Vreeland 794d92
	do
Justin Vreeland 1fc083
		test -e "$path"/MAINTAINERS && \
Justin Vreeland 1fc083
			test -d "$path"/drivers && \
Justin Vreeland 794d92
			break
Justin Vreeland 794d92
Justin Vreeland 1fc083
		path=$(dirname "$path")
Justin Vreeland 794d92
	done
Justin Vreeland 794d92
Justin Vreeland 794d92
	test -n "$path"  || die "Can't find toplevel"
Justin Vreeland 794d92
	echo "$path"
Justin Vreeland 794d92
}
Justin Vreeland 794d92
Justin Vreeland 794d92
checkoptions()
Justin Vreeland 794d92
{
Justin Vreeland 794d92
	/usr/bin/awk '
Justin Vreeland 794d92
Justin Vreeland 794d92
		/is not set/ {
Justin Vreeland 794d92
			split ($0, a, "#");
Justin Vreeland 794d92
			split(a[2], b);
Justin Vreeland 794d92
			if (NR==FNR) {
Justin Vreeland 794d92
				configs[b[1]]="is not set";
Justin Vreeland 794d92
			} else {
Justin Vreeland 794d92
				if (configs[b[1]] != "" && configs[b[1]] != "is not set")
Justin Vreeland 794d92
					 print "Found # "b[1] " is not set, after generation, had " b[1] " " configs[b[1]] " in Source tree";
Justin Vreeland 794d92
			}
Justin Vreeland 794d92
		}
Justin Vreeland 794d92
Justin Vreeland 794d92
		/=/     {
Justin Vreeland 794d92
			split ($0, a, "=");
Justin Vreeland 794d92
			if (NR==FNR) {
Justin Vreeland 794d92
				configs[a[1]]=a[2];
Justin Vreeland 794d92
			} else {
Justin Vreeland 794d92
				if (configs[a[1]] != "" && configs[a[1]] != a[2])
Justin Vreeland 794d92
					 print "Found "a[1]"="a[2]" after generation, had " a[1]"="configs[a[1]]" in Source tree";
Justin Vreeland 794d92
			}
Justin Vreeland 794d92
		}
Justin Vreeland 1fc083
	' "$1" "$2" > .mismatches
Justin Vreeland 794d92
Justin Vreeland 1fc083
	checkoptions_error=false
Justin Vreeland 794d92
	if test -s .mismatches
Justin Vreeland 794d92
	then
Justin Vreeland 1fc083
		while read -r LINE
Justin Vreeland 1fc083
		do
Justin Vreeland 1fc083
			if find ./ -name "$(echo "$LINE" | awk -F "=" ' { print $1 } ' | awk ' { print $2 }')" -print0 | xargs -0 grep ^ | grep -q "process_configs_known_broken"; then
Justin Vreeland 1fc083
				# This is a known broken config.
Justin Vreeland 1fc083
				# See script help warning.
Justin Vreeland 1fc083
				checkoptions_error=false
Justin Vreeland 1fc083
			else
Justin Vreeland 1fc083
				checkoptions_error=true
Justin Vreeland 1fc083
				break
Justin Vreeland 1fc083
			fi
Justin Vreeland 1fc083
		done < .mismatches
Justin Vreeland 1fc083
Justin Vreeland 1fc083
		! $checkoptions_error && return
Justin Vreeland 1fc083
Justin Vreeland 794d92
		echo "Error: Mismatches found in configuration files"
Justin Vreeland 794d92
		cat .mismatches
Justin Vreeland 794d92
		RETURNCODE=1
Justin Vreeland 794d92
		[ "$CONTINUEONERROR" ] || exit 1
Justin Vreeland 794d92
	fi
Justin Vreeland 794d92
}
Justin Vreeland 794d92
Justin Vreeland 794d92
parsenewconfigs()
Justin Vreeland 794d92
{
Justin Vreeland 794d92
	tmpdir=$(mktemp -d)
Justin Vreeland 794d92
Justin Vreeland 794d92
	# This awk script reads the output of make listnewconfig
Justin Vreeland 794d92
	# and puts it into CONFIG_FOO files. Using the output of
Justin Vreeland 794d92
	# listnewconfig is much easier to ensure we get the default
Justin Vreeland 794d92
	# output.
Justin Vreeland 1fc083
        /usr/bin/awk -v BASE="$tmpdir" '
Justin Vreeland 794d92
                /is not set/ {
Justin Vreeland 794d92
                        split ($0, a, "#");
Justin Vreeland 794d92
                        split(a[2], b);
Justin Vreeland 794d92
                        OUT_FILE=BASE"/"b[1];
Justin Vreeland 794d92
                        print $0 >> OUT_FILE;
Justin Vreeland 794d92
                }
Justin Vreeland 794d92
Justin Vreeland 794d92
                /=/     {
Justin Vreeland 794d92
                        split ($0, a, "=");
Justin Vreeland 794d92
                        OUT_FILE=BASE"/"a[1];
Justin Vreeland 794d92
                        if (a[2] == "n")
Justin Vreeland 794d92
                                print "# " a[1] " is not set" >> OUT_FILE;
Justin Vreeland 794d92
                        else
Justin Vreeland 794d92
                                print $0 >> OUT_FILE;
Justin Vreeland 794d92
                }
Justin Vreeland 794d92
Justin Vreeland 794d92
        ' .newoptions
Justin Vreeland 794d92
Justin Vreeland 794d92
	# This awk script parses the output of helpnewconfig.
Justin Vreeland 794d92
	# Each option is separated between ----- markers
Justin Vreeland 794d92
	# The goal is to put all the help text as a comment in
Justin Vreeland 794d92
	# each CONFIG_FOO file. Because of how awk works
Justin Vreeland 794d92
	# there's a lot of moving files around and catting to
Justin Vreeland 794d92
	# get what we need.
Justin Vreeland 1fc083
        /usr/bin/awk -v BASE="$tmpdir" '
Justin Vreeland 794d92
                BEGIN { inpatch=0;
Justin Vreeland 794d92
			outfile="none";
Justin Vreeland 794d92
                        symbol="none"; }
Justin Vreeland 794d92
                /^CONFIG_.*:$/ {
Justin Vreeland 794d92
                        split($0, a, ":");
Justin Vreeland 794d92
                        symbol=a[1];
Justin Vreeland 794d92
                        outfile=BASE "/fake_"symbol
Justin Vreeland 794d92
                }
Justin Vreeland 794d92
                /-----/ {
Justin Vreeland 794d92
			if (inpatch == 0) {
Justin Vreeland 794d92
				inpatch = 1;
Justin Vreeland 794d92
			}
Justin Vreeland 794d92
                        else {
Justin Vreeland 794d92
                                if (symbol != "none") {
Justin Vreeland 794d92
                                    system("cat " outfile " " BASE "/" symbol " > " BASE "/tmpf");
Justin Vreeland 794d92
                                    system("mv " BASE "/tmpf " BASE "/" symbol);
Justin Vreeland 794d92
                                    symbol="none"
Justin Vreeland 794d92
				}
Justin Vreeland 794d92
                                outfile="none"
Justin Vreeland 794d92
				inpatch = 0;
Justin Vreeland 794d92
                        }
Justin Vreeland 794d92
                }
Justin Vreeland 794d92
                !/-----/ {
Justin Vreeland 794d92
                        if (inpatch == 1 && outfile != "none") {
Justin Vreeland 794d92
                                print "# "$0 >> outfile;
Justin Vreeland 794d92
                        }
Justin Vreeland 794d92
                }
Justin Vreeland 794d92
Justin Vreeland 794d92
Justin Vreeland 794d92
        ' .helpnewconfig
Justin Vreeland 794d92
Justin Vreeland 1fc083
	pushd "$tmpdir" &> /dev/null
Justin Vreeland 794d92
	rm fake_*
Justin Vreeland 794d92
	popd &> /dev/null
Justin Vreeland 1fc083
	for f in "$tmpdir"/*; do
Justin Vreeland 1fc083
		[[ -e "$f" ]] || break
Justin Vreeland 1fc083
		cp "$f" "$SCRIPT_DIR/pending$FLAVOR/generic/"
Justin Vreeland 794d92
	done
Justin Vreeland 794d92
Justin Vreeland 1fc083
	rm -rf "$tmpdir"
Justin Vreeland 794d92
}
Justin Vreeland 794d92
Justin Vreeland 794d92
function commit_new_configs()
Justin Vreeland 794d92
{
Justin Vreeland 794d92
	# assume we are in $source_tree/configs, need to get to top level
Justin Vreeland 1fc083
	pushd "$(switch_to_toplevel)" &>/dev/null
Justin Vreeland 794d92
Justin Vreeland 1fc083
	for cfg in "$SCRIPT_DIR/${PACKAGE_NAME}${KVERREL}${SUBARCH}"*.config
Justin Vreeland 794d92
	do
Justin Vreeland 1fc083
		arch=$(head -1 "$cfg" | cut -b 3-)
Justin Vreeland 794d92
		cfgtmp="${cfg}.tmp"
Justin Vreeland 794d92
		cfgorig="${cfg}.orig"
Justin Vreeland 1fc083
		cat "$cfg" > "$cfgorig"
Justin Vreeland 794d92
Justin Vreeland 794d92
		if [ "$arch" = "EMPTY" ]
Justin Vreeland 794d92
		then
Justin Vreeland 794d92
			# This arch is intentionally left blank
Justin Vreeland 794d92
			continue
Justin Vreeland 794d92
		fi
Justin Vreeland 794d92
		echo -n "Checking for new configs in $cfg ... "
Justin Vreeland 794d92
Justin Vreeland 1fc083
		make ARCH="$arch" KCONFIG_CONFIG="$cfgorig" listnewconfig >& .listnewconfig
Justin Vreeland 794d92
		grep -E 'CONFIG_' .listnewconfig > .newoptions
Justin Vreeland 794d92
		if test -s .newoptions
Justin Vreeland 794d92
		then
Justin Vreeland 1fc083
			make ARCH="$arch" KCONFIG_CONFIG="$cfgorig" helpnewconfig >& .helpnewconfig
Justin Vreeland 794d92
			parsenewconfigs
Justin Vreeland 794d92
		fi
Justin Vreeland 794d92
		rm .newoptions
Justin Vreeland 794d92
		echo "done"
Justin Vreeland 794d92
	done
Justin Vreeland 794d92
Justin Vreeland 1fc083
	git add "$SCRIPT_DIR/pending$FLAVOR"
Justin Vreeland 794d92
	git commit -m "[redhat] AUTOMATIC: New configs"
Justin Vreeland 794d92
}
Justin Vreeland 794d92
Justin Vreeland 794d92
function process_configs()
Justin Vreeland 794d92
{
Justin Vreeland 794d92
	# assume we are in $source_tree/configs, need to get to top level
Justin Vreeland 1fc083
	pushd "$(switch_to_toplevel)" &>/dev/null
Justin Vreeland 794d92
Justin Vreeland 1fc083
	for cfg in "$SCRIPT_DIR/${PACKAGE_NAME}${KVERREL}${SUBARCH}"*.config
Justin Vreeland 794d92
	do
Justin Vreeland 1fc083
		arch=$(head -1 "$cfg" | cut -b 3-)
Justin Vreeland 794d92
		cfgtmp="${cfg}.tmp"
Justin Vreeland 794d92
		cfgorig="${cfg}.orig"
Justin Vreeland 1fc083
		cat "$cfg" > "$cfgorig"
Justin Vreeland 794d92
Justin Vreeland 794d92
		if [ "$arch" = "EMPTY" ]
Justin Vreeland 794d92
		then
Justin Vreeland 794d92
			# This arch is intentionally left blank
Justin Vreeland 794d92
			continue
Justin Vreeland 794d92
		fi
Justin Vreeland 794d92
		echo -n "Processing $cfg ... "
Justin Vreeland 794d92
Justin Vreeland 1fc083
		make ARCH="$arch" KCONFIG_CONFIG="$cfgorig" listnewconfig >& .listnewconfig
Justin Vreeland 794d92
		grep -E 'CONFIG_' .listnewconfig > .newoptions
Justin Vreeland 794d92
		if test -n "$NEWOPTIONS" && test -s .newoptions
Justin Vreeland 794d92
		then
Justin Vreeland 794d92
			echo "Found unset config items, please set them to an appropriate value"
Justin Vreeland 794d92
			cat .newoptions
Justin Vreeland 794d92
			rm .newoptions
Justin Vreeland 794d92
			RETURNCODE=1
Justin Vreeland 794d92
			[ "$CONTINUEONERROR" ] || exit 1
Justin Vreeland 794d92
		fi
Justin Vreeland 794d92
		rm .newoptions
Justin Vreeland 794d92
Justin Vreeland 794d92
		grep -E 'config.*warning' .listnewconfig > .warnings
Justin Vreeland 794d92
		if test -n "$CHECKWARNINGS" && test -s .warnings
Justin Vreeland 794d92
		then
Justin Vreeland 794d92
			echo "Found misconfigured config items, please set them to an appropriate value"
Justin Vreeland 794d92
			cat .warnings
Justin Vreeland 794d92
			rm .warnings
Justin Vreeland 794d92
			RETURNCODE=1
Justin Vreeland 794d92
			[ "$CONTINUEONERROR" ] || exit 1
Justin Vreeland 794d92
		fi
Justin Vreeland 794d92
		rm .warnings
Justin Vreeland 794d92
Justin Vreeland 794d92
		rm .listnewconfig
Justin Vreeland 794d92
Justin Vreeland 1fc083
		make ARCH="$arch" KCONFIG_CONFIG="$cfgorig" olddefconfig > /dev/null || exit 1
Justin Vreeland 1fc083
		echo "# $arch" > "$cfgtmp"
Justin Vreeland 1fc083
		cat "$cfgorig" >> "$cfgtmp"
Justin Vreeland 794d92
		if test -n "$CHECKOPTIONS"
Justin Vreeland 794d92
		then
Justin Vreeland 1fc083
			checkoptions "$cfg" "$cfgtmp"
Justin Vreeland 794d92
		fi
Justin Vreeland 794d92
		# if test run, don't overwrite original
Justin Vreeland 794d92
		if test -n "$TESTRUN"
Justin Vreeland 794d92
		then
Justin Vreeland 1fc083
			rm -f "$cfgtmp"
Justin Vreeland 794d92
		else
Justin Vreeland 1fc083
			mv "$cfgtmp" "$cfg"
Justin Vreeland 794d92
		fi
Justin Vreeland 1fc083
		rm -f "$cfgorig"
Justin Vreeland 794d92
		echo "done"
Justin Vreeland 794d92
	done
Justin Vreeland 794d92
	rm "$SCRIPT_DIR"/*.config*.old
Justin Vreeland 794d92
	popd > /dev/null
Justin Vreeland 794d92
Justin Vreeland 794d92
	echo "Processed config files are in $SCRIPT_DIR"
Justin Vreeland 794d92
}
Justin Vreeland 794d92
Justin Vreeland 794d92
CHECKOPTIONS=""
Justin Vreeland 794d92
CONTINUEONERROR=""
Justin Vreeland 794d92
NEWOPTIONS=""
Justin Vreeland 794d92
TESTRUN=""
Justin Vreeland 794d92
CHECKWARNINGS=""
Justin Vreeland 794d92
Justin Vreeland 794d92
RETURNCODE=0
Justin Vreeland 794d92
Justin Vreeland 794d92
while [[ $# -gt 0 ]]
Justin Vreeland 794d92
do
Justin Vreeland 794d92
	key="$1"
Justin Vreeland 794d92
	case $key in
Justin Vreeland 794d92
		-a)
Justin Vreeland 794d92
			CHECKOPTIONS="x"
Justin Vreeland 794d92
			CONTINUEONERROR="x"
Justin Vreeland 794d92
			NEWOPTIONS="x"
Justin Vreeland 794d92
			CHECKWARNINGS="x"
Justin Vreeland 794d92
			;;
Justin Vreeland 794d92
		-c)
Justin Vreeland 794d92
			CHECKOPTIONS="x"
Justin Vreeland 794d92
			;;
Justin Vreeland 794d92
		-h)
Justin Vreeland 794d92
			usage
Justin Vreeland 794d92
			;;
Justin Vreeland 794d92
		-i)
Justin Vreeland 794d92
			CONTINUEONERROR="x"
Justin Vreeland 794d92
			;;
Justin Vreeland 794d92
		-n)
Justin Vreeland 794d92
			NEWOPTIONS="x"
Justin Vreeland 794d92
			;;
Justin Vreeland 794d92
		-t)
Justin Vreeland 794d92
			TESTRUN="x"
Justin Vreeland 794d92
			;;
Justin Vreeland 794d92
		-w)
Justin Vreeland 794d92
			CHECKWARNINGS="x"
Justin Vreeland 794d92
			;;
Justin Vreeland 794d92
		-z)
Justin Vreeland 794d92
			COMMITNEWCONFIGS="x"
Justin Vreeland 794d92
			;;
Justin Vreeland 794d92
		*)
Justin Vreeland 794d92
			break;;
Justin Vreeland 794d92
	esac
Justin Vreeland 794d92
	shift
Justin Vreeland 794d92
done
Justin Vreeland 794d92
Justin Vreeland 794d92
PACKAGE_NAME="${1:-kernel}" # defines the package name used
Justin Vreeland 794d92
KVERREL="$(test -n "$2" && echo "-$2" || echo "")"
Justin Vreeland 794d92
SUBARCH="$(test -n "$3" && echo "-$3" || echo "")"
Justin Vreeland 794d92
FLAVOR="$(test -n "$4" && echo "-$4" || echo "-common")"
Justin Vreeland 1fc083
SCRIPT=$(readlink -f "$0")
Justin Vreeland 1fc083
SCRIPT_DIR=$(dirname "$SCRIPT")
Justin Vreeland 794d92
Justin Vreeland 794d92
# Most RHEL options are options we want in Fedora so RHEL pending settings head
Justin Vreeland 794d92
# to common/
Justin Vreeland 794d92
if [ "$FLAVOR" = "-rhel" ]
Justin Vreeland 794d92
then
Justin Vreeland 794d92
	FLAVOR="-common"
Justin Vreeland 794d92
fi
Justin Vreeland 794d92
Justin Vreeland 794d92
# to handle this script being a symlink
Justin Vreeland 1fc083
cd "$SCRIPT_DIR"
Justin Vreeland 794d92
Justin Vreeland 794d92
if test -n "$COMMITNEWCONFIGS"; then
Justin Vreeland 794d92
	commit_new_configs
Justin Vreeland 794d92
else
Justin Vreeland 794d92
	process_configs
Justin Vreeland 794d92
fi
Justin Vreeland 794d92
Justin Vreeland 794d92
exit $RETURNCODE