Subject: bin/21109: dhclient-script mis-handles resolv.conf sometimes
To: None <firstname.lastname@example.org>
From: None <kre@munnari.OZ.AU>
Date: 04/12/2003 20:53:00
>Synopsis: dhclient-script mis-handles resolv.conf sometimes
>Arrival-Date: Sat Apr 12 06:56:00 PDT 2003
>Originator: Robert Elz
>Release: NetBSD 1.6Q (-- current of 2003-04-12)
Prince of Songkla University
System: NetBSD delta.cs.mu.OZ.AU 1.6L NetBSD 1.6L (DELTA) #29: Fri Jan 10 11:40:50 ICT 2003 email@example.com.OZ.AU:/usr/obj/sys/DELTA i386
This is just the system I'm running send-pr from and is irrelevant.
If dhclient is run (without specifying a particular interface)
on a system with more than one interface, and it can only contact
a DHCP server on one (or less than all) of the available
interfaces, and if, before dhclient started there was an
/etc/resolv.conf that was not created by DHCP (say a fallback for
times when DHCP supplies no nameserver info, or there is no DHCP)
then after a while, rather than having an /etc/resolv.conf with
the results from DHCP, and the other saved, the fallback resolv.conf
will be in /etc/resolv.conf, and information from DHCP will have
Get a system with more than one interface. A moden laptop with
802.11 and 802.3 is a good choice for this.
Connect one of the two interfaces to a working net, complete with
a DHCP server that supplies nameserver information, and leave the
other interface disconnected (no cable for 802.3, no WEP key for
802.11 - or no AP - or just no DHCP server - having a DHCP server
which just doesn't bother to send nameserver info isn't sufficient
to trigger the bug, I don't think).
Before starting dhclient, create an /etc/resolv.conf file that
or something similar (it doesn't matter much what it contains,
just provided it isn't a resolv.conf that was previously created
with no interface specification (include -q if you prefer, most do).
After a short time (a second or two), an address should be
assigned to the working interface, and /etc/resolv.conf should
contain the nameserver information (and domain to search if any
was supplied by the DHCP server). This is the desired end state.
At this point, dhclient will (having obtained an address) vanish
into the background, and continue attempting to contact a
server for the other interface (while also renewing the lease
that has been obtained, when that becomes due).
Eventually, it will decide that it isn't going to succeed on the
unconnected interface, and run dhclient-script in its "cleanup" mode,
to put the world back to "no dhcp being attempted" state (this does
things like getting rid of the 0.0.0.0 address that dhclient needs
configured into the interface).
When that happens, dhclient-script notices that it had installed
the /etc/resolv.conf file, and as a part of its cleanup, it
restores the file that had existed previously (if there had been
none, it just leaves the file it created). This is despite
dhclient still being active on the interface that supplied the
information that was put in resolv.conf.
The patch below cause the interface name to be included in the
"signature" that dhclient-script uses to detect whether or not
it should restore the old resolv.conf - the old one will only be
restored when dhclient shuts down on the interface which supplied
the new resolv.conf information.
Note: the interface remains still not used in that part of the
script that determines whether a resolv.conf file that existed
when dhclient starts is a resolv.conf that was created by a
previous incarnation of dhclient (say, from before an OS crash)
and which therefore doesn't need to be saved. This has the
side effect of causing dhclient to use the last of the nameserver
information received, when more than one interface is successfully
configured, rather than the first, which might be preferred
normally (though it is probably rare that it will differ).
Fixing that is non-trivial (and may require some changes to
dhclient itself, rather than just the script).
--- dhclient-script Thu May 30 06:18:34 2002
+++ dhclient-script.FIXED Sat Apr 12 20:24:36 2003
@@ -5,7 +5,8 @@
-SIGNATURE="# Created by dhclient at: "
+SIGNATURE="# Created by dhclient from"
+INTSIG="$SIGNATURE $interface at: "
if [ ! -z "$new_domain_name_servers" ]; then
@@ -21,7 +22,7 @@
done < $RESOLV
- echo "$SIGNATURE$(date)" > $RESOLV
+ echo "$INTSIG$(date)" > $RESOLV
if [ ! -z "$new_domain_name" ]
echo search $new_domain_name >> $RESOLV
@@ -37,7 +38,7 @@
while read line; do
case $line in
mv $RESOLV.save $RESOLV;;