The rc.d mess strikes back
David Horn
dhorn2000 at gmail.com
Wed Mar 18 00:52:11 PDT 2009
On Sun, Mar 8, 2009 at 5:27 PM, Doug Barton <dougb at freebsd.org> wrote:
> Garrett Wollman wrote:
>> I've generally solved this by hacking a little script into the order
>> just after named to hold back the boot until named is able to resolve
>> an external hostname.
>
> I've been following this thread (and thinking about your previous
> posts on this topic Garrett) and I'm starting to think that having
> this as an option in the base is the Right AnswerTM. Off hand I'd say
> that we would need options for what hostname to ping, and whether to
> use the local name server or just what's in resolv.conf, but that is
> trivial stuff. Can I trouble you to post your script?
In case anyone is interested, here is my version of the "wait until
the network works" rc.d script:
#!/bin/sh
#
# Copyright (c) 2009 The FreeBSD Project. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE PROJECT ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE PROJECT BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#
# PROVIDE: network_is_working
# REQUIRE: NETWORKING
# BEFORE: DAEMON
# KEYWORD: nojail
. /etc/rc.subr
name="network_is_working"
rcvar=`set_rcvar network_is_working`
start_cmd="isworking_start"
# rc.conf variables:
#network_is_working_enable="YES"
#network_is_working_timeout="90"
#network_is_working_test="dns"
#network_is_working_host="www.freebsd.org"
# DNS test is the most basic, and can use ipv4 or ipv6 for transport, but is
# rarely blocked by firewalls, so is the default for this script. ipv4/ipv6
# selection is based upon the user /etc/resolv.conf, so not in control of
# this script. Also the slowest test, and does not respond well to ^C
# Of course dns does not stress a central server, which is a plus.
dns_test()
{
up="`host -W 1 -t A $host >/dev/null && echo -n "true"`"
}
# PING test is setup to be ipv4 only in this script, but also checks dns of
# course. icmp can be blocked by firewalls.
ping_test()
{
up="`ping -c1 -W 1 $host >/dev/null 2>&1 && echo -n "true"`"
}
# TCP test is the most robust, as it checks the default route, dns, and can
# automatically function with either ipv4 or ipv6, but of course the user must
# have a clear outbound connection to the net on port 80. While netcat (nc)
# can support proxies, no effort has been made to auto-detect, or use/pass
# proxy in this script.
tcp_test()
{
up="`echo "^D" | nc -w 1 $host 80 >/dev/null 2>&1 && echo -n "true"`"
}
isworking_start()
{
up="false"
num_nameservers="`grep -c "nameserver" /etc/resolv.conf`"
if [ $num_nameservers -eq 0 ]; then
echo ""
warn "No nameservers defined in /etc/resolv.conf"
exit 1
fi
if [ -z "`ifconfig -lu | tr " " "\n" | grep -v 'lo0'`" ]; then
echo ""
warn "No interfaces properly configured and up."
exit 1
fi
if [ -z $network_is_working_timeout ]; then
network_is_working_timeout="90"
fi
if [ -z $network_is_working_test ]; then
network_is_working_test="dns"
fi
# Use a dns name that has ipv4 host (A) record and ipv6 host (AAAA) record
# Use a host that allows both ipv4 and ipv6 ping
# Use a host that listens on tcp port 80 on both ipv4 and ipv6
if [ -z "$network_is_working_host" ]; then
network_is_working_host="www.freebsd.org"
fi
host="$network_is_working_host"
case $network_is_working_test in
[Pp][Ii][Nn][Gg])
func=ping_test
;;
[Dd][Nn][Ss])
func=dns_test
# host command takes longer, so adjust timeout
# (~ 2 sec per query per nameserver)
network_is_working_timeout=`expr "$network_is_working_timeout" / 2`
network_is_working_timeout=`expr "$network_is_working_timeout" /
"$num_nameservers"`
;;
[Tt][Cc][Pp])
func=tcp_test
;;
esac
debug "Now testing using: $func"
$func
if [ "${up}" != "true" ]; then
echo -n "Hit Ctrl+C to Abort waiting for network to come alive.."
fi
while [ "${up}" != "true" ]; do
debug "waiting for $func to return true"
$func
sleep 1 && echo -n "."
network_is_working_timeout=`expr $network_is_working_timeout - 1`
if [ "$network_is_working_timeout" -le 0 ]; then
echo ""
warn "Timeout while waiting for network to respond."
exit 1
break
fi
done
exit 0
}
load_rc_config $name
run_rc_command "$1"
Feel free to use/abuse/alter/trash/ignore as needed.
--Thanks!
--Dave
More information about the freebsd-current
mailing list