]> Zhao Yanbai Git Server - minix.git/commitdiff
update_bootcfg(8): various improvements
authorDavid van Moolenbroek <david@minix3.org>
Mon, 15 Oct 2012 22:40:35 +0000 (00:40 +0200)
committerDavid van Moolenbroek <david@minix3.org>
Tue, 16 Oct 2012 08:34:58 +0000 (10:34 +0200)
- 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.

commands/update_bootcfg/update_bootcfg.sh
etc/boot.cfg.default

index dc443ac5f8cdb3504e9f384c684913d90e49b62d..33abf6d30517d8191ab88bd46d14d9a7c80dcb88 100755 (executable)
@@ -6,26 +6,85 @@ DEFAULTCFG=/etc/boot.cfg.default
 LOCALCFG=/etc/boot.cfg.local
 TMP=/boot.cfg.temp
 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
        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
                        echo "$line"
                        continue
                fi
 
-               # Check if kernel presents
+               # Check if the referenced kernel is present
                kernel=`echo "$line" | sed -n 's/.*multiboot[[:space:]]*\(\/[^[:space:]]*\).*/\1/p'`
                if [ ! -r "$kernel" ]
                then
                        echo "Warning: config contains entry for \"$kernel\" which is missing! Entry skipped." 1>&2
+                       echo "menu=SKIP"
                else
                        echo "$line"
                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" ]
@@ -36,14 +95,22 @@ fi
 
 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 ]
 then
-       default_cfg=`cat $DEFAULTCFG`
-       # Substitute variables like $rootdevname
-       echo "$default_cfg" | while read line; do eval echo \"$line\" | filter_missing_entries >> $TMP; done
+       filter_entries < $DEFAULTCFG >> $TMP
 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
        latest=`basename \`stat -f "%Y" /boot/minix_latest\``
 fi
@@ -53,11 +120,19 @@ do
        build_name="`basename $i`"
        if [ "$build_name" != "$latest" ]
        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
 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
 
index dfc971704dcc0e73c3edb029b2de2a73f80dc09b..2ad2cc40433e48f654f19872603fb5eba1c5d16f 100644 (file)
@@ -1,8 +1,8 @@
 clear=1
 timeout=5
 default=2
-menu=Start MINIX 3:load_mods /boot/minix_default/mod*;multiboot /boot/minix_default/kernel rootdevname=$rootdevname
-menu=Start latest MINIX 3:load_mods /boot/minix_latest/mod*;multiboot /boot/minix_latest/kernel rootdevname=$rootdevname
-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 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 $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 $args
 menu=Edit menu option:edit
 menu=Drop to boot prompt:prompt