update_bootcfg(8): various improvements

- inherit a predefined set of system environment variables
  (the current set of inherited variables is: ahci; acpi; no_apic);
- auto-adjust the default menu option when lines are auto-removed;
- add variable substitution support for /etc/boot.cfg.local;
- make default menu options in boot.cfg.local relative to itself,
  allowing one to set the default to a menu option from this file.
This commit is contained in:
David van Moolenbroek 2012-10-16 00:40:35 +02:00
parent 3fab01cdb2
commit ceefd434f1
2 changed files with 88 additions and 13 deletions

View file

@ -6,26 +6,85 @@ DEFAULTCFG=/etc/boot.cfg.default
LOCALCFG=/etc/boot.cfg.local LOCALCFG=/etc/boot.cfg.local
TMP=/boot.cfg.temp TMP=/boot.cfg.temp
DIRSBASE=/boot/minix DIRSBASE=/boot/minix
INHERIT="ahci acpi no_apic"
filter_missing_entries() filter_entries()
{ {
# This routine performs three tasks:
# - substitute variables in the configuration lines;
# - remove multiboot entries that refer to nonexistent kernels;
# - adjust the default option for line removal and different files.
# The last part is handled by the awk part of the routine.
while read line while read line
do do
if ! echo "$line" | grep -s -q 'multiboot' # Substitute variables like $rootdevname and $args
line=$(eval echo \"$line\")
if ! echo "$line" | grep -sq '^menu=.*multiboot'
then then
echo "$line" echo "$line"
continue continue
fi fi
# Check if kernel presents # Check if the referenced kernel is present
kernel=`echo "$line" | sed -n 's/.*multiboot[[:space:]]*\(\/[^[:space:]]*\).*/\1/p'` kernel=`echo "$line" | sed -n 's/.*multiboot[[:space:]]*\(\/[^[:space:]]*\).*/\1/p'`
if [ ! -r "$kernel" ] if [ ! -r "$kernel" ]
then then
echo "Warning: config contains entry for \"$kernel\" which is missing! Entry skipped." 1>&2 echo "Warning: config contains entry for \"$kernel\" which is missing! Entry skipped." 1>&2
echo "menu=SKIP"
else else
echo "$line" echo "$line"
fi fi
done done | awk '
BEGIN {
count=1
base=0
default=0
}
/^menu=SKIP$/ {
# A menu entry discarded by the kernel check above
skip[count++]=1
next
}
/^menu=/ {
# A valid menu entry
skip[count++]=0
print
next
}
/^BASE=/ {
# The menu count base as passed in by count_entries()
sub(/^.*=/,"",$1)
base=$1+0
next
}
/^default=/ {
# The default option
# Correct for the menu count base and store for later
sub(/^.*=/,"",$1)
default=$1+base
next
}
{
# Any other line
print
}
END {
# If a default was given, correct for removed lines
# (do not bother to warn if the default itself is gone)
if (default) {
for (i = default; i > 0; i--)
if (skip[i]) default--;
print "default=" default
}
}
'
}
count_entries()
{
echo -n "BASE="; grep -cs '^menu=' "$1"
} }
if [ ! -b "$ROOT" ] if [ ! -b "$ROOT" ]
@ -36,14 +95,22 @@ fi
rootdevname=`echo $ROOT | sed 's/\/dev\///'` rootdevname=`echo $ROOT | sed 's/\/dev\///'`
# Construct a list of inherited arguments for boot options to use. Note that
# rootdevname must not be passed on this way, as it is changed during setup.
args=""
for k in $INHERIT; do
if sysenv | grep -sq "^$k="; then
kv=$(sysenv | grep "^$k=")
args="$args $kv"
fi
done
if [ -r $DEFAULTCFG ] if [ -r $DEFAULTCFG ]
then then
default_cfg=`cat $DEFAULTCFG` filter_entries < $DEFAULTCFG >> $TMP
# Substitute variables like $rootdevname
echo "$default_cfg" | while read line; do eval echo \"$line\" | filter_missing_entries >> $TMP; done
fi fi
if [ -e /boot/minix_latest -a -d /boot/minix_latest -o -h /boot/minix_latest ] if [ -d /boot/minix_latest -o -h /boot/minix_latest ]
then then
latest=`basename \`stat -f "%Y" /boot/minix_latest\`` latest=`basename \`stat -f "%Y" /boot/minix_latest\``
fi fi
@ -53,11 +120,19 @@ do
build_name="`basename $i`" build_name="`basename $i`"
if [ "$build_name" != "$latest" ] if [ "$build_name" != "$latest" ]
then then
echo "menu=Start MINIX 3 ($build_name):load_mods $DIRSBASE/$i/mod*;multiboot $DIRSBASE/$i/kernel rootdevname=$rootdevname" >> /$TMP echo "menu=Start MINIX 3 ($build_name):load_mods $DIRSBASE/$i/mod*;multiboot $DIRSBASE/$i/kernel rootdevname=$rootdevname $args" >> $TMP
fi fi
done done
[ -r $LOCALCFG ] && cat $LOCALCFG | filter_missing_entries >> $TMP if [ -r $LOCALCFG ]
then
# If the local config supplies a "default" option, we assume that this
# refers to one of the options in the local config itself. Therefore,
# we increase this default by the number of options already present in
# the output so far. To this end, count_entries() inserts a special
# token that is recognized and filtered out by filter_entries().
(count_entries $TMP; cat $LOCALCFG) | filter_entries >> $TMP
fi
mv $TMP /boot.cfg mv $TMP /boot.cfg

View file

@ -1,8 +1,8 @@
clear=1 clear=1
timeout=5 timeout=5
default=2 default=2
menu=Start MINIX 3:load_mods /boot/minix_default/mod*;multiboot /boot/minix_default/kernel rootdevname=$rootdevname menu=Start MINIX 3:load_mods /boot/minix_default/mod*;multiboot /boot/minix_default/kernel rootdevname=$rootdevname $args
menu=Start latest MINIX 3:load_mods /boot/minix_latest/mod*;multiboot /boot/minix_latest/kernel rootdevname=$rootdevname menu=Start latest MINIX 3:load_mods /boot/minix_latest/mod*;multiboot /boot/minix_latest/kernel rootdevname=$rootdevname $args
menu=Start latest MINIX 3 in single user mode:load_mods /boot/minix_latest/mod*;multiboot /boot/minix_latest/kernel rootdevname=$rootdevname bootopts=-s menu=Start latest MINIX 3 in single user mode:load_mods /boot/minix_latest/mod*;multiboot /boot/minix_latest/kernel rootdevname=$rootdevname bootopts=-s $args
menu=Edit menu option:edit menu=Edit menu option:edit
menu=Drop to boot prompt:prompt menu=Drop to boot prompt:prompt