Commit 7a82778e authored by Leigh B Stoller's avatar Leigh B Stoller

A slew of new support for cooked mode. Swapmod now works pretty well,

although the default is currently to do cooked mode in "basic" mode,
rather then "full" mode.
parent 99c6c7c4
This diff is collapsed.
......@@ -239,6 +239,17 @@ sub GetCertificate($) { return $_[0]->{'CERTIFICATE'}; }
# An alias so that slivers look like aggregates.
sub resource_type($) { return field($_[0], "type"); }
# A place to stash a temporary rspec.
sub rspec($;$)
{
my ($self, $rspec) = @_;
if (defined($rspec)) {
$self->{'RSPEC'} = $rspec;
}
return $self->{'RSPEC'};
}
# Return the URN.
sub urn($)
{
......@@ -770,6 +781,8 @@ sub Start($$$)
return -1;
}
if ($reservation->SameExperiment($experiment)) {
my $vnode;
#
# Since this is an aggregate, some slivers may already be
# in the started state. Skip those, unless doing a restart.
......@@ -778,14 +791,28 @@ sub Start($$$)
if ($sliver->state() eq "started" && !$restart);
if ($node->isvirtnode()) {
# A virtnode on a shared physical node needs reboot or setup
if ($node->sharing_mode()) {
if ($restart && $sliver->state() eq "started") {
$reboots{$node->node_id} = $node;
}
else {
$vnodes{$node->node_id} = $node;
}
next;
}
# See below.
$vnode = $node;
# A virtnode on a shared physical node needs nothing else.
next
if ($node->sharing_mode());
# But if non-shared, have to make sure that the phys node
# gets loaded.
#
# Now it gets messy. Do not want to mess with the physnode
# if its running other vnodes, and we just need to fire up
# a new one. But if the physnode is going to get rebooted,
# then there is no need to do anything with the vnodes; they
# will boot up with the physnode.
#
# But, have to make sure that the phys node gets setup.
#
my $physnodeid = $node->phys_nodeid();
next
if (exists($poweron{$physnodeid}) ||
......@@ -798,21 +825,22 @@ sub Start($$$)
}
}
#
# Look to see if local physical node was stopped (powered off).
# If the node is not imageable, then there is not much to
# do except turn it on or reboot it. I am assuming that a
# a non imageable node is always in raw mode.
#
if (!$node->isremotenode() &&
($sliver->state() eq "stopped")) {
if (!$node->imageable()) {
if ($sliver->state() eq "stopped") {
$poweron{$node->node_id} = $node;
}
else {
# node_reboot is smart enough to know that if a pnode
# is rebooted it can ignore the vnodes on it, so do
# not optimize this here.
$reboots{$node->node_id} = $node;
}
next
if (!$node->imageable());
next;
}
#
# See if the node is running the requested OS.
#
my $osinfo = OSinfo->Lookup($node->def_boot_osid());
if (!defined($osinfo)) {
print STDERR "Could not get osinfo for $node\n";
......@@ -852,6 +880,14 @@ sub Start($$$)
$reloads{$image->imageid()} = [ ];
}
push(@{ $reloads{$image->imageid()} }, $node);
# Reload means reboot or power on.
if (!defined($vnode) && $sliver->state() eq "stopped") {
$poweron{$node->node_id} = $node;
}
else {
$reboots{$node->node_id} = $node;
}
}
else {
#
......@@ -861,6 +897,33 @@ sub Start($$$)
print STDERR " Could not os_select $node to $osinfo\n";
return -1;
}
#
# If the node is going to get rebooted, then do not need
# to worry about the vnodes on it. But if the node is ready
# to go, then we have to do the vnodes. Remember, we do not
# reboot the physnode since we might only be adding a new node
# in which case, a full reboot is wrong.
#
if (! $node->IsUp()) {
if ($sliver->state() eq "stopped" && !defined($vnode)) {
$poweron{$node->node_id} = $node;
}
else {
$reboots{$node->node_id} = $node;
}
}
elsif ($restart && !defined($vnode)) {
# Just a physnode that needs restarting.
$reboots{$node->node_id} = $node;
}
elsif (defined($vnode)) {
if ($sliver->state() eq "started") {
$reboots{$vnode->node_id} = $vnode;
}
else {
$vnodes{$vnode->node_id} = $vnode;
}
}
}
}
else {
......
......@@ -150,7 +150,7 @@ sub Resolve($)
undef, "Nothing here by that name");
}
my $rspec = GetAdvertisement(0, $node->node_id(), "0.1");
my $rspec = GetAdvertisement(0, $node->node_id(), "0.1", undef);
if (! defined($rspec)) {
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Could not start avail");
......@@ -237,10 +237,29 @@ sub DiscoverResourcesAux($$$)
}
}
#
# See if one of the credentials is a slice credential. If it is, and
# that slice is active, pass it to ptopgen so that it includes the current
# resources as available.
#
my $experiment = undef;
foreach my $credential (@$credentials) {
my ($auth, $type, $id) = GeniHRN::Parse($credential->target_urn());
if ($type eq "slice") {
# Might not exist here yet.
my $slice = GeniSlice->Lookup($credential->target_urn());
if (defined($slice)) {
# See if the local experiment exists yet.
$experiment = Experiment->Lookup($slice->uuid());
}
last;
}
}
#
# Acquire the advertisement from ptopgen and compress it if requested.
#
my $xml = GetAdvertisement($available, undef, "0.2");
my $xml = GetAdvertisement($available, undef, "0.2", $experiment);
if (! defined($xml)) {
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Could not start avail");
......@@ -258,12 +277,16 @@ sub DiscoverResourcesAux($$$)
#
# Use ptopgen in xml mode to spit back an xml file.
#
sub GetAdvertisement($$$)
sub GetAdvertisement($$$$)
{
my ($available, $pc, $version) = @_;
my ($available, $pc, $version, $experiment) = @_;
my $xml = undef;
my $invocation = "$PTOPGEN -x -g $version -r -p GeniSlices";
if (defined($experiment)) {
my $eid = $experiment->eid();
$invocation .= " -e $eid";
}
$invocation .= " -a" unless $available;
if (defined($pc)) {
$invocation .= " -1 $pc";
......@@ -1535,6 +1558,7 @@ sub SliverWorkAux($$$$$$$)
my $response;
my $ticket;
my $rspec;
my $oldmanifest;
require Interface;
# V2 API support.
......@@ -1665,10 +1689,18 @@ sub SliverWorkAux($$$$$$$)
print GeniXML::Serialize($rspec);
# The Manifest starts out as a copy of the rspec.
my $manifest = $rspec->cloneNode(1);
#
# Find current slivers and save.
#
if (defined($aggregate)) {
$oldmanifest = $aggregate->GetManifest(0);
if (!defined($oldmanifest)) {
$message = "Internal error getting manifest";
goto bad;
}
my @slivers;
if ($aggregate->SliverList(\@slivers) != 0) {
$message = "Could not get sliverlist for $aggregate";
......@@ -2040,8 +2072,22 @@ sub SliverWorkAux($$$$$$$)
}
# Already in the aggregate?
next
if (grep {$_ eq $virtual_id} keys(%nodemap));
if (grep {$_ eq $virtual_id} keys(%nodemap)) {
#
# Need to find the old manifest entry and make sure it
# gets into the new manifest.
#
if (defined($oldmanifest)) {
my $oldnode = GeniXML::GetNodeByVirtualId($virtual_id,
$oldmanifest);
my $curnode = GeniXML::GetNodeByVirtualId($virtual_id,
$manifest);
if (defined($oldnode) && defined($curnode)) {
GeniXML::ReplaceNode($curnode, $oldnode);
}
}
next;
}
my $node = GeniUtil::LookupNode($resource_id);
if (!defined($node)) {
......@@ -2080,6 +2126,13 @@ sub SliverWorkAux($$$$$$$)
}
push(@plabnodes, $vnode);
}
# Store the updated rspec for later.
goto bad
if ($sliver->UpdateRspec($ref));
# And store into the new manifest.
my $oldnode = GeniXML::GetNodeByVirtualId($virtual_id, $manifest);
GeniXML::ReplaceNode($oldnode, $ref);
}
#
......@@ -2126,8 +2179,22 @@ sub SliverWorkAux($$$$$$$)
# Do not worry about modifying a link that is setup, unless a tunnel.
# Need to deal with this later.
if (grep {$_ eq $linkname} keys(%linkmap)) {
next
if ($is_tunnel);
if (!$is_tunnel) {
#
# Need to find the old manifest entry and make sure it
# gets into the new manifest.
#
if (defined($oldmanifest)) {
my $oldlink = GeniXML::GetLinkByVirtualId($linkname,
$oldmanifest);
my $curlink = GeniXML::GetLinkByVirtualId($linkname,
$manifest);
if (defined($oldlink) && defined($curlink)) {
GeniXML::ReplaceNode($curlink, $oldlink);
}
}
next;
}
#
# Gack, we have to recreate all the tunnel physical state, but
......@@ -2201,7 +2268,7 @@ sub SliverWorkAux($$$$$$$)
$message = "Could not set aggregate for $tunnel to $aggregate";
goto bad;
}
next;
goto manifest;
}
my $linkaggregate = GeniAggregate::Link->Create($slice, $owner,
......@@ -2340,6 +2407,11 @@ sub SliverWorkAux($$$$$$$)
goto bad;
}
}
manifest:
# And store into the new manifest.
my $oldlink = GeniXML::GetLinkByVirtualId($linkname, $manifest);
GeniXML::ReplaceNode($oldlink, $linkref);
}
skiplinks:
#
......@@ -2445,14 +2517,12 @@ sub SliverWorkAux($$$$$$$)
}
}
# The Manifest.
my $manifest = GeniXML::Serialize($rspec);
#
# Move this elsewhere.
#
my $manifest_string = GeniXML::Serialize($manifest);
DBQueryWarn("replace into geni_manifests set ".
" manifest=". DBQuoteSpecial($manifest) . ", " .
" manifest=". DBQuoteSpecial($manifest_string) . ", " .
" idx=NULL, slice_uuid='$slice_uuid', created=now()");
if (GeniUsage->NewManifest($aggregate, $rspec)) {
......@@ -2485,7 +2555,7 @@ sub SliverWorkAux($$$$$$$)
$slice->UnLock();
return GeniResponse->Create(GENIRESPONSE_SUCCESS,
[$sliver_credential->asString(),
$manifest]);
$manifest_string]);
}
#
# Free any slivers that were no longer wanted.
......@@ -2505,9 +2575,9 @@ sub SliverWorkAux($$$$$$$)
if ($v2) {
return GeniResponse->Create(GENIRESPONSE_SUCCESS,
[$sliver_credential->asString(),
$manifest]);
$manifest_string]);
} else {
return GeniResponse->Create(GENIRESPONSE_SUCCESS, $manifest);
return GeniResponse->Create(GENIRESPONSE_SUCCESS, $manifest_string);
}
bad:
......
......@@ -125,7 +125,7 @@ sub Resolve($)
if ($type eq "node") {
my $node = $object;
my $rspec = GeniCM::GetAdvertisement(0, $node->node_id(), "0.1");
my $rspec = GeniCM::GetAdvertisement(0, $node->node_id(), "0.1", undef);
if (! defined($rspec)) {
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Error getting advertisement");
......@@ -586,6 +586,8 @@ sub SliverAction($$$$$)
my ($action, $slice_urn, $sliver_urns, $credentials, $manifest) = @_;
my $response;
print STDERR "fooey\n";
if (! (defined($credentials) &&
(defined($slice_urn) || defined($sliver_urns)))) {
return GeniResponse->MalformedArgsResponse("Missing arguments");
......
This diff is collapsed.
......@@ -321,6 +321,26 @@ sub GetManifest($$)
return $xml;
}
#
# Store the rspec/manifest string.
#
sub UpdateRspec($$)
{
my ($self, $rspec) = @_;
my $idx = $self->idx();
my $rspec_string = GeniXML::Serialize($rspec);
my $safe_rspec = DBQuoteSpecial($rspec_string);
return -1
if (!DBQueryWarn("update geni_slivers set ".
" rspec_string=$safe_rspec ".
"where idx='$idx'"));
$self->{'RSPEC'} = $rspec;
return 0;
}
#
# Set the aggregate for a sliver.
#
......
......@@ -1645,14 +1645,45 @@ sub LightUpNodes($@)
my $experiment = $parent->experiment();
my $pid = $experiment->pid();
my $eid = $experiment->eid();
my @rebootlist = ();
#
# What nodes need reboot.
#
foreach my $node (@nodelist) {
push (@rebootlist, $node)
if ($node->allocstate() eq TBDB_ALLOCSTATE_RES_REBOOT());
}
TBDebugTimeStamp("Starting Geni setup.");
#
# This will start newly added slivers, but not existing.
#
if (libGeni::StartSlivers($experiment,
$parent->user(), 0, $parent->debug())) {
$parent->user(), $parent->debug())) {
print STDERR "*** Could not start Geni slivers\n";
return 1;
}
TBDebugTimeStamp("Geni slivers have been started.");
# Now reboot the rest.
if (@rebootlist) {
if (libGeni::RestartNodes($parent->user(), $parent->debug(), @rebootlist)) {
tbdie("Could not restart protogeni nodes\n");
}
#
# We always do a wait for geni nodes since for nodes in "basic"
# cooked mode, nothing will be reporting a state change from the
# node. We have to go poll it to make sure that the node is alive,
# and so we can report ISUP for it. This is a bit of a violation of
# the default reboot model, which is fire and forget when waitmode
# is not set, but no way around it.
#
if (libGeni::WaitForNodes($parent->user(),
$parent->debug(), undef, @rebootlist)) {
tbdie("Error in waiting for protogeni nodes\n");
}
}
return 0;
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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