Commit c44c47c9 authored by David Johnson's avatar David Johnson

Add support for including nodes from multiple PLCs in experiments. Right

now, this is keyed off nodetype.  Lots of hardcoded constants and config
stuff moved to attributes in the db.  You can now set per-PLC and
per-slice attributes, so you can (for instance) use different auth info
whenever you want.  Experiments can use preexisting slices if somebody
sets up the db before swapin.  Also, we no longer have to rely on
slices.xml to sync up nodes/sites with PLC... can use xmlrpc instead.

Lots of code cleanup, improved some abstractions, etc.
parent a25fc201
......@@ -1502,8 +1502,6 @@ OUTERBOSS_NODENAME=""
OUTERBOSS_XMLRPCPORT=3069
OUTERBOSS_SSLCERTNAME="/etc/outer_emulab.pem"
PLABSUPPORT=0
PLAB_ROOTBALL="change.me"
PLAB_SLICEPREFIX="utah_elab"
WIKISUPPORT=0
TRACSUPPORT=0
BUGDBSUPPORT=0
......@@ -1727,12 +1725,6 @@ EOF
fi
if test $PLABSUPPORT -eq 1; then
if test "$PLAB_ROOTBALL" = "change.me"; then
{ echo "configure: error: plab support included but PLAB_ROOTBALL not defined." 1>&2; exit 1; }
fi
fi
if test $ELABINELAB -eq 1; then
cat >> confdefs.h <<EOF
#define ELABINELAB 1
......@@ -2810,8 +2802,6 @@ s%@BUGDBSUPPORT@%$BUGDBSUPPORT%g
s%@OPSDBSUPPORT@%$OPSDBSUPPORT%g
s%@NFSTRACESUPPORT@%$NFSTRACESUPPORT%g
s%@TBLOGFACIL@%$TBLOGFACIL%g
s%@PLAB_ROOTBALL@%$PLAB_ROOTBALL%g
s%@PLAB_SLICEPREFIX@%$PLAB_SLICEPREFIX%g
s%@TESTBED_NETWORK@%$TESTBED_NETWORK%g
s%@EXTERNAL_TESTBED_NETWORK@%$EXTERNAL_TESTBED_NETWORK%g
s%@TESTBED_NETMASK@%$TESTBED_NETMASK%g
......
......@@ -161,8 +161,6 @@ AC_SUBST(BUGDBSUPPORT)
AC_SUBST(OPSDBSUPPORT)
AC_SUBST(NFSTRACESUPPORT)
AC_SUBST(TBLOGFACIL)
AC_SUBST(PLAB_ROOTBALL)
AC_SUBST(PLAB_SLICEPREFIX)
AC_SUBST(TESTBED_NETWORK)
AC_SUBST(EXTERNAL_TESTBED_NETWORK)
AC_SUBST(TESTBED_NETMASK)
......@@ -256,8 +254,6 @@ OUTERBOSS_NODENAME=""
OUTERBOSS_XMLRPCPORT=3069
OUTERBOSS_SSLCERTNAME="/etc/outer_emulab.pem"
PLABSUPPORT=0
PLAB_ROOTBALL="change.me"
PLAB_SLICEPREFIX="utah_elab"
WIKISUPPORT=0
BUGDBSUPPORT=0
OPSDBSUPPORT=0
......@@ -381,12 +377,6 @@ if test $ELVIN_COMPAT -eq 1; then
AC_DEFINE_UNQUOTED(ELVIN_COMPAT, 1)
fi
if test $PLABSUPPORT -eq 1; then
if test "$PLAB_ROOTBALL" = "change.me"; then
AC_MSG_ERROR([plab support included but PLAB_ROOTBALL not defined.])
fi
fi
if test $ELABINELAB -eq 1; then
AC_DEFINE_UNQUOTED(ELABINELAB, 1)
fi
......
......@@ -8,7 +8,6 @@ SRCDIR = @srcdir@
TESTBED_SRCDIR = @top_srcdir@
OBJDIR = ../../../..
SUBDIR = tbsetup/plab/etc/netbed_files
ROOTBALL = @PLAB_ROOTBALL@
include $(OBJDIR)/Makeconf
......@@ -22,10 +21,7 @@ include $(TESTBED_SRCDIR)/GNUmakerules
mkdirs: $(LOG_DIR) $(WWW_DIR)
rootball-link:
-ln -fs $(INSTALL_ETCDIR)/plab/$(ROOTBALL) $(WWW_DIR)/$(ROOTBALL)
install: sbin-install mkdirs rootball-link
install: sbin-install mkdirs
sbin-install: $(addprefix $(SBIN_DIR)/, $(SBIN_STUFF))
......
#!/bin/sh
CRONTAB=/usr/bin/crontab
CRONLINE="@reboot cd /home/utah_elab_svc; ./netbed_files/sbin/thttpd.restart"
CRONLINE="@reboot cd $HOME; ./netbed_files/sbin/thttpd.restart"
#
# For now, just install the new crontab - we don't really have a reason to
......
#!/bin/sh
MAIL_WARNINGS_TO=testbed-ops@emulab.net
BASE=/home/utah_svc_slice/netbed_files
SLICE=`basename $HOME`
BASE=$HOME/netbed_files
LOGDIR=$BASE/log
LOGFILE=$LOGDIR/thttpd.log
PIDFILE=$LOGDIR/thttpd.pid
......@@ -32,8 +32,9 @@ $HTTPD_COMMAND
#
# Make sure it started
#
if $WGET_COMMAND; then
$WGET_COMMAND
if [ "$?" != "0"; then
ERRSTR="thttpd on `hostname` failed to start"
echo $ERRSTR
echo "$ERRSTR" | mail -s "$ERRSTR" $MAIL_WARNINGS_TO
# echo "$ERRSTR" | mail -s "$ERRSTR" $MAIL_WARNINGS_TO
fi;
This diff is collapsed.
......@@ -11,7 +11,8 @@ use Exporter;
use vars qw(@ISA @EXPORT);
@ISA = "Exporter";
@EXPORT = qw (MIN TimeStamp getLA OpenLog Log STATUSLOG STATUSLOGPATH);
@EXPORT = qw (MIN TimeStamp getLA OpenLog Log STATUSLOG STATUSLOGPATH
getPLCName setPLCName);
# Must come after package declaration!
use lib '@prefix@/lib';
......@@ -29,9 +30,27 @@ my $UPTIME = "/usr/bin/uptime";
# package vars
my %logs = ();
my $plcname;
sub STATUSLOG { "StatusLog"; }
sub STATUSLOGPATH { "$TB/log/plabnodestatus.log"; }
sub setPLCName {
my $tplcname = shift;
if (defined($tplcname)) {
$plcname = $tplcname;
}
}
sub getPLCName {
return $plcname;
}
sub STATUSLOG {
my $log = shift || '';
return "StatusLog-$log";
}
sub STATUSLOGPATH {
my $log = shift || '';
return "$TB/log/plabnodestatus-$log.log";
}
sub MIN($$) {
my ($a, $b) = @_;
......
This diff is collapsed.
......@@ -126,6 +126,22 @@ class NMagent:
pass
return self.__vers
def ping(self):
try:
res = self.__server.version()
if type(res) == list and len(res) == 2 and res[0] == 0:
return True
pass
except:
if debug:
traceback.print_exc()
pass
pass
return False
def getAgentClass(self):
return self.__class__
pass
#wrap_around(NMagent.create_sliver, timeAdvice)
#wrap_around(NMagent.delete_sliver, timeAdvice)
......
......@@ -2,7 +2,7 @@
# -*- python -*-
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2003 University of Utah and the Flux Group.
# Copyright (c) 2000-2003, 2008 University of Utah and the Flux Group.
# All rights reserved.
#
......@@ -12,21 +12,28 @@ import libplab
from libtestbed import *
def usage(me):
print "Usage: %s [ -vd ]" % me
print " Passing -o to getfree will cause it to only run once."
print " Passing -i to getfree will cause if to only update using"
print " existing node info (no new nodes will be added)."
print "Usage: %s [ -vd ] [<plc>]" % me
print " (where <plc> is the name or id of a plc in the db)"
sys.exit(1)
def main(args):
me = args[0]
parser = TBParser()
parser.parse_args()
(options,cargs) = parser.parse_args()
plab = libplab.Plab()
plab.updateNodeEntries()
if len(cargs) > 0:
print "Updating node entries at %s." % cargs[0]
plab.updateNodeEntries(cargs[0])
else:
# Grab all the PLCs we know about and do for all...
plcs = plab.getPLCs()
for (name,idx) in plcs:
print "Updating node entries at %s." % name
plab.updateNodeEntries(name)
pass
pass
return
if __name__ == "__main__":
......
......@@ -136,6 +136,7 @@ sub checknextnode($) {
# However, wastes resources on boss by not exec'ing this; we have a
# whole extra process hanging around just so we can do the rootball
# and httpd stuff after. XXX!
my $vres = TBForkCmd("$SSH -host $vnode $CLIENT_BIN/vnodesetup" .
" -p $vnode");
if ($vres) {
......@@ -143,18 +144,6 @@ sub checknextnode($) {
exit($vres);
}
# Try to dist out the rootball and other files, but don't make
# setup conditional on success/failure.
if (TBForkCmd("$PLABDIST $vnode")) {
print "*** Could not dist out rootball on $vnode, ignoring.\n";
}
# Try to start the thttpd server in the service sliver, but don't make
# setup conditional on success/failure
if (TBForkCmd("$PLABHTTPD $vnode")) {
print "*** Could not start thttpd on $vnode, ignoring.\n";
}
exit($vres);
#exec "$SSH -host $vnode $CLIENT_BIN/vnodesetup -p $vnode" or
......@@ -260,10 +249,10 @@ sub processchild($$$) {
delete $self->{'PENDING'}->{$pnode->{'name'}};
if (!$exstat) {
print "Teardown of $pnode->{'vnode'} complete\n";
Log(STATUSLOG, $logmsg . "teardown, success, teardown succeeded.");
Log(STATUSLOG(getPLCName()), $logmsg . "teardown, success, teardown succeeded.");
} else {
print "Teardown of $pnode->{'vnode'} failed: $exstat\n";
Log(STATUSLOG, $logmsg . "teardown, fail, teardown failed.");
Log(STATUSLOG(getPLCName()), $logmsg . "teardown, fail, teardown failed.");
}
return 1;
......@@ -311,7 +300,7 @@ sub processchild($$$) {
$self->teardownnode($pnode);
$self->calcnextcheck($pnode);
$pnode->{'consecfails'}++;
Log(STATUSLOG, $logmsg);
Log(STATUSLOG(getPLCName()), $logmsg);
} else {
# Instantiation was successful.
# Setup a timeout to wait for ISUP.
......@@ -339,7 +328,7 @@ sub checkexpiration($) {
# Yes! Node is up.
print "Setup of $pnode->{'vnode'} on $pnode->{'name'} ".
" succeeded\n";
Log(STATUSLOG, "$self->{'NAME'}, $pnode->{'name'}, ".
Log(STATUSLOG(getPLCName()), "$self->{'NAME'}, $pnode->{'name'}, ".
"setup, success, node came up successfully.");
$self->nodesetupcomplete($pnode);
$numfinished++;
......
......@@ -76,7 +76,29 @@ sub new($$$$$) {
# Clean up anything left behind by a terminated monitor
# XXX: this is kind of hacky, but it works.
my @vnodes = ExpNodes($PLABTESTING_PID, $PLABTESTING_EID);
#
# NOTE: we grab all the nodes for this plc, OR any vnodes in this
# experiment that don't have entries in the plab_slice_nodes table.
# This presents a nice race, but we don't have a great way to solve
# right now.
my $plcname = getPLCName();
my @vnodes = ();
my $qres = DBQueryFatal("select r.node_id" .
" from reserved as r" .
" left join plab_slice_nodes as psn" .
" on r.node_id=psn.node_id" .
" left join plab_plc_info as ppi" .
" on psn.plc_idx=ppi.plc_idx" .
" where r.pid='$PLABTESTING_PID'" .
" and r.eid='$PLABTESTING_EID'" .
" and (ppi.plc_name='$plcname'" .
" or ppi.plc_name is NULL)");
if ($qres->num_rows()) {
while (my @row = $qres->fetchrow_array()) {
my $vnodename = $row[0];
push @vnodes, $vnodename;
}
}
if (@vnodes) {
system("$VNODE_SETUP -f -k -n 100 $PLABTESTING_PID $PLABTESTING_EID");
Node::DeleteVnodes(@vnodes);
......
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2003 University of Utah and the Flux Group.
# Copyright (c) 2000-2003, 2008 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
......@@ -17,7 +17,7 @@ use POSIX ":sys_wait_h";
#
sub usage()
{
print STDERR "Usage: plabmonitord [-dS]\n";
print STDERR "Usage: plabmonitord [-dS] <plcname>\n";
print STDERR " -d Debug mode.\n";
print STDERR " -S Run WITHOUT reading monitor state from database;\n";
print STDERR " new state will still be written (default is to" .
......@@ -27,6 +27,8 @@ sub usage()
my $optlist = "dS";
my $debug = 0;
my $stateful = 1;
my $plcname = '';
my $plctype = '';
#
# Only real root can call this.
......@@ -82,9 +84,6 @@ my %options = ();
if (! getopts($optlist, \%options)) {
usage();
}
if (@ARGV) {
usage();
}
if (defined($options{"d"})) {
$debug = 1;
}
......@@ -92,6 +91,36 @@ if (defined($options{'S'})) {
$stateful = 0;
}
#
# Grab the supplied plcname and ensure we know about it.
#
if (scalar(@ARGV) == 1) {
$plcname = shift(@ARGV);
# XXX need to escape this better
if ($plcname =~ /\'/) {
print STDERR "plcname has illegal characters: $plcname\n";
usage();
}
my $qres = DBQueryFatal("select plc_name,node_type" .
" from plab_plc_info" .
" where plc_name='$plcname'");
if (!$qres->numrows()) {
print STDERR "Unknown plc $plcname!\n";
exit(-62);
}
($plcname,$plctype) = $qres->fetchrow_array();
# tell other libplabmon users, sigh
setPLCName($plcname);
}
else {
print STDERR "Must supply plcname argument!\n";
usage();
}
#
# Function prototypes
#
......@@ -101,8 +130,8 @@ sub fatal($);
#
# Global vars
#
my $LOGFILE = "$TB/log/plabmonitord";
my $PIDFILE = "/var/run/plabmonitord.pid";
my $LOGFILE = "$TB/log/plabmonitord-$plcname";
my $PIDFILE = "/var/run/plabmonitord-$plcname.pid";
my $MINSLEEP = 2; # Sleep for no less than 2 seconds.
my $MAXWINSIZE = 40; # Degree of parallelization.
my $MAXSLEEPTIME = 600; # Don't ever sleep for longer than this - we need
......@@ -133,16 +162,17 @@ system("echo '$PID' > $PIDFILE") == 0 or
die("*** $0:\n".
" Could not create $PIDFILE!");
# pid -> pool mapping; passed in as param to pool setup funtion.
# pid -> pool mapping; passed in as param to pool setup function.
my %chpid2pool = ();
print "Plab Monitor Daemon starting... pid $$, at ".`date`;
print "Plab Monitor Daemon ($plcname) starting... pid $$, at ".`date`;
#
# Open the status log. This will be used by the pools to log
# node success/fail results, and other status info.
#
OpenLog(STATUSLOG, STATUSLOGPATH) or die "Can't open status log!";
OpenLog(STATUSLOG($plcname), STATUSLOGPATH($plcname))
or die "Can't open status log!";
#
# Create the node pools.
......@@ -259,14 +289,6 @@ while (1) {
}
}
# This is the best place to get an idea of running plabnode procs.
my @procs = `ps axwww | grep 'emulab-ops plab-' | wc -l`;
my $pcount = 0;
if (scalar(@procs) > 0) {
$procs[0] =~ /(\d+)/;
$pcount = $procs[0];
}
# Look for expired processes. Calling checkexpiration on a pool
# has the side effect of checking for ISUP (or ISUP expiration) for
# any nodes pending thusly in the pool. The return value is the
......@@ -277,9 +299,6 @@ while (1) {
$windowsize -= $numfinished;
}
# Log diff between believed window size, and "actual"
print "winsize = $windowsize / runprocs = $pcount\n";
# We may have just fired off a bunch of kills, so chill for a bit to
# let things quiesce.
sleep($CHILLTIME);
......@@ -301,14 +320,21 @@ sub updatenodepool($) {
print "Updating node membership in pool: $pool->{'NAME'}\n";
# XXX: checking node type like this is mighty expensive! Can't we just
# check the base type for this plc?
# XXX: need to change everything to deal with vnodes rather than pnodes.
#
# NOTE: in the query below, we filter by plctype, but append phys to the
# type string! In libplab, when nodes are added to the db, we also
# auto-append "phys" to create the phys category of the plab type.
my $qres =
DBQueryFatal("select r.node_id from reserved as r ".
"left join nodes as n on n.node_id=r.node_id ".
"left join node_types as nt on n.type = nt.type ".
"where r.pid='$poolpid' and ".
" r.eid='$pooleid' and ".
" nt.isplabphysnode = 1 ".
" nt.isplabphysnode = 1 and ".
" nt.type='${plctype}phys'".
"order by rand()");
if ($qres and $qres->num_rows()) {
......@@ -346,7 +372,7 @@ sub updatenodepool($) {
print "calcnextcheck($pnodename) = ".($nct-time())."\n";
}
Log(STATUSLOG, "plabmonitord, $pnodename, addtopool, ".
Log(STATUSLOG($plcname), "plabmonitord, $pnodename, addtopool, ".
"nostat, node added to pool $pool->{'NAME'}");
}
# Mark this node as still in the pool as of this check.
......@@ -361,7 +387,7 @@ sub updatenodepool($) {
if ($poolpnodes->{$pnodename}->{'updtime'} != $now) {
print "Removing $pnodename from pool: $pool->{'NAME'}\n";
delete $poolpnodes->{$pnodename};
Log(STATUSLOG, "plabmonitord, $pnodename, removefrompool, ".
Log(STATUSLOG($plcname), "plabmonitord, $pnodename, removefrompool, ".
"nostat, node removed from pool $pool->{'NAME'}");
}
}
......
......@@ -72,10 +72,10 @@ def main(args):
plab = libplab.Plab()
if slicename != None:
slice = plab.loadSliceNoDB(slicename)
slice = plab.loadSliceDirect(slicename)
pass
else:
slice = plab.loadSlice(pid, eid)
slice = plab.loadSliceByNode(pid, eid, nodeid)
pass
if command == "alloc":
......@@ -91,6 +91,7 @@ def main(args):
# Note that vnode_setup boots the node
pass
except Exception, e:
traceback.print_exc()
print "Node setup failed on %s" % nodeid
processException(command, nodeid, e)
try: node.free()
......
......@@ -2,7 +2,7 @@
# -*- python -*-
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2003 University of Utah and the Flux Group.
# Copyright (c) 2000-2003, 2008 University of Utah and the Flux Group.
# All rights reserved.
#
......@@ -11,12 +11,11 @@ sys.path.append("@prefix@/lib")
import getopt
from libtestbed import *
import libplab
import traceback
usage = "%prog [-vd] {create|destroy} pid eid\n" \
" Without Emulab DB:\n" \
"%prog [-vd] [-u <user1,...>] [-n <node1,...>] [-m <instmethod>] \n" \
" -c <slicedesc> {create|destroy} slicename"
# [-w <url>]
usage = "\t%prog [-vd] {create|destroy|metaup} pid eid [-p plc slicename]\n" \
"\t%prog [-vd] [-u <user1,...>] [-n <node1,...>] [-m <instmethod>] \n"\
"\t -c <slicedesc> [-w <url>] {create|destroy} slicename"
def main(args):
me = args[0]
......@@ -31,19 +30,26 @@ def main(args):
help="Slice description",default=None)
parser.add_option("-m","--instmethod",dest="instmethod",action="store",
help="Slice instantiation method",default=None)
# parser.add_option("-w","--sliceurl",dest="sliceurl",action="store_true",
# help="Slice URL",default=None)
parser.add_option("-w","--sliceurl",dest="sliceurl",action="store",
help="Slice URL",default=None)
parser.add_option("-p","--plc",dest="plc",action="store",
help="PLC Name",default=None)
command,slicename = None,None
userlist,nodelist = None,None
pid,eid = None,None
(opts, args) = parser.parse_args()
usedb = True
if len(args) == 2:
usedb = False
command,slicename = args
if args[0] == 'create' and (opts.slicedesc == None \
or opts.slicedesc == ''):
parser.error("Must supply a slice description if creating by slicename!")
parser.error("Must supply a slice description if creating" \
" by slicename!")
pass
if opts.plc == None:
parser.error("Must supply a plc if creating by slicename!")
pass
if opts.nodes != None:
nodelist = opts.nodes.split(',')
......@@ -52,7 +58,7 @@ def main(args):
nodelist = []
pass
if opts.users != None:
userlist = opts.nodes.split(',')
userlist = opts.users.split(',')
pass
else:
userlist = []
......@@ -61,31 +67,93 @@ def main(args):
elif len(args) == 3:
command,pid,eid = args
pass
elif len(args) == 4:
command,pid,eid,slicename = args
if not opts.plc or opts.plc == '':
parser.error("When specifying a slicename, you must also specify" \
" a PLC!")
pass
pass
else:
parser.error("Incorrect number of arguments")
pass
plab = libplab.Plab()
slicelist = []
if command == "create":
if usedb:
slice = plab.createSlice(pid, eid)
if pid and eid and slicename:
slice = plab.createSlice(pid,eid,opts.plc,slicename)
slicelist.append(slice)
pass
elif pid and eid:
slicelist = plab.createSlices(pid,eid)
else:
slice = plab.createSliceDirect(opts.plc,slicename,
opts.slicedesc,opts.sliceurl,
userlist=userlist,nodelist=nodelist,
instmethod=opts.instmethod)
slicelist.append(slice)
pass
pass
elif command == "destroy":
if pid and eid and slicename:
slice = plab.loadSlice(pid,eid,opts.plc,slicename)
slice.destroy()
pass
elif pid and eid:
failedslices = []
slicelist = plab.loadSlices(pid,eid)
for slice in slicelist:
try:
slice.destroy()
except:
print "Failed to destroy %s:" % str(slice.slicename)
failedslices.append(slice.slicename)
traceback.print_exc()
pass
pass
if not failedslices == []:
raise RuntimeError("Could not destroy some slices: %s" % \
','.join(failedslices))
pass
else:
slice = plab.createSliceNoDB(slicename,opts.slicedesc,
slice = plab.loadSliceDirect(opts.plc,slicename,
slicedescr=opts.slicedesc,
userlist=userlist,nodelist=nodelist,
instmethod=opts.instmethod)
slice.destroy()
pass
pass
elif command == "destroy":
if usedb:
slice = plab.loadSlice(pid, eid)
elif command == "metaup":
if pid and eid and slicename:
slice = plab.loadSlice(pid,eid,opts.plc,slicename)
slice.updateSliceMeta()
pass
elif pid and eid:
failedslices = []
slicelist = plab.loadSlices(pid, eid)
for slice in slicelist:
try:
slice.updateSliceMeta()
except:
print "Failed to update ticket for %s:" % \
str(slice.slicename)
failedslices.append(slice.slicename)
traceback.print_exc()
pass
pass
if not failedslices == []:
raise RuntimeError("Could not update tickets for some slices:"
" %s" % '.'.join(failedslices))
pass
else:
slice = plab.loadSliceNoDB(slicename,slicedescr=opts.slicedesc,
userlist=userlist,nodelist=nodelist,
instmethod=opts.instmethod)
slice = plab.loadSliceDirect(slicename,slicedescr=opts.slicedesc,
userlist=userlist,nodelist=nodelist,
instmethod=opts.instmethod)
slice.updateSliceMeta()
pass
slice.destroy()
pass
else:
usage(me)
......
......@@ -709,20 +709,23 @@ sub doSwapout($) {
"where pid='$pid' and eid='$eid'");
if ($db_result->numrows) {
# Are there any dslice nodes left?
# Are there any nodes left in the slice?
$db_result =
DBQueryFatal("select n.node_id from nodes as n ".
"left join node_types as nt on n.type = nt.type ".
"left join reserved as r ".
" on r.node_id = n.node_id ".
"where r.pid='$pid' and r.eid='$eid' ".
" and nt.isplabdslice = 1");
DBQueryFatal("select r.node_id ".
" from plab_slices as ps".
" left join plab_slice_nodes as psn ".
" on (ps.slicename=psn.slicename ".
" and ps.plc_idx=psn.plc_idx) ".
" left join reserved as r ".
" on psn.node_id=r.node_id ".
" where ps.pid='$pid' and ps.eid='$eid'".
" and r.node_id is not NULL");
if (!$db_result->numrows) {
print "Destroying Planetlab slice.\n";
print "Tearing down Slices.\n";
TBDebugTimeStamp("plabslice destroy started");
if (system("plabslice destroy $pid $eid")) {
tberror "Failed to destroy Plab dslice.";
tberror "Failed to tear down Slices.";
$swapout_errors = 1;
}
TBDebugTimeStamp("plabslice destroy finished");
......@@ -990,37 +993,33 @@ sub doSwapin($) {
# dslice now
#
if ($type > UPDATE_RECOVER) {
# Are there any Plab nodes?
# Are there any Plab nodes? First get a list of node types in the exp;
# if any are types hosted by any of the PLCs we know about, create
# all slices necessary for the experiment in a single plabslice call.
$db_result =
DBQueryFatal("select n.node_id from nodes as n ".
"left join node_types as nt on n.type = nt.type ".
"left join reserved as r on r.node_id = n.node_id ".
"where r.pid='$pid' and r.eid='$eid' ".
" and nt.isplabdslice = 1");
DBQueryFatal("select nt.type,ppi.plc_name from nodes as n ".
" left join node_types as nt on n.type = nt.type ".
" left join reserved as r on r.node_id = n.node_id ".
" left join plab_plc_info as ppi ".
" on nt.type = ppi.node_type".
" where r.pid='$pid' and r.eid='$eid'".
" and ppi.node_type is not NULL".
" group by nt.type");
if ($db_result->numrows) {
# Does slice already exist?
$db_result =
DBQueryFatal("select slicename from plab_slices ".
"where pid='$pid' and eid='$eid'");
if (! $db_result->numrows) {
my @plabnodes = ();
while (my ($node) = $db_result->fetchrow_array()) {
push(@plabnodes, $node);
}