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