findcnet 5.23 KB
Newer Older
David Johnson's avatar
David Johnson committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
#!/bin/sh

#
# Find the Emulab control network interface.
#
# When called the first time (an invocation on any interface when
# /var/emulab/boot/controlif does not exist) we run DHCP and find the
# control network.
#
# On all invocations, we check the contents of that file against the
# interface we were called with and return "cnet" if we are the control
# net.  Otherwise we just return the physical interface name.
#

static_widearea_config()
{
	local iface=$1

	if [ -e /etc/emulab/isrem -a -e /etc/emulab/waconfig ]; then
		echo "Found Emulab widearea config info..."
		. /etc/emulab/waconfig
	else
		return 1
	fi

	# XXX check WA_MAC?
	if [ "$WA_BOOTMETHOD" != static ]; then
		return 1
	fi
	
	cnetif=`/sbin/ifconfig -a | \
		sed -n 's/^\([^ ]*\) *Link encap:Ethernet *HWaddr '$WA_MAC' *$/\1/ip'`

	if [ -z "$cnetif" ]; then
		echo "Could not find iface with MAC $WA_MAC; trying DHCP!"
		return 1
	elif [ -z "$WA_HOSTNAME"   -o -z "$WA_DOMAIN" -o \
	       -z "$WA_IP_ADDR"    -o -z "$WA_IP_NETMASK" -o \
	       -z "$WA_IP_GATEWAY" -o -z "$WA_IP_DNS1" ]; then
		echo "Missing static IP config vars; trying DHCP!"
		return 1
	fi

	# Make sure ifup passed us the correct interface.  If not,
	# exit successfully so that the DHCP client isn't run
	if [ "$cnetif" != "$iface" ]; then
		return 0
	fi

	# We're going ahead with the static config
	echo "Statically configuring control net on $cnetif ..."
	/sbin/ifconfig "$cnetif" inet "$WA_IP_ADDR" netmask "$WA_IP_NETMASK" up
	/sbin/route add default gateway "$WA_IP_GATEWAY"
		
        # setup resolv.conf
	echo "search $WA_DOMAIN" > /etc/resolv.conf
	echo "nameserver $WA_IP_DNS1" >> /etc/resolv.conf
	if [ -n "$WA_IP_DNS2" ]; then
		echo "nameserver $WA_IP_DNS2" >> /etc/resolv.conf
	fi

        # set hostname
	hosts_str="$WA_HOSTNAME"
	if echo "$WA_HOSTNAME" | grep -q \\.; then
		hostname "$WA_HOSTNAME"
	else
		hostname "${WA_HOSTNAME}.${WA_DOMAIN}"
		hosts_str="${WA_HOSTNAME}.${WA_DOMAIN} ${hosts_str}"
	fi

        # setup hosts file
	echo "$WA_IP_ADDR ${hosts_str}" >> /etc/hosts

        # setup a few necessary emulab files...
	echo "$cnetif" > $BOOTDIR/controlif
	if [ -e "/etc/emulab/bossnode" ]; then
		bossnode=`cat /etc/emulab/bossnode`
		i=0
		while [ $i -lt 6 ]; do
			bossip=`host -t A "$bossnode"`
			[ $? -eq 0 ] && break
			i=`expr $i + 1`
			sleep 5
		done
		
		echo `echo "$bossip" | sed -n -e 's/.*has address\s*\(.*\)/\1/p'` \
			> $BOOTDIR/bossip
	fi
	echo "$WA_HOSTNAME" > $BOOTDIR/realname
	echo "$WA_IP_GATEWAY" > $BOOTDIR/routerip
	echo "$WA_IP_ADDR" > $BOOTDIR/myip
	echo "$WA_IP_NETMASK" > $BOOTDIR/mynetmask

	return 0
}

export LANG=C
iface="$1"

cnetfile="/var/run/cnet"
cnetif=''

# We only need the lock if the file doesn't exist.
# XXX keep this lightweight as it can be called many times from
# ifquery in the udev path.
if [ -f $cnetfile ]; then
    cnetif=`cat $cnetfile`
    if [ "$cnetif" = $iface ]; then
	echo cnet
    else
	echo $iface
    fi
    exit 0
fi

lockdir=/var/lock/findcnet

. /etc/emulab/paths.sh

while ! mkdir $lockdir 2> /dev/null; do
	sleep 1
done

echo "`date`: $iface: starting" >>$LOGDIR/dhclient.log

#
# We use /var/run to store the current idea of the cnet interface
# because we want it to go away on reboot.
#

if [ -f $cnetfile ]; then
    cnetif=`cat $cnetfile`
    echo "`date`: $iface: $cnetfile already had $cnetif" >>$LOGDIR/dhclient.log
elif static_widearea_config $iface; then
    #
    # Make sure that static_widearea_config matched $iface to the target WA_MAC.
    #
    if [ "$cnetif" = "$iface" ]; then
	echo $iface > $cnetfile
	cnetif=`cat $cnetfile`
	/sbin/initctl emit -n 'emulab-findcnet-done'
    else
        #
        # If not, don't fail; there was widearea config info; but also don't
	# succeed in the final check at the end of the script.  This $iface is
	# not the control net.
        #
	cnetif=''
    fi
else
    #
    # Find a list of candidate interfaces
    #
    _iflist=`ifconfig -a | grep '^eth' | awk '{ print $1 }'`
    echo "`date`: $iface: findcnet running dhclient on: $_iflist"

    #
    # If dhclient returns success, then it has configured the first interface
    # and gone into background mode.  At that point we don't care about it any
    # more and just kill it.  We also shutdown all the other interfaces (which
    # dhclient will leave "up").
    #
    if [ -x /sbin/dhclient ] && /sbin/dhclient -q $_iflist ; then
        killall dhclient
	rm -f /var/run/dhclient.pid
        echo "`date`: $iface: findcnet dhclient returned"
	[ -f $BOOTDIR/controlif ] && cp $BOOTDIR/controlif $cnetfile
    	cnetif=`cat $cnetfile`
	for _if in $_iflist; do
	    [ $_if = $cnetif ] && continue
	    echo "`date`: taking $_if down"
	    ifconfig $_if down
	done
    fi

    # Emit this upstart event to allow boot to continue, even
    # if we couldn't get a dhcp lease.
    /sbin/initctl emit -n 'emulab-findcnet-done'
fi >>$LOGDIR/dhclient.log 2>&1

#
# In case ifup/ifdown try to feed us anything
#
while read foo bar; do
    echo "`date`: $iface: findcnet got \"$foo $bar\" from caller"
done >>$LOGDIR/dhclient.log 2>&1

if [ -z "$cnetif" ]; then
    echo "`date`: $iface: findcnet got empty $cnetfile" >>$LOGDIR/dhclient.log
fi

echo "`date`: $iface: cnet is $cnetif" >>$LOGDIR/dhclient.log

if [ "$cnetif" = $iface ]; then
    echo cnet
else
    echo $iface
fi

rm -rf $lockdir
exit 0