Commit 9a9240e2 authored by Leigh Stoller's avatar Leigh Stoller

Fixes for individual sliver restart/stop/start. Add reload action.

parent ab001a86
......@@ -1084,6 +1084,8 @@ sub PerformOperationalAction
return GeniCMV2::RestartSliver($args);
} elsif ($action eq 'geni_stop') {
return GeniCMV2::StopSliver($args);
} elsif ($action eq 'geni_reload') {
return GeniCMV2::ReloadSliver($args);
} elsif ($action eq 'geni_update_users') {
if (!exists($options->{"geni_users"})) {
return GeniResponse->MalformedArgsResponse("No keys provided!");
......
......@@ -858,28 +858,49 @@ sub ProcessManifest($$)
return 0;
}
sub Start($$)
{
my ($self, $version) = @_;
return $self->Action($version, "start");
}
sub Restart($$)
{
my ($self, $version) = @_;
return $self->Action($version, "restart");
}
sub Reload($$)
{
my ($self, $version) = @_;
return $self->Action($version, "reload");
}
#
# Start all the slivers in the aggregate. Start is special since it
# sorta means reboot, and the only thing we reboot are nodes. And,
# since we might have multiple vnodes on a pnode, we want to be efficient
# about it.
# Start/Restart/reload all the slivers in the aggregate. Start is
# special since it sorta means reboot, and the only thing we reboot
# are nodes. And, since we might have multiple vnodes on a pnode, we
# want to be efficient about it.
#
# XXX Is is assumed that there is a single toplevel aggregate for the
# slice, so we can get all the nodes.
#
sub Start($$$)
sub Action($$$)
{
my ($self, $version, $restart) = @_;
my ($self, $version, $action) = @_;
$self->ClearBootFailure();
my $msg = "Internal Error: ";
my $restart = ($action eq "restart" ? 1 : 0);
my $reload = ($action eq "reload" ? 1 : 0);
require Lan;
require OSinfo;
require Image;
return -1
if (! ref($self));
$restart = 0
if (!defined($restart));
# Clear last error.
$self->SetErrorLog("");
......@@ -928,7 +949,7 @@ sub Start($$$)
}
# The nodes will not boot locally unless there is a DNS record,
# but we also need it before we can issue the reloads.
if (system("$NAMEDSETUP")) {
if (!$reload && system("$NAMEDSETUP")) {
$msg .= "$NAMEDSETUP failed\n";
goto bad;
}
......@@ -979,9 +1000,10 @@ sub Start($$$)
#
# Since this is an aggregate, some slivers may already be
# in the started state. Skip those, unless doing a restart.
# But reload is allowed in either started or stopped state.
#
next
if ($sliver->state() eq "started" && !$restart);
if (! $reload && ($sliver->state() eq "started" && !$restart));
if ($node->isvirtnode()) {
# A virtnode on a shared physical node needs reboot or setup
......@@ -1016,7 +1038,7 @@ sub Start($$$)
$msg .= "Error determining if $osinfo is loaded on $vnode";
goto bad;
}
if (! $isloaded) {
if (!$isloaded || $reload) {
my $image = $osinfo->MapToImage("pcvm");
if (defined($image)) {
print STDERR "Setting $vnode to load $image\n";
......@@ -1041,6 +1063,9 @@ sub Start($$$)
$vnodekills{$vnode->node_id()} = $vnode;
$vnodes{$node->node_id()} = $vnode;
}
elsif ($reload) {
$vnodes{$node->node_id()} = $vnode;
}
}
}
......@@ -1074,6 +1099,10 @@ sub Start($$$)
if (exists($poweron{$physnodeid}) ||
exists($reboots{$physnodeid}) ||
exists($reloads{$physnodeid}));
#
# We continue below, but now looking at the physical node
# that the vnode is running one.
#
}
#
# If the node is not imageable, then there is not much to
......@@ -1118,7 +1147,7 @@ sub Start($$$)
$msg .= "Error determining if $osinfo is loaded on $node";
goto bad;
}
if (! $isloaded) {
if (!$isloaded || $reload) {
print STDERR " Setting up a reload for $node\n";
my $image = $osinfo->MapToImage($node->type());
......@@ -1237,7 +1266,7 @@ sub Start($$$)
}
}
if ($version >= 2) {
if ($version >= 2 && !$reload) {
#
# Dump the manifest into the experiment directory.
#
......@@ -1443,16 +1472,18 @@ sub Start($$$)
#
# Start the event scheduler.
#
my $action = ($restart ? "replay" : "start");
system("$EVENTSYS $action $pid,$eid");
if ($?) {
$msg .= "Failed to (re)start the event system";
if ($TB ne "/usr/testbed") {
# Not sure why this is failing.
print STDERR "$msg\n";
}
else {
goto bad;
if (!$reload) {
my $action = ($restart ? "replay" : "start");
system("$EVENTSYS $action $pid,$eid");
if ($?) {
$msg .= "Failed to (re)start the event system";
if ($TB ne "/usr/testbed") {
# Not sure why this is failing.
print STDERR "$msg\n";
}
else {
goto bad;
}
}
}
......
......@@ -4266,7 +4266,7 @@ sub StartSliver($)
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"FlipToUser Error");
}
if (!$impotent && $sliver->Start($API_VERSION, 0) != 0) {
if (!$impotent && $sliver->Start($API_VERSION) != 0) {
$slice->UnLock();
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Could not start sliver/aggregate");
......
#!/usr/bin/perl -wT
#
# Copyright (c) 2008-2013 University of Utah and the Flux Group.
# Copyright (c) 2008-2014 University of Utah and the Flux Group.
#
# {{{GENIPUBLIC-LICENSE
#
......@@ -536,7 +536,7 @@ sub CreateSliver($)
#
$mypid = $PID;
if ($aggregate->Start($API_VERSION, 0) != 0) {
if ($aggregate->Start($API_VERSION) != 0) {
if ($PID == $mypid) {
$slice->UnLock();
print STDERR "Could not start sliver.\n";
......@@ -804,6 +804,17 @@ sub RestartSliver($)
$slice_urn, $sliver_urns, $credentials, $manifest);
}
sub ReloadSliver($)
{
my ($argref) = @_;
my $slice_urn = $argref->{'slice_urn'};
my $sliver_urns = $argref->{'sliver_urns'} || $argref->{'component_urns'};
my $credentials = $argref->{'credentials'};
return SliverAction("reload",
$slice_urn, $sliver_urns, $credentials, undef);
}
sub SliverAction($$$$$)
{
my ($action, $slice_urn, $sliver_urns, $credentials, $manifest) = @_;
......@@ -839,6 +850,10 @@ sub SliverAction($$$$$)
return $slice
if (defined($slice) && GeniResponse::IsResponse($slice));
#
# I think this allows the CM to perform an action without
# the slice credential?
#
if ( (!defined($slice)) &&
($credential->target_urn() =~ /\+authority\+cm$/)) {
# administrative credentials are presented.
......@@ -918,6 +933,12 @@ sub SliverAction($$$$$)
"Sliver is not started (yet)");
}
}
elsif ($action eq "reload") {
if ($object->state() ne "started" && $object->state() ne "stopped"){
return GeniResponse->Create(GENIRESPONSE_REFUSED, undef,
"Sliver is not started or stopped (yet)");
}
}
return 0;
};
my $PerformAction = sub {
......@@ -926,13 +947,16 @@ sub SliverAction($$$$$)
my $exitval = 0;
if ($action eq "start") {
$exitval = $object->Start($API_VERSION, 0);
$exitval = $object->Start($API_VERSION);
}
elsif ($action eq "stop") {
$exitval = $object->Stop($API_VERSION);
}
elsif ($action eq "restart") {
$exitval = $object->Start($API_VERSION, 1);
$exitval = $object->Restart($API_VERSION);
}
elsif ($action eq "reload") {
$exitval = $object->Reload($API_VERSION);
}
return GeniResponse->Create(GENIRESPONSE_ERROR,
"Could not $action sliver")
......@@ -957,7 +981,7 @@ sub SliverAction($$$$$)
goto bad
if (GeniResponse::IsResponse($response));
if ($action eq "start" || $action eq "restart") {
if ($action eq "start" || $action eq "restart" || $action eq "reload"){
if (defined($manifest) &&
$aggregate->ProcessManifest($manifest)) {
$response = GeniResponse->Create(GENIRESPONSE_ERROR,
......
#!/usr/bin/perl -wT
#
# Copyright (c) 2008-2011, 2013 University of Utah and the Flux Group.
# Copyright (c) 2008-2014 University of Utah and the Flux Group.
#
# {{{GENIPUBLIC-LICENSE
#
......@@ -72,6 +72,7 @@ my $PLABNODE = "$TB/sbin/plabnodewrapper";
my $VNODESETUP = "$TB/sbin/vnode_setup";
my $GENTOPOFILE = "$TB/libexec/gentopofile";
my $POWER = "$TB/bin/power";
my $OSLOAD = "$TB/bin/os_load";
# Cache of instances to avoid regenerating them.
my %slivers = ();
......@@ -1124,12 +1125,35 @@ sub ProcessManifest($$)
return 0;
}
sub Start($$)
{
my ($self, $version) = @_;
return $self->Action($version, "start");
}
sub Restart($$)
{
my ($self, $version) = @_;
return $self->Action($version, "restart");
}
sub Reload($$)
{
my ($self, $version) = @_;
return $self->Action($version, "reload");
}
#
# Start (or restart) a node. Basically, a reboot.
# Start, Restart, and Reload.
#
sub Start($$$)
sub Action($$$)
{
my ($self, $version, $restart) = @_;
my ($self, $version, $action) = @_;
my $restart = ($action eq "restart" ? 1 : 0);
my $reload = ($action eq "reload" ? 1 : 0);
return -1
if (! ref($self));
......@@ -1158,24 +1182,31 @@ sub Start($$$)
if ($reservation->SameExperiment($experiment)) {
my $node_id = $node->node_id();
if ($reload) {
system("$OSLOAD -c -s $node_id");
return -1
if ($?);
}
#
# Reboot and wait?
#
if ($node->isvirtnode() && $node->sharing_mode()) {
if ($node->eventstate() eq TBDB_NODESTATE_SHUTDOWN()) {
if ($node->isvirtnode()) {
if ($self->state() eq "stopped") {
system("$VNODESETUP -j -m $pid $eid $node_id");
}
elsif ($restart) {
system("$NODEREBOOT $node_id");
}
}
else {
#
# Look to see if local physical node was stopped (powered off).
#
if (!$node->isvirtnode() &&
!$node->isremotenode() &&
$self->state() eq "stopped") {
if ($self->state() eq "stopped") {
system("$POWER on $node_id");
}
else {
elsif ($restart) {
system("$NODEREBOOT $node_id");
}
}
......@@ -1223,12 +1254,10 @@ sub Stop($$)
my $node_id = $node->node_id();
#
# Reboot and wait?
# Virtnodes are "halted" which shuts down the VM but leaves the disks.
#
if ($node->isvirtnode() && $node->sharing_mode()) {
if ($node->eventstate() eq TBDB_NODESTATE_SHUTDOWN()) {
system("$VNODESETUP -j -k -m $pid $eid $node_id");
}
if ($node->isvirtnode()) {
system("$VNODESETUP -j -h -m $pid $eid $node_id");
}
else {
system("$POWER off $node_id");
......
......@@ -36,7 +36,7 @@ use Getopt::Std;
#
sub usage()
{
print "Usage: sliveraction [-f] start|stop|restart <urn>\n";
print "Usage: sliveraction [-f] start|stop|restart|reload <urn>\n";
exit(1);
}
sub fatal($);
......@@ -125,7 +125,7 @@ if (!defined($aggregate)) {
}
GeniUtil::FlipToGeniUser();
if ($action eq "start") {
$aggregate->Start(2, 0) == 0
$aggregate->Start(2) == 0
or fatal("Could not start $aggregate");
}
elsif ($action eq "stop") {
......@@ -133,7 +133,11 @@ elsif ($action eq "stop") {
or fatal("Could not stop $aggregate");
}
elsif ($action eq "restart") {
$aggregate->Start(2, 1) == 0
$aggregate->Restart(2) == 0
or fatal("Could not restart $aggregate");
}
elsif ($action eq "reload") {
$aggregate->Reload(2) == 0
or fatal("Could not restart $aggregate");
}
#
......
#!/usr/bin/perl -w
#
# Copyright (c) 2008-2013 University of Utah and the Flux Group.
# Copyright (c) 2008-2014 University of Utah and the Flux Group.
#
# {{{GENIPUBLIC-LICENSE
#
......@@ -94,6 +94,7 @@ elsif ($GENI_VERSION eq "2.0") {
"StartSliver" => \&GeniCMV2::StartSliver,
"StopSliver" => \&GeniCMV2::StopSliver,
"RestartSliver" => \&GeniCMV2::RestartSliver,
"ReloadSliver" => \&GeniCMV2::ReloadSliver,
"BindToSlice" => \&GeniCMV2::BindToSlice,
"ListUsage" => \&GeniCMV2::ListUsage,
"ListHistory" => \&GeniCMV2::ListHistory,
......
#!/usr/bin/perl -wT
#
# Copyright (c) 2000-2012 University of Utah and the Flux Group.
# Copyright (c) 2000-2014 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -38,7 +38,7 @@ sub usage()
print STDOUT "Usage: vnode_setup [-m] [-q] [-f] [-k] [-j] [-p] [-n <numbatch>] [-w <wait_time>] <pid> <eid> [node ...]\n";
exit(-1);
}
my $optlist = "fdkjpn:w:mq";
my $optlist = "fdkjpn:w:mqh";
#
# We don't want to run this script unless its the real version.
......@@ -65,6 +65,7 @@ my $debug = 0;
my $force = 0;
my $failed = 0;
my $killmode = 0;
my $haltmode = 0;
my $jailonly = 0;
my $sendemail = 0;
my $quiet = 0;
......@@ -117,6 +118,9 @@ if (defined($options{"d"})) {
if (defined($options{"k"})) {
$killmode = 1;
}
if (defined($options{"h"})) {
$haltmode = 1;
}
if (defined($options{"j"})) {
$jailonly = 1;
}
......@@ -221,7 +225,7 @@ my $exptstate = $experiment->state();
# Just the vnodes mam.
foreach my $node (@nodes) {
my $mode = ($killmode ? "teardown" : "setup");
my $mode = ($killmode ? "teardown" : ($haltmode ? "halt" : "setup"));
my $nodeobj = Node->Lookup($node);
if (!defined($nodeobj)) {
......@@ -239,7 +243,7 @@ foreach my $node (@nodes) {
# Special hack for SPP nodes. Need to generalize this.
if ($shared && $nodeobj->type eq "sppvm") {
if ($mode eq "teardown") {
if ($mode eq "teardown" || $mode eq "halt") {
$nodeobj->SetEventState(TBDB_NODESTATE_SHUTDOWN());
}
else {
......@@ -404,7 +408,7 @@ foreach my $node (@nodes) {
#
# XXX: Don't we always want to set this?
#
if ($mode eq "teardown" || $mode eq "reboot") {
if ($mode eq "teardown" || $mode eq "reboot" || $mode eq "halt") {
$nodeobj->SetEventState(TBDB_NODESTATE_SHUTDOWN);
}
......@@ -504,20 +508,22 @@ while (1) {
$nodeobj->SetAllocState(TBDB_ALLOCSTATE_RES_INIT_DIRTY);
}
if ($geni && ($mode eq "teardown" || $mode eq "cleanup")) {
if ($geni &&
($mode eq "teardown" || $mode eq "cleanup" || $mode eq "halt")){
$nodeobj->SetEventState(TBDB_NODESTATE_SHUTDOWN);
$UID = $SAVEUID;
$EUID = $UID;
# $exval = GeniEmulab->DestroySlivers($experiment, [ $nodeobj ]);
}
elsif (!($plab && ($mode eq "cleanup" || $mode eq "teardown"))
&& !($mode eq "setup" && $remote && !$plab)) {
&& !($mode eq "setup" && $remote && !$plab)) {
# Cleanup is used only on plab nodes.
# Don't try to teardown plab vnodes; it's just asking for
# trouble as the shutdown may hang or take too long. It's
# best to simply try and free the vserver below.
my $args = (($mode eq "teardown") ? "-k " :
($mode eq "reboot" ? "-r " : " "));
(($mode eq "reboot") ? "-r " :
(($mode eq "halt") ? "-h " : " ")));
$args .= ($jailed ? "-jVt " : ($plab ? "-p " : "-i "));
$args .= "$vnode ";
......@@ -526,8 +532,12 @@ while (1) {
if ($plab) {
$pnodeOrVnode = $vnode;
}
$exval = TBForkCmd("$ssh -host $pnodeOrVnode ".
"$CLIENT_BIN/vnodesetup $args",1);
my $cmd = "$ssh -host $pnodeOrVnode ".
" $CLIENT_BIN/vnodesetup $args";
if ($debug) {
print "Running: '$cmd'\n";
}
$exval = TBForkCmd($cmd, 1);
}
# Free the plab node lease if necessary.
......@@ -682,6 +692,10 @@ if ($killmode) {
print STDOUT "Vnode teardown finished.\n"
if (!$quiet);
}
elsif ($haltmode) {
print STDOUT "Vnode halt finished.\n"
if (!$quiet);
}
else {
print STDOUT "Vnode setup initiated on all nodes ...\n"
if (!$quiet);
......
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