Commit 2be10d86 authored by Leigh B Stoller's avatar Leigh B Stoller

Merge branch 'mymaster'

parents 64702af5 2b095d85
......@@ -3540,6 +3540,31 @@ sub ClearReservedVlanTags($)
return 0;
}
#
# This is slightly different then above. Rather then releasing all
# reserved tags, we release only the tags that are "dangling"; these
# are tags in the reserved_vlantags table, but without a corresonding
# entry in the lans table. Used from the Protogeni code, when
# releasing a ticket (which reserved some tags that will not be used).
#
sub ClearUnusedReservedVlanTags($)
{
my ($self) = @_;
# Must be a real reference.
return -1
if (! ref($self));
my $idx = $self->idx();
return -1
if (! DBQueryWarn("delete r from reserved_vlantags as r ".
"left join lans as l on l.lanid=r.lanid ".
"where l.lanid is null and r.exptidx='$idx'"));
return 0;
}
#
# Does experiment have any program agents.
#
......
......@@ -263,7 +263,7 @@ SELFLOADER_DATA="__DATA__"
#
# Virtual node network configuration (if you don't want virtual nodes,
# just leave this as is)
# just leave this as is).
#
# Needs at least a /16 network. For a /16 the layout of an IP is:
# X.Y.<pnode>.<vnode>
......@@ -274,6 +274,8 @@ SELFLOADER_DATA="__DATA__"
# the default 172.16/12, then you can have up to 16 * 254 physical hosts.
# If you want more than 254 vnodes per pnode, you are screwed.
#
# ********* DO NOT CHANGE THESE UNLESS YOU ASK UTAH FIRST! *********
#
VIRTNODE_NETWORK=172.16.0.0
VIRTNODE_NETMASK=255.240.0.0
# XXX compat
......
This diff is collapsed.
......@@ -1820,31 +1820,98 @@ sub ReserveVlanTags($)
}
#
# Go through the component hops and find the one that refers to us.
# This is our external network point.
# Need to dig inside the stitching section to find the path.
#
my $stitching_path;
foreach my $ref (GeniXML::FindNodesNS("n:stitching",
$rspec,
$GeniXML::STITCH_NS)->get_nodelist()){
foreach my $path (GeniXML::FindNodes("n:path",
$ref)->get_nodelist()) {
my $path_id = GeniXML::GetText("id", $path);
if ($path_id eq $linkname) {
$stitching_path = $path;
last;
}
}
}
if (!defined($stitching_path)) {
$response = GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"Could not find path in rspec");
goto done;
}
#
# Look at the hop list to find the edge point.
#
my @hoplist = GeniXML::FindNodes("n:hop", $stitching_path)->get_nodelist();
if (! @hoplist) {
$response = GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"No hops in the stitching path");
goto done;
}
if (!GeniHRN::IsValid(GeniCM::GetHopLinkID($hoplist[0]))) {
$response = GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"Invalid URN in first hop in path");
goto done;
}
my ($hopauth) = GeniHRN::Parse(GeniCM::GetHopLinkID($hoplist[0]));
if ($hopauth ne $OURDOMAIN) {
# Reverse the list to make life easier.
@hoplist = reverse(@hoplist);
}
#
# Go through the hop list to find the edge point. This will
# be the first hop that is in a different domain.
#
my $hopref;
foreach my $ref (GeniXML::FindNodes("n:component_hop",
$linkref)->get_nodelist()) {
my $component_urn = GeniXML::GetNodeId($ref);
my ($domain,undef,undef) = GeniHRN::Parse($component_urn);
if (defined($domain) and $domain eq $me->domain()) {
$hopref = $ref;
my $lasthop;
foreach my $hop (@hoplist) {
my $hopurn = GeniCM::GetHopLinkID($hop);
next
if (! GeniHRN::IsValid($hopurn));
my ($auth,undef,undef) = GeniHRN::Parse($hopurn);
next
if (!defined($auth));
if ($auth ne $OURDOMAIN) {
$hopref = $lasthop;
last;
}
$lasthop = $hop;
}
if (!defined($hopref)) {
$response = GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"Could not find hop in link");
$response = GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Could not find the edge hop");
goto done;
}
my $hop_urn = GeniXML::GetNodeId($hopref);
my (undef,undef,$network_id) = GeniHRN::Parse($hop_urn);
my $hopurn = GeniCM::GetHopLinkID($hopref);
my (undef,undef,$network_stuff) = GeniHRN::Parse($hopurn);
my (undef,undef,$network_id) = split('//', $network_stuff);
my $network = ExternalNetwork->Lookup($network_id);
if (!defined($network)) {
$response = GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"$hop_urn is not an external network");
"$hopurn is not an external network");
goto done;
}
#
# Special case; if the lan has a tag reserved already, the tag we
# got must be an exact match. This can happen if the ticket is
# being updated before redeem, at the other side.
#
if (my $t = VLan::GetReservedVlanTag($slice_experiment, $linkname)) {
if ((grep {$_ == $t} @{ $taglist })) {
$actualtag = $t;
goto gottag;
}
$response = GeniResponse->Create(GENIRESPONSE_SEARCHFAILED, undef,
"Already have a tag reserved");
goto done;
}
......@@ -1972,6 +2039,7 @@ sub ReserveVlanTags($)
goto done;
}
gottag:
print STDERR "Agreed on tag $actualtag\n";
GeniXML::SetText("vlantag", $linkref, $actualtag);
$response = GeniResponse->Create(GENIRESPONSE_SUCCESS,
GeniXML::Serialize($rspec));
......
......@@ -796,6 +796,14 @@ sub Release($$)
my @nodes = ();
my @vhosts = ();
#
# Release unused reserved vlantags.
#
$experiment->ClearUnusedReservedVlanTags();
#
# Release nodes.
#
foreach my $ref (GeniXML::FindNodes("n:node",
$self->rspec())->get_nodelist()) {
# Skip lan nodes; they are fake.
......
#!/usr/bin/perl -w
#
# GENIPUBLIC-COPYRIGHT
# Copyright (c) 2008-2011 University of Utah and the Flux Group.
# Copyright (c) 2008-2012 University of Utah and the Flux Group.
# All rights reserved.
#
use strict;
......@@ -15,7 +15,8 @@ use Data::Dumper;
#
sub usage()
{
print STDERR "Usage: reservevlans <slice_urn> <linkname> <rspec>\n";
print STDERR
"Usage: reservevlans <slice_urn> <linkname> <hopurn> <rspec>\n";
exit(1);
}
my $optlist = "";
......@@ -40,6 +41,7 @@ sub fatal($);
sub busy();
sub ReserveLocalTags(@);
sub ReserveRemoteTags($$@);
sub GetHopLinkID($);
#
# Turn off line buffering on output
......@@ -71,11 +73,12 @@ if (! getopts($optlist, \%options)) {
usage();
}
usage()
if (@ARGV != 3);
if (@ARGV != 4);
my $slice_urn = $ARGV[0];
my $linkname = $ARGV[1];
my $rspecfile = $ARGV[2];
my $hopurn = $ARGV[2];
my $rspecfile = $ARGV[3];
#
# Load the CM cert to act as caller context.
......@@ -138,28 +141,11 @@ if (!defined($other_manager)) {
fatal("Who is the other manager?");
}
#
# Go through the component hops and find the one that refers to us.
# This is our external network point.
#
my $hopref;
foreach my $ref (GeniXML::FindNodes("n:component_hop",
$linkref)->get_nodelist()) {
my $component_urn = GeniXML::GetNodeId($ref);
my ($domain,undef,undef) = GeniHRN::Parse($component_urn);
if (defined($domain) and $domain eq $me->domain()) {
$hopref = $ref;
last;
}
}
if (!defined($hopref)) {
fatal("Could not find hop in link");
}
my $hop_urn = GeniXML::GetNodeId($hopref);
my (undef,undef,$network_id) = GeniHRN::Parse($hop_urn);
my (undef,undef,$network_stuff) = GeniHRN::Parse($hopurn);
my (undef,undef,$network_id) = split('//', $network_stuff);
my $network = ExternalNetwork->Lookup($network_id);
if (!defined($network)) {
fatal("$hop_urn is not an external network");
fatal("$hopurn is not an external network");
}
# The bounds of the vlan tags we can use for this network point.
my $mintag = $network->min_vlan();
......@@ -180,15 +166,6 @@ my $vlan = VLan->Lookup($experiment, $linkname);
if (defined($vlan)) {
fatal("There is already a lan object for $linkname; $vlan");
}
#
# The point of this is to create the VLan object, just long enough to
# get a lanid and a tag assigned.
#
$vlan = VLan->Create($experiment, $linkname);
if (!defined($vlan)) {
fatal("Could not create vlan for $linkname");
}
my $lanid = $vlan->lanid();
#
# Setup a signal handler to clean things up.
......@@ -201,8 +178,33 @@ $SIG{HUP} = \&handler;
$SIG{TERM} = \&handler;
$SIG{INT} = \&handler;
# The other side returns suitable tags.
my @othertags = ();
#
# Special case; if the lan has a tag reserved already, we must
# try with that one tag and if the other side says no, we are done.
#
if (my $t = VLan::GetReservedVlanTag($experiment, $linkname)) {
my $tag = ReserveRemoteTags($other_manager, \@othertags, $t);
if ($tag) {
print STDERR "Agreed on tag $tag.\n";
exit(0);
}
# Tell caller we failed to reserve tags.
exit(-1)
}
#
# The point of this is to create the VLan object, just long enough to
# get a lanid and a tag assigned.
#
$vlan = VLan->Create($experiment, $linkname);
if (!defined($vlan)) {
fatal("Could not create vlan for $linkname");
}
my $lanid = $vlan->lanid();
while (my @tags = ReserveLocalTags(@othertags)) {
my $tag = ReserveRemoteTags($other_manager, \@othertags, @tags);
if ($tag) {
......@@ -382,3 +384,15 @@ sub busy()
# Exit value important; positive integer indicate BUSY to caller.
exit(1);
}
sub GetHopLinkID($)
{
my ($ref) = @_;
my $result = "";
my $link = FindFirst("n:link", $ref);
if (defined($link)) {
$result = GetText("id", $link);
}
return $result;
}
......@@ -33,19 +33,6 @@ http://www.protogeni.net/resources/rspec/2/request.xsd"
<interface_ref client_id="right:if0" />
<property source_id="left:if0" dest_id="right:if0" capacity="100000"/>
<property source_id="right:if0" dest_id="left:if0" capacity="100000"/>
<component_hop
component_urn="urn:publicid:IDN+emulab.net+link+instageni">
<interface_ref
component_node_urn="urn:publicid:IDN+emulab.net+node+instageni"
component_interface_id="eth0"/>
</component_hop>
<component_hop
component_urn="urn:publicid:IDN+utah.geniracks.net+link+emulab">
<interface_ref
component_node_urn="urn:publicid:IDN+utah.geniracks.net+node+emulab"
component_interface_id="eth0"/>
</component_hop>
</link>
<stitching xmlns="http://hpn.east.isi.edu/rspec/ext/stitch/0.1/"
......
......@@ -2376,6 +2376,7 @@ CREATE TABLE `node_history` (
`exptidx` int(10) unsigned default NULL,
`stamp` int(10) unsigned default NULL,
`cnet_IP` varchar(15) default NULL,
`cnet_mac` varchar(12) default NULL,
`phys_nodeid` varchar(32) default NULL,
PRIMARY KEY (`history_id`),
KEY `node_id` (`node_id`,`history_id`),
......@@ -2384,7 +2385,9 @@ CREATE TABLE `node_history` (
KEY `cnet_IP` (`cnet_IP`),
KEY `nodestamp` (`node_id`,`stamp`),
KEY `ipstamp` (`cnet_IP`,`stamp`),
KEY `hid_stamp` (`history_id`,`stamp`)
KEY `hid_stamp` (`history_id`,`stamp`),
KEY `cnet_mac` (`cnet_mac`),
KEY `macstamp` (`cnet_mac`,`stamp`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
......
#
# Add more slots to node_history to allow recording dynamic virtual nodes.
#
use strict;
use libdb;
sub DoUpdate($$$)
{
my ($dbhandle, $dbname, $version) = @_;
if (!DBSlotExists("node_history", "cnet_mac")) {
print " *** Updating a big table ... please be very patient.\n";
DBQueryFatal("alter table node_history ".
" add `cnet_mac` varchar(12) default NULL ".
" after cnet_IP," .
" add KEY `cnet_mac` (`cnet_mac`),".
" add KEY `macstamp` (`cnet_mac`,`stamp`)");
}
return 0;
}
1;
# Local Variables:
# mode:perl
# End:
......@@ -47,6 +47,7 @@ my $DELAYTHRESH = @DELAYTHRESH@;
my $PGENISUPPORT = @PROTOGENI_SUPPORT@;
my $PGENIRACK = @PROTOGENI_GENIRACK@;
my $OURDOMAIN = "@OURDOMAIN@";
my $MAINSITE = @TBMAINSITE@;
my $mycmurn = GeniHRN::Generate("@OURDOMAIN@", "authority", "cm");
# Flags.
......@@ -1631,6 +1632,56 @@ sub LoadVirtLans($)
}
}
#
# Sanity check the shared lan requests.
#
foreach my $virtlan (values(%{ $self->vlans() })) {
next
if (!defined($virtlan->_portvlan()));
my $porttoken = $virtlan->_portvlan();
#
# Map the token.
#
my $rowref = Lan->LookupSharedVLanByToken($porttoken);
if (!defined($rowref)) {
tberror("No shared vlan exists for $porttoken!\n");
return -1;
}
my $portvlan = VLan->Lookup($rowref->{'lanid'});
if (!defined($portvlan)) {
tberror("Target vlan for $porttoken does not exist!\n");
return -1;
}
# Very primitive access check.
if (! ($rowref->{'open'} || $self->user()->IsAdmin())) {
tberror("Target vlan for $porttoken is not open!\n");
return -1;
}
#
# Oh this is bogus; Utah's Ciscos run firmware that dates back to
# the age of the dinosaurs, and so we cannot do vlans greater
# then 1000 on them. This means that we have to put a feature
# on those nodes that are attached to switches that *are* able
# to (the procurves).
#
if ($MAINSITE) {
my $tag = $portvlan->GetTag();
if (defined($tag) && $tag > 1000) {
#
# Add a desire to all of the nodes.
#
foreach my $member ($virtlan->memberlist()) {
$member->virt_node()->_desires()->{"highvlan"} = "1.0";
}
}
}
# Convert to actual object for later
$virtlan->_portvlan($portvlan);
}
#
# Load up the virt_bridges.
#
......@@ -2684,30 +2735,8 @@ sub GenVirtLans($)
# Special case that we use to connect a port to a vlan
# in another experiment. There is no delay or other stuff.
#
my $porttoken = $vlan->_portvlan();
my $lannode = "portlan/$vname";
my $lannode = "portlan/$vname";
#
# Map the token.
#
my $rowref = Lan->LookupSharedVLanByToken($porttoken);
if (!defined($rowref)) {
tberror("No shared vlan exists for $porttoken!\n");
return -1;
}
my $portvlan = Lan->Lookup($rowref->{'lanid'});
if (!defined($portvlan)) {
tberror("Target vlan for $porttoken does not exist!\n");
return -1;
}
# Very primitive access check.
if (! ($rowref->{'open'} || $self->user()->IsAdmin())) {
tberror("Target vlan for $porttoken is not open!\n");
return -1;
}
# Convert to actual object for later
$vlan->_portvlan($portvlan);
# Lan node for assign.
$self->createNode($lannode, $mycmurn, "lan", '1', '',
{ 'virtualization_type' => 'raw' });
......
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