Commit 312f6259 authored by Leigh Stoller's avatar Leigh Stoller

Merge branch 'master' of git-public.flux.utah.edu:/flux/git/emulab-devel

parents 597dc491 f2b15557
......@@ -397,6 +397,33 @@ sub Create($$$)
return Interface->Lookup($node_id, $card, $port);
}
#
# Delete a logical interface.
#
sub Delete($)
{
my ($self) = @_;
if (! $self->logical()) {
print STDERR "Refusing to delete real $self\n";
return -1;
}
my $node_id = $self->node_id();
my $card = $self->card();
my $port = $self->port();
return -1
if (!DBQueryWarn("delete from interface_state ".
"where node_id='$node_id' and card='$card' and ".
" port='$port'"));
return -1
if (!DBQueryWarn("delete from interfaces ".
"where logical=1 and ".
" node_id='$node_id' and card='$card' and ".
" port='$port'"));
return 0;
}
#
# Create a fake object, as for the mapper (assign_wrapper) during debugging.
#
......@@ -872,6 +899,38 @@ sub port1($) { return $_[0]->field('port1'); }
sub port2($) { return $_[0]->field('port2'); }
sub type($) { return $_[0]->field('type'); }
sub logical($) { return $_[0]->field('logical'); }
sub IsActive($) { return ($_[0]->type() eq "Unused" ? 0 : 1); }
#
# Delete a logical wire and its interfaces.
#
sub Delete($)
{
my ($self) = @_;
my ($interface1, $interface2) = $self->Interfaces();
if (! $self->logical()) {
print STDERR "Refusing to delete real $self\n";
return -1;
}
if (defined($interface1) && $interface1->logical()) {
$interface1->Delete() == 0
or return -1;
}
if (defined($interface2) && $interface2->logical()) {
$interface2->Delete() == 0
or return -1;
}
my $node_id1 = $self->node_id1();
my $card1 = $self->card1();
my $port1 = $self->port1();
return -1
if (!DBQueryWarn("delete from wires ".
"where logical=1 and node_id1='$node_id1' and ".
" card1=$card1 and port1=$port1"));
return 0;
}
#
# A wire has two interfaces, but we do not always create interface
......@@ -901,8 +960,9 @@ sub Stringify($)
my $card2 = $self->card2();
my $port1 = $self->port1();
my $port2 = $self->port2();
my $type = ($self->logical() ? "LogicalWire" : "Wire");
return "[Wire: $node1:$card1:$port1/$node2:$card2:$port2]";
return "[$type: $node1:$card1:$port1/$node2:$card2:$port2]";
}
#
......@@ -939,6 +999,77 @@ sub DeActivate($)
return 0;
}
#
# Find all logical wires for an experiment.
#
sub ExperimentLogicalWires($$$)
{
my ($class, $experiment, $plist) = @_;
return -1
if (! (ref($plist) && ref($experiment)));
my $exptidx = $experiment->idx();
my @result = ();
# Note that a wire between two pc interfaces will cause this
# query to return two results, one of which is bogus, since
# the wires table is unique on node_id1,card1,port1. Need to
# check for this in the where clause.
my $query_result =
DBQueryWarn("select r.node_id,w.card1,w.port1 from reserved as r ".
"left join interfaces as i on i.node_id=r.node_id ".
"left join wires as w on w.node_id1=r.node_id and ".
" w.card1=i.card and w.port1=i.port ".
"where i.logical=1 and r.exptidx='$exptidx' and ".
" card1 is not null");
return -1
if (!$query_result);
while (my ($nodeid,$card,$port) = $query_result->fetchrow_array()) {
my $wire = Interface::Wire->Lookup("$nodeid:$card:$port");
if (!defined($wire)) {
print STDERR "Could not lookup wire: $nodeid:$card:$port\n";
return -1;
}
push(@result, $wire);
}
@$plist = @result;
return 0;
}
#
# Delete all logical wires for an experiment, as for swapout.
#
sub DeleteLogicalWires($$)
{
my ($class, $experiment) = @_;
my @wires = ();
my $errors = 0;
return -1
if (! ref($experiment));
return -1
if (Interface::Wire->ExperimentLogicalWires($experiment, \@wires));
return 0
if (!@wires);
foreach my $wire (@wires) {
print STDERR "Deleting $wire\n";
if ($wire->IsActive()) {
print STDERR "$wire is still active; cannot delete!\n";
$errors++;
}
if ($wire->Delete()) {
print STDERR "$wire could not be deleted!\n";
$errors++;
}
}
return $errors;
}
##############################################################################
#
# A wrapper class for a "logical wire". This is a wire that exists
......
......@@ -43,9 +43,10 @@ void usage(char * name);
// structure, and sets up the two subscription strings for events.
void writePidFile(string const & pidFile);
void initEvents(string const & server, string const & port,
string const & keyFile, string const & subscription);
string const & keyFile, string const & subscription,
string const & group);
void subscribe(event_handle_t handle, address_tuple_t eventTuple,
string const & subscription);
string const & subscription, string const & group);
void callback(event_handle_t handle,
event_notification_t notification, void *data);
......@@ -63,12 +64,13 @@ void readArgs(int argc, char * argv[])
string port;
string keyFile;
string subscription;
string group;
// Prevent getopt from printing an error message.
opterr = 0;
/* get params from the optstring */
char const * argstring = "s:p:dE:k:u:";
char const * argstring = "s:p:dE:k:u:g:";
int option = getopt(argc, argv, argstring);
while (option != -1)
{
......@@ -93,6 +95,9 @@ void readArgs(int argc, char * argv[])
case 'u':
subscription = optarg;
break;
case 'g':
group = optarg;
break;
case '?':
default:
usage(argv[0]);
......@@ -106,18 +111,19 @@ void readArgs(int argc, char * argv[])
usage(argv[0]);
initEvents(server, port, keyFile, subscription);
initEvents(server, port, keyFile, subscription, group);
}
void usage(char * name)
{
cerr << "Usage: " << name << " -E proj/exp -s server [-d] [-p port] "
<< "[-i pidFile] [-k keyFile] [-u subscription]" << endl;
<< "[-i pidFile] [-k keyFile] [-u subscription] [-g group]" << endl;
exit(-1);
}
void initEvents(string const & server, string const & port,
string const & keyFile, string const & subscription)
string const & keyFile, string const & subscription,
string const & group)
{
cerr << "Initializing event system" << endl;
string serverString = "elvin://" + server;
......@@ -144,7 +150,7 @@ void initEvents(string const & server, string const & port,
address_tuple_t eventTuple = address_tuple_alloc();
subscribe(handle, eventTuple, subscription);
subscribe(handle, eventTuple, subscription, group);
address_tuple_free(eventTuple);
......@@ -152,10 +158,15 @@ void initEvents(string const & server, string const & port,
}
void subscribe(event_handle_t handle, address_tuple_t eventTuple,
string const & subscription)
string const & subscription, string const & group)
{
cerr << "Link subscription names: " << subscription << endl;
eventTuple->objname = const_cast<char *>(subscription.c_str());
string name = subscription;
if (group != "")
{
name += "," + group;
}
cerr << "Link subscription names: " << name << endl;
eventTuple->objname = const_cast<char *>(name.c_str());
// eventTuple->objtype = TBDB_OBJECTTYPE_LINK;
eventTuple->objtype = ADDRESSTUPLE_ANY;
// eventTuple->eventtype = TBDB_EVENTTYPE_MODIFY;
......
system("../../../pubsub/pubsubd -v -d -p 4001");
system("./simple-agent -E delay-agent/single-node -s localhost -k /var/emulab/boot/eventkey -u foobar -p 4001");
......@@ -17,8 +17,6 @@ use vars qw(@ISA @EXPORT);
@ISA = "Exporter";
@EXPORT = qw ( );
# Must come after package declaration!
use lib '@prefix@/lib';
use GeniCMV2;
use GeniResponse;
use GeniCredential;
......
......@@ -17,8 +17,6 @@ use vars qw(@ISA @EXPORT);
@ISA = "Exporter";
@EXPORT = qw ( );
# Must come after package declaration!
use lib '@prefix@/lib';
use GeniDB;
use Genixmlrpc;
use GeniResponse;
......
......@@ -18,7 +18,6 @@ use vars qw(@ISA @EXPORT);
@EXPORT = qw ( );
# Must come after package declaration!
use lib '@prefix@/lib';
use GeniDB;
use GeniResponse;
use GeniTicket;
......
......@@ -17,7 +17,6 @@ use vars qw(@ISA @EXPORT);
@EXPORT = qw ( );
# Must come after package declaration!
use lib '@prefix@/lib';
use GeniDB;
use Genixmlrpc;
use GeniResponse;
......
#!/usr/bin/perl -wT
#
# GENIPUBLIC-COPYRIGHT
# Copyright (c) 2008-2009 University of Utah and the Flux Group.
# Copyright (c) 2008-2011 University of Utah and the Flux Group.
# All rights reserved.
#
package GeniSES;
......@@ -18,7 +18,6 @@ use vars qw(@ISA @EXPORT);
@EXPORT = qw ( );
# Must come after package declaration!
use lib '@prefix@/lib';
use GeniDB;
use User;
use Genixmlrpc;
......
......@@ -5522,7 +5522,7 @@ sub InterpLinksAux($)
# 2 segments in it.
#
my $firstlink = shift(@links);
my $lastlink = pop(@links);
my $lastlink = (@links ? pop(@links) : $firstlink);
my $firstwire = $firstlink->_logicalwire();
my $lastwire = $lastlink->_logicalwire();
......
......@@ -1990,7 +1990,7 @@ sub doReset($@) {
return -1;
}
# Find the vlan that uses this interface.
my $vlanusing = Lan->FindVlanByInterface($experiment, $interface1);
my $vlanusing = VLan->FindVlanByInterface($experiment, $interface1);
if (defined($vlanusing) && $vlanusing->CreatedOnSwitches()) {
print STDERR "Logical wire $wire is in use by $vlanusing; ".
"not allowed to remove $vlan\n";
......
......@@ -2027,7 +2027,7 @@ sub doReset($@) {
return -1;
}
# Find the vlan that uses this interface.
my $vlanusing = Lan->FindVlanByInterface($experiment, $interface1);
my $vlanusing = VLan->FindVlanByInterface($experiment, $interface1);
if (defined($vlanusing) && $vlanusing->CreatedOnSwitches()) {
print STDERR "Logical wire $wire is in use by $vlanusing; ".
"not allowed to remove $vlan\n";
......
......@@ -659,6 +659,16 @@ sub doSwapout($) {
}
}
#
# Clear logical interfaces and wires. This might move to support
# swapmod.
#
print "Removing logical wires.\n";
if (Interface::Wire->DeleteLogicalWires($experiment)) {
tberror("Could not delete logical wires and interfaces\n");
return 1;
}
#
# remove all nodes from the experiment.
# (nfree will send them to RES_FREE_DIRTY)
......
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