Subject: bin/13871: rc.d/bootconf.sh can destroy etc.current
To: None <gnats-bugs@gnats.netbsd.org>
From: None <kre@munnari.OZ.AU>
List: netbsd-bugs
Date: 09/05/2001 20:47:17
>Number: 13871
>Category: bin
>Synopsis: rc.d/bootconf.sh can cause etc.current -> etc.current
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Sep 05 06:43:00 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator: Robert Elz
>Release: <NetBSD-current source date>
>Organization:
University of Melbourne, Computer Science
>Environment:
System (PR sent from): NetBSD brandenburg.cs.mu.OZ.AU 1.5_BETA NetBSD 1.5_BETA (BRANDENBURG) #4: Mon Dec 4 17:01:12 EST 2000 kre@brandenburg.cs.mu.OZ.AU:/usr/src/sys/arch/i386/compile/BRANDENBURG i386
System (tested on): NetBSD jade.coe.psu.ac.th 1.5W NetBSD 1.5W (KRE) #4: Fri Jun 22 11:56:33 ICT 2001 kre@kre.coe.psu.ac.th:/usr/obj/sys/compile/KRE i386
Using sources from NetBSD-current as of 2001-09-04 (via anon cvs)
>Description:
bootconf.sh almost supports arranging for the default boot
configuration to be whatever was used last time, either by
simply not having an etc.default (default boot config) or
by having the default boot config be the current boot config
(as in etc.default -> etc.current along with etc.current -> etc.network)
However, if either of those is used, then when bootconf runs
next, it will change etc.current -> etc.network into
etc.current -> etc.current
That's because of the following two lines
rm -f /etc/etc.current
ln -s /etc/etc.$conf /etc/etc.current
when $conf == current.
>How-To-Repeat:
cd /etc
rm etc.default
reboot
bad things happen
Same would happen if
ln -s etc.current etc.default
>Fix:
Three different patches are appended. Pick one, any one ...
The first avoids the problem, by making sure the bad 2 lines
don't get executed in the problem case.
The second avoids the problem by avoiding the pre-condition
for the problem ($conf should never be "current" in this case).
This one also causes the config prompt to tell you which config
will actually be used (so you know which is the default) in these
cases, which wasn't happening before.
The third is both of the above - just to make it easier for
whoever applies the patch (Luke??) if you take my advice
and fix this both ways. The 2nd patch is nicer to use,
but isn't an absolute guarantee. The first is.
There's another possible problem that I don't encounter as
I replaced the use of the read/trap method of obtaining the
desired configuration long ago, but with the current distributed
scripts it is possible for the user to type "default" at the
prompt.
That will cause
ln -s etc.default etc.current
which will probably work the first time, but next boot it
would not be pretty I think. A minor modification to the
first or third patches would avoid that (don't do the symlink
if $conf == "default" )
ps: these could be redone using if statements, I grew up on
case as the way to do string tests in sh, so that's what I use...
--- bootconf.sh.WAS Mon Oct 9 12:30:17 2000
+++ bootconf.sh Wed Sep 5 20:21:58 2001
@@ -55,8 +55,15 @@
conf=${_DUMMY}
fi
done
- rm -f /etc/etc.current
- ln -s /etc/etc.$conf /etc/etc.current
+
+ case "$conf" in
+ current)
+ ;;
+ *) rm -f /etc/etc.current
+ ln -s /etc/etc."$conf" /etc/etc.current
+ ;;
+ esac
+
if [ -f /etc/rc.conf ] ; then
. /etc/rc.conf
fi
--- bootconf.sh.WAS Mon Oct 9 12:30:17 2000
+++ bootconf.sh.ALT Wed Sep 5 20:24:17 2001
@@ -20,6 +20,14 @@
else
default=current
fi
+
+ case "$default" in
+ current)
+ def=`ls -ld /etc/etc.current 2>&1`
+ default="${def##*-> etc.}"
+ ;;
+ esac
+
spc=""
for i in /etc/etc.*
do
--- bootconf.sh.WAS Mon Oct 9 12:30:17 2000
+++ bootconf.sh.BOTH Wed Sep 5 20:25:26 2001
@@ -20,6 +20,14 @@
else
default=current
fi
+
+ case "$default" in
+ current)
+ def=`ls -ld /etc/etc.current 2>&1`
+ default="${def##*-> etc.}"
+ ;;
+ esac
+
spc=""
for i in /etc/etc.*
do
@@ -55,8 +63,15 @@
conf=${_DUMMY}
fi
done
- rm -f /etc/etc.current
- ln -s /etc/etc.$conf /etc/etc.current
+
+ case "$conf" in
+ current)
+ ;;
+ *) rm -f /etc/etc.current
+ ln -s /etc/etc."$conf" /etc/etc.current
+ ;;
+ esac
+
if [ -f /etc/rc.conf ] ; then
. /etc/rc.conf
fi
>Release-Note:
>Audit-Trail:
>Unformatted: