Noticed a strange issue with the creation / update of /etc/resolv.conf. The
details of the system that I noticed the issue on is:
Version : FreeBSD 8.0
Patch level: not patched
Uname: FreeBSD shastry.eudaemonicsystems.net 8.0-RELEASE FreeBSD 8.0-RELEASE
#0: Thu Sep 29 22:37:51 IST 2011
I generally have a static IP 192.168.98.6 (via rc.conf) for my Beastie. The
contents of my /etc/resolv.conf is as follows:
No matter how many times I reboot the system, the resolv.conf does not get
overwritten when configured with a static IP.
I modified the /etc/rc.conf to have the flag:
The next reboot of the system caused the /etc/resolv.conf to be overwritten with
the following contents:
I was baffled with this behaviour and checked /etc/rc.d/resolv script and there
was no reason as to why "[ ! -e /etc/resolv.conf]" should fail at any given
instance. Out of curiosity executed "/bin/kenv dhcp.domain-name" which returned
with the info: kenv: unable to get dhcp.domain-name. Would it be fair to assume
that /etc/rc.d/resolv not to cause the issue?
What is causing this behaviour? Have I missed something?
Had a look at network-dhcp.html, and found /etc/dhclient.conf to be empty on my
Digging further, was looking at the scripts under /etc/rc.d, found
/etc/rc.d/named to be another script creating the /etc/resolv.conf and this was
in the routine named_precmd(). I have not enabled 'named_enable' flag in
/etc/rc.conf, while it is commented; by default; in /etc/defaults/rc.conf file.
Found /sbin/dhclient-script to be another script that creates /etc/resolv.conf,
and this; as I understand; is being referred to by
/usr/src/sbin/dhclient/clparse.c and /usr/src/sbin/dhclient/dhclient.c.
The script /sbin/dhclient-script has a case option which is:
BOUND|RENEW|REBIND|REBOOT). I suppose this is causing the function
add_new_resolv_conf() to be invoked. In this function, found the following code
(yes, I have marked the code of interest with 1***, 2***, 3*** and 4***):
1*** if [ -n "$new_domain_name_servers" ]; then
for nameserver in $new_domain_name_servers; do
echo "nameserver $nameserver" >>$tmpres
if [ -f $tmpres ]; then
if [ -f /etc/resolv.conf.tail ]; then
cat /etc/resolv.conf.tail >>$tmpres
2*** # When resolv.conf is not changed actually, we don't
# need to update it.
# If /usr is not mounted yet, we cannot use cmp, then
# the following test fails. In such case, we simply
# ignore an error and do update resolv.conf.
3*** if cmp -s $tmpres /etc/resolv.conf; then
rm -f $tmpres
# In case (e.g. during OpenBSD installs) /etc/resolv.conf
# is a symbolic link, take care to preserve the link and write
# the new data in the correct location.
to a system
if [ -f /etc/resolv.conf ]; then
cat /etc/resolv.conf > /etc/resolv.conf.save
4*** cat $tmpres > /etc/resolv.conf
rm -f $tmpres
# Try to ensure correct ownership and permissions.
chown -RL root:wheel /etc/resolv.conf
chmod -RL 644 /etc/resolv.conf
I guess, the 1***, 3*** and 4*** is causing the recreation of /etc/resolv.conf.
Is this correct? I did a small modification to 3*** which is:
if !(cmp -s $tmpres /etc/resolv.conf); then
rm -f $tmpres
This seems to have solved the issue of /etc/resolv.conf getting overwritten with
just: nameserver 192.168.98.4. This ensures that: If there is a difference
between $tmpres and /etc/resolv.conf, then it exits post removal of $tmpres. If
the execution of 3*** returns a 0, a new file gets created. I guess the
modification get the intent of 3*** working.
Have I barked up the wrong tree?
Consider the scenarios when DHCP is enabled on my laptop which is shutdown and
started at change of location of usage:
1. Office IP address space is different from the home router IP address range.
2. Office IP address space = home IP address space, router has different IP address.
3. Scenario 2 + IP address is reserved for my laptop is fixed with the MAC
address in the router.
The /sbin/dhclient-script get even more complex to handle such scenarios; yes, I
still have not yet reached that stage.
About 2***, so what are the conditions to be true to figure out that
/etc/resolv.conf has not changed? What are the checks made to see if /usr is not
yet mounted. Not sure if the code; following the comment under 2***; how it
behaves when the following is the output of mount:
/dev/ad4s1a on / (ufs, local)
devfs on /dev (devfs, local, multilabel)
/dev/ad4s1f on /home (ufs, local, soft-updates)
/dev/ad4s1d on /usr/ports (ufs, local, soft-updates)
/dev/ad4s1e on /usr/src (ufs, local, soft-updates)
procfs on /proc (procfs, local)
linprocfs on /usr/compat/linux/proc (linprocfs, local)
Now I guess the code in 3*** should also be modified to check if the
/usr/bin/cmp is available.
Would this be correct?
Simple, Specific & Insightful
This email is confidential, and may be legally privileged. If you
are not the intended recipient, you must not use or disseminate
this information in any format. If you have received this email in
error, please do delete it along with copies of it existing in any
other format, and notify the sender immediately. The sender of this
email believes it is virus free, and does not accept any liability
for any errors or omissions arising thereof.