Commit aba79edd authored by Leigh B Stoller's avatar Leigh B Stoller

Add support for linkwide properties which are far more efficient wrt the

XML size on really big lans. I do not expect this to be used very often,
but it is handy. On the geni-lib side:

class setProperties(object):
    """Added to a Link or LAN object, this extension tells Emulab based
    clusters to set the symmetrical properties of the entire link/lan to
    the desired characteristics (bandwidth, latency, plr). This produces
    more efficient XML then setting a property on every source/destination
    pair, especially on a very large lan. Bandwidth is in Kbps, latency in
    milliseconds, plr a floating point number between 0 and 1. Use keyword
    based arguments, all arguments are optional:

        link.setProperties(bandwidth=100000, latency=10, plr=0.5)

    """
parent 428d54d3
......@@ -2561,18 +2561,27 @@ sub GetTicketAuxAux($)
$besteffort = 1;
}
}
#
# Link wide properties. Saves a lot of XML when all the user
# wants is to set symmetrical properties for the entire lan.
#
my $linkwide_properties = GeniXML::GetLinkWideProperties($linkref);
#
# On a really big lan, we do not want to search the properties
# over and over.
#
my %properties = ();
my @properties = GeniXML::GetLinkProperties($linkref);
foreach my $property (@properties) {
foreach my $property (GeniXML::GetLinkProperties($linkref)) {
my $source = GetText("source_id", $property);
my $dest = GetText("dest_id", $property);
$properties{"$source:$dest"} = $property;
if (!(defined($source) && defined($dest) ||
$source eq "" || $dest eq "")) {
GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"$lanname: Missing source or dest in property");
}
$properties{"$source:$dest"} = $property;
}
my $edgecount = 0;
foreach my $ref (@interfaces) {
......@@ -2759,11 +2768,32 @@ sub GetTicketAuxAux($)
my $restbw = undef;
my $uselinkdelay = $forcedelay;
# Let user override.
my $user_bandwidth = GeniXML::GetBandwidth($linkref);
if (defined($user_bandwidth)) {
$bandwidth = $user_bandwidth;
$rbandwidth = $user_bandwidth;
# Let linkwide property override defaults above.
if (defined($linkwide_properties)) {
if (defined($linkwide_properties->{"bandwidth"})) {
$bandwidth = $linkwide_properties->{"bandwidth"};
$rbandwidth = $bandwidth;
$uselinkdelay = 1
if (!$nobwshaping);
}
if (defined($linkwide_properties->{"latency"})) {
$latency = $linkwide_properties->{"latency"};
if (@interfaces == 2) {
$latency = $latency / 2.0
}
$rlatency = $latency;
# Latency, we have to use a link delay.
$uselinkdelay = 1;
}
if (defined($linkwide_properties->{"lossrate"})) {
$lossrate = $linkwide_properties->{"lossrate"};
if (@interfaces == 2) {
$lossrate = 1.0 - sqrt(1.0 - $lossrate);
}
$rlossrate = $lossrate;
# Lossrate, we have to use a link delay.
$uselinkdelay = 1;
}
}
# Look for a link to a bridge.
......@@ -2821,7 +2851,7 @@ sub GetTicketAuxAux($)
}
$bridge_vname = $bblob->{'name'};
}
elsif (@properties) {
elsif (keys(%properties)) {
$uselinkdelay = 1
if (!$nobwshaping);
......@@ -2831,7 +2861,7 @@ sub GetTicketAuxAux($)
# let do them independently below.
#
if (@interfaces == 2) {
foreach my $property (@properties) {
foreach my $property (values(%properties)) {
#
# Need to make sure we get the correct direction.
#
......
......@@ -36,7 +36,7 @@ use vars qw(@ISA @EXPORT);
@ISA = "Exporter";
@EXPORT = qw(Parse ParseFile GetXmlVersion IsVersion0 FindNodes FindNodesNS
FindFirst FindFirstNS FindElement FindAttr GetNodeByVirtualId GetLinkByVirtualId
IsLanNode IsLocalNode IsTunnel GetExpires GetBandwidth GetIp GetVnodeId
IsLanNode IsLocalNode IsTunnel GetExpires GetLinkWideProperties GetIp GetVnodeId
GetNodeId GetVirtualId GetInterfaceId GetInterfaceNodeId GetSliverId
GetManagerId GetColocate GetSubnodeOf GetStartupCommand GetTarball
GetVirtualizationType SetVirtualizationSubtype GetVirtualizationSubtype
......@@ -434,19 +434,35 @@ sub SetExpires($$)
}
}
sub GetBandwidth($)
#
# An optimization for when you just want symmetrical properties for the
# entire link/lan. Saves a lot of XML on a big topology.
#
sub GetLinkWideProperties($)
{
my ($link) = @_;
my $result = undef;
if (IsVersion0($link)) {
$result = GeniXML::GetText("bandwidth", $link);
} else {
my $prop = FindFirst("n:property", $link);
if (defined($prop)) {
$result = GeniXML::GetText("capacity", $prop);
}
my $bandwidth = GeniXML::GetText("bandwidth", $link);
return undef
if (!defined($bandwidth));
return {"bandwidth" => $bandwidth};
}
return $result;
my $ref = GeniXML::FindNodesNS("n:properties", $link, $EMULAB_NS)->pop();
return undef
if (!defined($ref));
my $bandwidth = GeniXML::GetText("capacity", $ref);
my $latency = GeniXML::GetText("latency", $ref);
my $lossrate = GeniXML::GetText("packet_loss", $ref);
return undef
if (!(defined($bandwidth) || defined($latency) || defined($lossrate)));
return {"bandwidth" => $bandwidth,
"latency" => $latency,
"lossrate" => $lossrate};
}
sub GetLinkProperties($)
......
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