common-env.sh 7.59 KB
Newer Older
1
#!/bin/sh
Mike Hibler's avatar
Mike Hibler committed
2 3
#
# Copyright (c) 2006 University of Utah and the Flux Group.
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
# 
# {{{EMULAB-LICENSE
# 
# This file is part of the Emulab network testbed software.
# 
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
# 
# This file is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
# License for more details.
# 
# You should have received a copy of the GNU Affero General Public License
# along with this file.  If not, see <http://www.gnu.org/licenses/>.
# 
# }}}
Mike Hibler's avatar
Mike Hibler committed
23 24
#

25 26 27 28 29
#
# Simple shell script to get some environment variables useful for pelab
# shell scripts
#

30 31 32 33 34 35
#
# 'Header guard'
#
if [ "$COMMON_ENV_LOADED" != "yes" ]; then
COMMON_ENV_LOADED="yes"

36 37 38 39 40
#
# Find out the OS we're running on
#
UNAME=`uname -s`

41 42 43 44 45 46 47 48 49 50 51
#
# Yow.  The BSD shell requires setting trapsasync (-T) to allow us to
# receive signals when in a wait.
#
if [ "$UNAME" = "FreeBSD" ]; then
    set -o trapsasync
    SH="/bin/sh -T"
else
    SH=/bin/sh
fi

52 53 54
#
# Different binary directories for FreeBSD/Linux
#
55
if [ "$UNAME" = "Linux" ]; then
56
    BIN_PATH="/usr/bin"
57
elif [ "$UNAME" = "FreeBSD" ]; then
58 59 60 61 62 63
    BIN_PATH="/usr/local/bin"
else
    echo "Unable to determine operating system"
    exit -1
fi

64 65 66 67 68 69 70 71 72
#
# Locations of some Emulab-specific files
#
EMUVAR="/var/emulab"
EMUBOOT="$EMUVAR/boot"
NICKFILE="$EMUBOOT/nickname"
RCPLAB="$EMUBOOT/rc.plab"
HOSTSFILE="/etc/hosts"
IFCONFIG="/sbin/ifconfig"
73
PERL="/usr/bin/perl"
74 75
PYTHON="${BIN_PATH}/python"
SUDO="${BIN_PATH}/sudo"
76 77
MKDIR="/bin/mkdir"
CHMOD="/bin/chmod"
78
SU="/bin/su"
79

80
SYNC="/usr/local/etc/emulab/emulab-sync"
81 82
SYNCTIMO=120

83
if [ "$UNAME" = "Linux" ]; then
84
    GREP="/bin/grep"
85 86
elif [ "$UNAME" = "FreeBSD" ]; then
    GREP="/usr/bin/grep"
87 88 89 90
else
    echo "Unable to determine operating system"
    exit -1
fi
91 92 93 94 95

#
# Some 'constants' by convention. 
#
export PELAB_LAN=elabc
96
export EPLAB_LAN=plabc
97

98 99 100 101 102
#
# Name of the barrier for indicating all stubs are ready
#
export STUB_BARRIER=stubsready

103 104 105
#
# Node/experiment info
#
106
export NICKNAME=`cat $NICKFILE`
107
export HOSTNAME=`echo $NICKNAME | cut -d. -f1`;
108 109 110
export EXPERIMENT=`echo $NICKNAME | cut -d. -f2`;
export PROJECT=`echo $NICKNAME | cut -d. -f3`;

111 112 113 114 115 116 117

#
# Important directories
#
SCRIPT_LOCATION=`dirname $0`
export BASE="${SCRIPT_LOCATION}/../";
export STUB_DIR="${BASE}/stub/";
118
export MAGENT_DIR="${BASE}/magent/";
119 120
export NETMON_DIR="${BASE}/libnetmon/";
export MONITOR_DIR="${BASE}/monitor/";
121
export DBMONITOR_DIR="${BASE}/dbmonitor/";
122
export IPERFD_DIR="${BASE}/iperfd/";
123
export TMPDIR="/var/tmp/";
124 125 126
export LOGDIR="/local/logs/"

#
Mike Hibler's avatar
Mike Hibler committed
127 128
# Temproary files we use.
# We put them in /local/logs so they become part of the fossil record.
129
#
Mike Hibler's avatar
Mike Hibler committed
130 131
export IPMAP="/local/logs/ip-mapping.txt"
export INITCOND="/local/logs/initial-conditions.txt"
132 133

#
Mike Hibler's avatar
Mike Hibler committed
134
# Important scripts/libraries
135 136 137
#
export NETMOND="netmond"
export STUBD="stubd"
138
export MAGENT="magent"
139
export MONITOR="monitor.py"
140
export DBMONITOR="dbmonitor.pl"
141
export IPERFD="iperfd"
142
export GENIPMAP="gen-ip-mapping.pl"
Mike Hibler's avatar
Mike Hibler committed
143
export GENINITCOND="init-elabnodes.pl"
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
export NETMON_LIB="libnetmon.so"

#
# Where are we running?
#
if [ -e "$RCPLAB" ]; then
    export RUNNING_ON="plab"
    export ON_PLAB="yes"
    export ON_ELAB=""
else
    export RUNNING_ON="elab"
    export ON_PLAB=""
    export ON_ELAB="yes"
fi

159 160 161 162 163 164 165 166 167 168
#
# Find out if we're in a vserver - can we see the init process?
#
ps --pid 1 > /dev/null
if [ $? == 1 ]; then
    export IN_VSERVER="yes"
else
    export IN_VSERVER=""
fi

Mike Hibler's avatar
Mike Hibler committed
169 170 171 172 173 174 175 176 177 178
#
# Are we the "master" (sync server) node?
#

if `$SYNC -m`; then
    export ON_MASTER="yes"
else
    export ON_MASTER=""
fi

179 180 181 182 183 184 185 186 187 188
#
# Make a handy variable for running as root (ie. invoke sudo if necessary)
#
if [ "$EUID" != "0" ]; then
    export AS_ROOT="$SUDO"
else
    export AS_ROOT=""
fi

#
189 190 191 192
# How big is this experiment? Counts the number of planetlab nodes. IF there
# are real planetlab nodes in this experiment, count them instead of the number
# of fake planetlab nodes - this allows us to remove planetlab nodes that fail
# from the experiment, and *maybe* everything else will just work.
193
#
194
export PEER_PAIRS=`$GREP -q planet /etc/hosts && $GREP -E -c 'planet-.*-realinternet ' /etc/hosts || $GREP -E -c 'plab-.*-plabc ' /etc/hosts`
195 196 197 198 199 200 201 202 203 204
export PEERS=`expr $PEER_PAIRS \* 2`

#
# Make the logdir if it doesn't exist
#
if [ ! -d $LOGDIR ]; then
    $AS_ROOT $MKDIR -p $LOGDIR
    $AS_ROOT $CHMOD 777 $LOGDIR
fi

205 206 207 208
#
# IP addresses and interface names
#
ifacename() {
209
    LINKIP=$1
210 211 212 213 214 215 216 217 218
    IFACENAME=`$IFCONFIG -a | $PERL -e "while(<>) { if (/^(eth\d+)/) { \\\$if = \\\$1; } if (/$LINKIP/) { print \"\\\$if\n\"; exit 0; }} exit 1;"`

    echo $IFACENAME
}

lookup_ip_host()
{
    HOST=$1
    LINK=$2
219
    IPADDR=`grep "${HOST}-${LINK}[ ]" $HOSTSFILE | cut -f1`
220 221 222 223 224 225 226 227 228 229 230 231
    echo $IPADDR
}

get_iface_addr() {
    IFACE=$1
    IFACEADDR=`$IFCONFIG -a | $PERL -e "while(<>) { if (/^$IFACE/) { \\\$found = 1; } if (\\\$found && /addr:(\d+\.\d+\.\d+\.\d+)/) { print \"\\\$1\n\"; exit 0; }} exit 1;"`
    echo $IFACEADDR
}

#
# $HOST_ROLE should be set by the calling script
#
232
if [ "$HOST_ROLE" = "monitor" ]; then
233 234
    export PELAB_IP=`lookup_ip_host $HOSTNAME $PELAB_LAN`
    export PELAB_IFACE=`ifacename $PELAB_IP`
235 236
elif [ "$HOST_ROLE" = "stub" ]; then
    if [ "$ON_ELAB" = "yes" ]; then
237
        export PLAB_IP=`lookup_ip_host $HOSTNAME $EPLAB_LAN`
238 239 240 241 242 243 244 245
        #
        # We could still be in a vserver
        #
        if [ "$IN_VSERVER" = "yes" ]; then
            export PLAB_IFACE="vnet"
        else
            export PLAB_IFACE=`ifacename $PLAB_IP`
        fi
246 247 248 249 250 251 252
    else
        # On real planetlab
        export PLAB_IFACE="vnet"
        export PLAB_IP=`get_iface_addr $PLAB_IFACE`
    fi
fi

253 254 255 256 257 258 259 260
#
# Function for waiting on a barrier sync
# I'd rather automatically determine the number of peer pairs, but that
# looks too hard for now.
#
barrier_wait()
{
    BARRIER=$1
Mike Hibler's avatar
Mike Hibler committed
261 262

    if [ $ON_MASTER ]; then
263
        WAITERS=`expr $PEERS - 1`
264 265 266
        echo "Waiting up to $SYNCTIMO seconds for $WAITERS clients"
        sync_timeout $SYNCTIMO $SYNC -n $BARRIER -i $WAITERS
	_rval=$?
Mike Hibler's avatar
Mike Hibler committed
267
    else
268 269 270 271 272 273 274 275 276 277 278 279 280
	#
	# XXX on planetlab, lookup of the syncserver name can
	# fail transiently.  Try a couple more times, waiting in between.
	#
	for i in 1 2 3; do
	    $SYNC -n $BARRIER 
	    _rval=$?
	    if [ $_rval -ne 68 ]; then
	        break
	    fi
	    echo "sync on $BARRIER failed, trying again..."
	    sleep 10
	done
281
    fi
282 283

    return $_rval
284 285
}

286 287 288 289 290 291 292 293 294 295 296 297
#
# Log the stdout and stderr of the given process to the logdir
# Runs the program in the background and returns its pid
#
log_output_background()
{
    PROGNAME=$1
    CMD=$2
    $CMD 1> ${LOGDIR}/${PROGNAME}.stdout 2> ${LOGDIR}/${PROGNAME}.stderr &
    echo $!
}

298 299 300 301 302 303 304 305 306 307
sync_watchdog()
{
    TIMO=$1
    SYNCDPID=$2

    sleep $TIMO
    echo '*** HUPing syncd'
    $AS_ROOT kill -HUP $SYNCDPID
}

308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328
#
# If $SYNC command doesn't return within the indicated timeout period,
# HUP the syncserver to force everyone out of a barrier.
#
sync_timeout()
{
    TIMO=$1
    shift
    CMDSTR=$*

    if [ -r /var/run/syncd.pid ]; then
        SYNCDPID=`cat /var/run/syncd.pid`
    else
        SYNCDPID=""
    fi

    # fire off the command
    $CMDSTR & CMDPID=$!

    # and a watchdog
    if [ -n "$SYNCDPID" ]; then
329
        sync_watchdog $TIMO $SYNCDPID & DOGPID=$!
330 331 332 333 334 335 336 337
    fi

    # wait for the command to finish or be terminated
    wait $CMDPID
    RVAL=$?

    # nuke the watchdog
    if [ -n "$SYNCDPID" ]; then
338
        kill -9 $DOGPID >/dev/null 2>&1
339 340 341 342 343 344
    fi

    # and return the result
    return $RVAL
}

345 346 347 348
#
# Become the 'vuser'
#

349
fi # End of header guard