Commit caad3a35 authored by Chad Barb's avatar Chad Barb

New version of unified tbswap in/out.
startexp/endexp/swapexp have been changed to use new script.

tbswapin and tbswapout have been replaced with a script which
spits out a warning message, then calls tbswap appropriately.

The README has also been modified.
parent 0c74b706
......@@ -1333,6 +1333,7 @@ outfiles="$outfiles Makeconf GNUmakefile \
tbsetup/ns2ir/parse-ns \
tbsetup/ns2ir/sim.tcl tbsetup/db2ns \
tbsetup/tbprerun tbsetup/tbswapin tbsetup/tbswapout tbsetup/tbend \
tbsetup/tbswap \
tbsetup/tbreport tbsetup/named_setup tbsetup/exports_setup \
tbsetup/checkpass/GNUmakefile tbsetup/assign_wrapper tbsetup/ptopgen \
tbsetup/frisbeelauncher tbsetup/node_update tbsetup/webnodeupdate \
......
......@@ -376,6 +376,7 @@ outfiles="$outfiles Makeconf GNUmakefile \
tbsetup/ns2ir/parse-ns \
tbsetup/ns2ir/sim.tcl tbsetup/db2ns \
tbsetup/tbprerun tbsetup/tbswapin tbsetup/tbswapout tbsetup/tbend \
tbsetup/tbswap \
tbsetup/tbreport tbsetup/named_setup tbsetup/exports_setup \
tbsetup/checkpass/GNUmakefile tbsetup/assign_wrapper tbsetup/ptopgen \
tbsetup/frisbeelauncher tbsetup/node_update tbsetup/webnodeupdate \
......
......@@ -17,7 +17,8 @@ SUBDIRS = checkpass ns2ir
BIN_STUFF = power snmpit tbend tbswapin tbswapout tbprerun tbreport \
tbresize os_load startexp endexp batchexp swapexp \
node_reboot nscheck node_update savelogs node_control \
portstats checkports eventsys_control os_select tbrestart
portstats checkports eventsys_control os_select tbrestart \
tbswap
# Stuff that mere users get on plastic.
USERBINS = os_load node_reboot nscheck node_update savelogs \
......
......@@ -11,13 +11,15 @@ ns-file, and then converts the ns-file into a virtual topology stored
in the database.
----------------------------------------------------------------------
tbswap
tbswapin
'tbswap in'
Syntax:
tbswapin <pid> <eid>
tbswap in <pid> <eid>
tbswapin swaps an experiment in. Specifically it finds and allocates
tbswap, when passed 'in' as its operation,
swaps an experiment in. Specifically, it finds and allocates
a set of resources and configures these resources to emulate the
desired experiment. As a part of this it configures the physical
state in the DB.
......@@ -25,9 +27,9 @@ state in the DB.
Exit Codes:
tbswapin exits with a variety of codes to represent different error
'tbswap in' exits with a variety of codes to represent different error
conditions. Almost all of these codes are actually generated by
assign_wrapper and just passed through by tbswapin.
assign_wrapper and just passed through by 'tbswap in'.
Exit 0 : All good
2: Insufficient resources.
......@@ -50,15 +52,16 @@ I.e.
----------------------------------------------------------------------
tbswapout
'tbswap out'
Syntax:
tbswapout [-force] <pid> <eid>
tbswap out [-force] <pid> <eid>
tbswapout is the inverse of tbswapin. It tears down the physical
tbswap, when passed 'out' as its operation,
is the inverse of 'tbswap in'. It tears down the physical
state on the testbed, freeing the resources for other use. It clears
the physical state from the DB but leaves the virtual state intact. I.e.
it reverse tbswapin but not tbprerun.
the physical state from the DB but leaves the virtual state intact.
I.e., it reverses 'tbswap in' but not tbprerun.
-force - Does not check current experiment state.
......@@ -94,9 +97,9 @@ Basic Operation
The basic operation of the tbsetup tools is:
1. tbprerun
2. tbswapin
2. tbswap in
3. do experiment
4. tbswapout
4. tbswap out
5. Repeat steps 2-4 as necessary.
6. tbend
......@@ -114,39 +117,41 @@ state before running.
prerunning - During tbprerun.
swapped - After tbprerun or tbswapout. tbswapin requires the
swapped - After tbprerun or 'tbswap out'. 'tbswap in' requires the
experiment to be in this state before running. tbend requires this
state unless -force is used.
activating - During tbswapin.
activating - During 'tbswap in'.
active - After tbswapin. tbswapout requires this state unless -force
is used.
active - After 'tbswap in'.
'tbswap out' requires this state unless -force is used.
swapping - During tbswapout.
swapping - During 'tbswap out'.
terminating - During tbend.
ended - After tbend.
tested - After tbswapin is run in testing mode.
tested - After 'tbswap in' is run in testing mode.
----------------------------------------------------------------------
Non-symmetries
In general tbprerun and tbend are inverse operations and tbswapin and
tbswapout are inverse operations. This is not completely true,
however. tbswapout does completely reverse tbswapin, and tbend clears
some state that is set in tbswapin, rather than tbprerun.
In general tbprerun and tbend are inverse operations and
'tbswap in' and 'tbswap out' are inverse operations.
This is not completely true, however.
'tbswap out' does not completely reverse 'tbswap in',
and tbend clears some state that is set in 'tbswap in',
rather than tbprerun.
Node state: For performance reasons tbswapout does not touch node
Node state: For performance reasons 'tbswap out' does not touch node
state. The idea being that node state only matters for active
experiments and these experiments will reconfigure the node state when
they are swapped in.
Portmap: The portmap table in the DB is not cleared by tbswapout.
This is because the portmap table will be used the next time tbswapin
Portmap: The portmap table in the DB is not cleared by 'tbswap out'.
This is because the portmap table will be used the next time 'tbswap in'
is called to try to match the portmapping of the previous swap. The
purpose behind this is to preserve the same port mapping across swaps.
The portmap table is cleared in tbend instead.
......
......@@ -270,9 +270,9 @@ if (! $batch) {
# Sanity check states in case someone changes something.
#
if ($estate eq EXPTSTATE_ACTIVE) {
print STDOUT "Running tbswapout with arguments: $pid $eid\n";
if (system("$tbdir/tbswapout $pid $eid") != 0) {
fatal("tbswapout failed!\n");
print STDOUT "Running 'tbswap out' with arguments: $pid $eid\n";
if (system("$tbdir/tbswap out $pid $eid") != 0) {
fatal("tbswap out failed!\n");
}
$estate = ExpState($pid,$eid);
......
......@@ -236,11 +236,11 @@ if (system("$tbdir/tbprerun $pid $eid $nsfile") != 0) {
$estate = EXPTSTATE_PRERUN;
if (! $frontend) {
if (system("$tbdir/tbswapin $pid $eid") != 0) {
if (system("$tbdir/tbswap in $pid $eid") != 0) {
$errorstat = $? >> 8;
fatal("tbswapin failed!\n");
fatal("tbswap in failed!\n");
}
# So fatal errors run tbswapout,
# So fatal errors run tbswap out,
$estate = EXPTSTATE_ACTIVE;
#
......@@ -431,9 +431,9 @@ sub fatal()
sub tbendit()
{
if ($estate eq EXPTSTATE_ACTIVE) {
print "Running tbswapout with arguments: $pid $eid\n";
if (system("$tbdir/tbswapout $pid $eid") != 0) {
print "tbswapout failed!\n";
print "Running 'tbswap out' with arguments: $pid $eid\n";
if (system("$tbdir/tbswap out $pid $eid") != 0) {
print "tbswap out failed!\n";
}
}
print "Running tbend with arguments: -force $pid $eid\n";
......
......@@ -272,9 +272,9 @@ if ($inout ne "restart" && -e $repfile) {
# Sanity check states in case someone changes something.
#
if ($inout eq "out") {
print STDOUT "Running tbswapout with arguments: $pid $eid\n";
if (system("$tbdir/tbswapout $pid $eid") != 0) {
fatal("tbswapout failed!\n");
print STDOUT "Running 'tbswap out' with arguments: $pid $eid\n";
if (system("$tbdir/tbswap out $pid $eid") != 0) {
fatal("tbswap out failed!\n");
}
$estate = ExpState($pid,$eid);
......@@ -283,9 +283,9 @@ if ($inout eq "out") {
}
}
elsif ($inout eq "in") {
print STDOUT "Running tbswapin with arguments: $pid $eid\n";
if (system("$tbdir/tbswapin $pid $eid") != 0) {
fatal("tbswapin failed!\n");
print STDOUT "Running 'tbswap in' with arguments: $pid $eid\n";
if (system("$tbdir/tbswap in $pid $eid") != 0) {
fatal("tbswap in failed!\n");
}
$estate = ExpState($pid,$eid);
......
#!/usr/bin/perl -w
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2003 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
# tbswapin
# This is the second program in the
# tbprerun/tbswapin/tbswapout/.../tbend sequences. It's purpose is
# to setup the testbed for experimental use. The first part centers
# around assign and converting the virtual topology to a physical
# actuality and setting up the vlans and delays table. The second
# part calls a number of scripts to set up switch, node, and
# nameserver state.
#
# Configure variables
#
my $TBROOT = "@prefix@";
my $TESTMODE = @TESTMODE@;
my $DISABLE_EVENTS = "@DISABLE_EVENT_SCHED@";
# Untaint the path
$ENV{'PATH'} = "/usr/bin:$TBROOT/libexec:$TBROOT/libexec/ns2ir" .
":$TBROOT/sbin:$TBROOT/bin";
#
# Testbed Support libraries
#
use lib "@prefix@/lib";
use libdb;
use libtestbed;
require exitonwarn; # exitonwarn isn't really a module, so just require it
#
# Turn off line buffering on output
#
$| = 1;
if ($#ARGV != 1) {
print STDERR "Syntax: $0 pid eid\n";
exit(1);
}
my ($pid,$eid) = @ARGV;
my $cleanvlans = 0;
my $state;
#
# Cleanup if something goes wrong.
#
sub cleanup {
print STDERR "Cleaning up after errors.\n";
if ($os_setup_pid) {
print "Waiting for os_setup to finish\n";
waitpid($os_setup_pid,0);
}
if (!$DISABLE_EVENTS) {
print "Stopping event system\n";
if (system("eventsys_control stop $pid $eid")) {
print STDERR "*** Failed to stop the event system.\n";
}
}
if ($cleanvlans) {
print STDERR "Removing VLANs.\n";
if (system("snmpit -r $pid $eid")) {
print STDERR "*** Failed to clean up VLANs\n";
}
}
#
# This is a hack. We need a more general os_teardown, but for now
# we just kill off the vnode stuff.
#
TBDebugTimeStamp("vnode_setup -k started");
if (system("vnode_setup -d -k $pid $eid")) {
print STDERR "*** Failed tear down vnodes.\n";
}
print STDERR "Freeing up nodes.\n";
if (system("nfree $pid $eid")) {
print STDERR "*** Could not free nodes.\n";
}
print STDERR "Resetting DB.\n";
DBQueryWarn("DELETE from delays where pid='$pid' and eid='$eid'");
DBQueryWarn("DELETE from vlans where pid='$pid' and eid='$eid'");
DBQueryWarn("DELETE from tunnels where pid='$pid' and eid='$eid'");
DBQueryWarn("DELETE from v2pmap where pid='$pid' and eid='$eid'");
DBQueryWarn("DELETE from ipport_ranges where pid='$pid' and eid='$eid'");
DBQueryWarn("DELETE from linkdelays where pid='$pid' and eid='$eid'");
SetExpState($pid, $eid, EXPTSTATE_SWAPPED);
}
print "Beginning swapin in for $pid/$eid. " . TBTimeStamp() . "\n";
TBDebugTimeStamp("tbswapin started");
if (! ($state = ExpState($pid, $eid))) {
print STDERR "*** No such experiment $pid/$eid\n";
exit(1);
}
if ($state eq EXPTSTATE_ACTIVE) {
print STDERR "*** Experiment is already running. Must be swapped out.\n";
exit(1);
}
elsif ($state ne EXPTSTATE_SWAPPED) {
print STDERR "*** Experiment is in the wrong state: $state.\n";
exit(1);
}
if (! SetExpState($pid, $eid, EXPTSTATE_ACTIVATING)) {
print STDERR "*** Failed to set intermediate experiment state.\n";
exit(1);
}
# This does all the virtual to physical mapping and updating the DB state.
print "Mapping to physical reality ...\n";
TBDebugTimeStamp("assign_wrapper started");
my $exitcode;
if ($exitcode = system("assign_wrapper $pid $eid")) {
print STDERR "*** Failed to map to reality.\n";
cleanup();
# Pass exit code through
exit($exitcode >> 8);
}
TBDebugTimeStamp("assign_wrapper finished");
print "Mapped to physical reality!\n";
# Exit here if we are testing.
if ($TESTMODE) {
print "Testing run - Stopping here.\n";
if (! SetExpState($pid, $eid, EXPTSTATE_TESTING)) {
print STDERR "*** Failed to set experiment state.\n";
cleanup();
exit(1);
}
exit(0);
}
# Everything from now on sets up switch and node state.
#
# These things need to get started before the nodes come up, so we'll
# do them before the os_setup. Everything else can done in parallel with
# os_setup. (Actually, these probably can too, since they should finish
# long before the nodes reboot, but better safe than sorry)
#
print "Setting up mountpoints.\n";
TBDebugTimeStamp("mountpoints started");
if (system("exports_setup")) {
print STDERR "*** Failed to setup mountpoints.\n";
cleanup();
exit(1);
}
TBDebugTimeStamp("mountpoints finished");
TBDebugTimeStamp("named started");
print "Setting up named maps.\n";
if (system("named_setup")) {
print STDERR "*** WARNING: Failed to add node names to named map.\n";
#
# This is a non-fatal error.
#
}
TBDebugTimeStamp("named finished");
#
# Since it'll take a while for the nodes to reboot, we'll start now, and
# wait for the os_setup to finish, down below
#
print "Resetting OS and rebooting.\n";
TBDebugTimeStamp("os_setup started");
if (!($os_setup_pid = fork())) {
exec("os_setup $pid $eid") or exit(1);
} elsif ($os_setup_pid == -1) {
print STDERR "*** Fork failed.\n";
cleanup();
exit(1);
}
#
# XXX: Don't add any steps between here and the waitpid() call below without
# verifying that 1) It's OK for nodes to come up before the step has
# completed and 2) It's OK for the command to run in parallel with os_setup
# (no DB dependencies, etc.)
#
print "Setting up VLANs.\n";
TBDebugTimeStamp("snmpit started");
if (system("snmpit -t $pid $eid")) {
print STDERR "*** Failed to set up VLANs.\n";
cleanup();
exit(1);
}
TBDebugTimeStamp("snmpit finished");
#
# An error now means that the VLANS need to be cleaned up.
#
$cleanvlans = 1;
print "Setting up email lists.\n";
TBDebugTimeStamp("genelists started");
if (system("genelists")) {
print STDERR "*** WARNING: Failed to update email lists.\n";
#
# This is a non-fatal error.
#
}
TBDebugTimeStamp("genelists finished");
print "Clearing port counters.\n";
TBDebugTimeStamp("portstats started");
if (system("portstats -z -a -q $pid $eid")) {
print STDERR "*** WARNING: Failed to clear port counters.\n";
#
# This is a non-fatal error.
#
}
TBDebugTimeStamp("porstats finished");
#
# OK, let's see how that os_setup did
#
$kid = waitpid($os_setup_pid,0);
if ($kid == $os_setup_pid) {
undef $os_setup_pid; # Make sure cleanup() doesn't wait for it
if ($CHILD_ERROR) {
print STDERR "*** Failed to reset OS and reboot nodes.\n";
cleanup;
exit(1);
}
} else {
undef $os_setup_pid;
print STDERR "*** Error waiting for os_setup to finish.\n";
cleanup;
exit(1);
}
TBDebugTimeStamp("os_setup finished");
#
# Okay, start the event system now that we know all the nodes have
# rebooted (os_setup is done). This only takes a moment (puts itself
# in the background), so its not enough of a delay to worry about.
#
if (!$DISABLE_EVENTS) {
print "Starting the event system.\n";
TBDebugTimeStamp("eventsys_control started");
if (system("eventsys_control start $pid $eid")) {
print STDERR "*** Failed to start the event system.\n";
cleanup;
exit(1);
}
TBDebugTimeStamp("eventsys_control finished");
}
# Accounting info.
TBSetExpSwapTime($pid, $eid);
unshift(@ARGV,"in");
if (!SetExpState($pid, $eid, EXPTSTATE_ACTIVE)) {
print STDERR "*** Failed to set experiment state!\n";
cleanup();
exit(1);
}
print STDERR "Use of tbswapin is deprecated!\n";
print STDERR "Use 'tbswap' instead.\n";
print "Swapin finished. " . TBTimeStamp() . "\n";
TBDebugTimeStamp("tbswapin finished");
exit(0);
exec "@prefix@/bin/tbswap", @ARGV;
die("tbswapin: Could not exec tbswap: $!");
#!/usr/bin/perl -w
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2003 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
# tbswapout
# This is the third program in the
# tbprerun/tbswapin/tbswapout/.../tbend sequences. It's purpose is
# to reverse what tbswapin did. I.e. tear down all switch and node
# state and remove the entries from the delays and vlans table.
# When this script succesfully completes the testbed will be in
# a state for tbswapin or tbend to be run.
sub usage()
{
print STDERR "Usage: $0 [-force] pid eid\n";
exit(-1);
}
#
# Configure variables
#
my $TBROOT = "@prefix@";
my $TESTMODE = @TESTMODE@;
my $DISABLE_EVENTS = "@DISABLE_EVENT_SCHED@";
# Untaint the path
$ENV{'PATH'} = "/usr/bin:$TBROOT/libexec:$TBROOT/libexec/ns2ir" .
":$TBROOT/sbin:$TBROOT/bin";
#
# Testbed Support libraries
#
use lib "@prefix@/lib";
use libdb;
use libtestbed;
require exitonwarn; # exitonwarn isn't really a module, so just require it
#
# Turn off line buffering on output
#
$| = 1;
my $force = 0;
my $errors = 0;
my $state;
while ($#ARGV > 1) {
$arg = shift;
if ($arg eq "-force") {
$force = 1;
} else {
usage();
}
}
if ($#ARGV < 1) {
usage();
}
my ($pid,$eid) = @ARGV;
TBDebugTimeStampsOn();
print "Beginning swapout for $pid/$eid. " . TBTimeStamp() . "\n";
TBDebugTimeStamp("tbswapout started");
if (! ($state = ExpState($pid, $eid))) {
print STDERR "*** No such experiment $pid/$eid\n";
exit(1);
}
if (! $force) {
if ($TESTMODE) {
if ($state ne EXPTSTATE_TESTING) {
print STDERR "*** Experiment should be in testing state.\n";
exit(1);
}
}
elsif ($state eq EXPTSTATE_SWAPPED) {
print STDERR "*** Experiment is already swapped out.\n" .
" Try swapping in first or use -force.\n";
exit(1);
}
elsif ($state ne EXPTSTATE_ACTIVE) {
print STDERR "*** Experiment is not running\n".
" Try swapping in first or use -force.\n";
exit(1);
}
}
elsif ($state ne EXPTSTATE_ACTIVE) {
print STDERR "*** WARNING: Ignoring improper state: $state.\n";
}
if (! SetExpState($pid, $eid, EXPTSTATE_SWAPPING)) {
print STDERR "*** Failed to set intermediate experiment state.\n";
exit(1);
}
if (! $TESTMODE) {
if (! $DISABLE_EVENTS) {
print "Stopping the event system.\n";
if (system("eventsys_control stop $pid $eid")) {
print STDERR "*** Failed to stop the event system.\n";
$errors = 1;
}
}
TBDebugTimeStamp("snmpit started");
print "Clearing VLANs.\n";
if (system("snmpit -r $pid $eid")) {
print STDERR "*** Failed to reset VLANs.\n";
$errors = 1;
}
TBDebugTimeStamp("snmpit finished");
#
# This is a hack. We need a more general os_teardown, but for now
# we just kill off the vnode stuff.
#
print "Tearing down virtual nodes.\n";
TBDebugTimeStamp("vnode_setup started");
if (system("vnode_setup -d -k $pid $eid")) {
print STDERR "*** Failed tear down vnodes.\n";
$errors = 1;
}
TBDebugTimeStamp("vnode_setup finished");
}
print "Freeing resources.\n";
TBDebugTimeStamp("nfree started");
if (system("nfree $pid $eid")) {
print STDERR "*** Failed to free resources.\n";
$errors=1;
}
TBDebugTimeStamp("nfree finished");
if (! $TESTMODE) {
#
# All of these errors are non-fatal on swapout. We find out about them
# via email sent from the individual scripts.
#
print "Resetting mountpoints.\n";
TBDebugTimeStamp("exports started");
if (system("exports_setup")) {
print STDERR "*** Failed to reset mountpoints.\n";
}
TBDebugTimeStamp("exports finished");
print "Resetting named maps.\n";
TBDebugTimeStamp("named started");
if (system("named_setup")) {
print "*** WARNING: Failed to reset named map.\n";
}
TBDebugTimeStamp("named finished");
print "Resetting email lists.\n";
TBDebugTimeStamp("genelists started");
if (system("genelists")) {
print "*** WARNING: Failed to reset email lists.\n";
}
TBDebugTimeStamp("genelists finished");
}
print "Resetting DB.\n";
DBQueryWarn("DELETE from delays where pid='$pid' and eid='$eid'")
or $errors++;
DBQueryWarn("DELETE from vlans where pid='$pid' and eid='$eid'")
or $errors++;
DBQueryWarn("DELETE from tunnels where pid='$pid' and eid='$eid'")
or $errors++;
DBQueryWarn("DELETE from v2pmap where pid='$pid' and eid='$eid'")
or $errors++;
DBQueryWarn("DELETE from ipport_ranges where pid='$pid' and eid='$eid'")
or $errors++;
DBQueryWarn("DELETE from linkdelays where pid='$pid' and eid='$eid'")
or $errors++;
# Accounting info.
TBSetExpSwapTime($pid, $eid);
unshift (@ARGV,"out");
if ($errors == 0) {
SetExpState($pid, $eid, EXPTSTATE_SWAPPED)
or $errors++;
}
print STDERR "Use of tbswapout is deprecated!\n";
print STDERR "Use 'tbswap' instead.\n";
TBDebugTimeStamp("tbswapout finished");
print "Swapout finished. " . TBTimeStamp() . "\n";
exit $errors;
exec "@prefix@/bin/tbswap", @ARGV;
die("tbswapout: Could not exec tbswap: $!");
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment