Commit 003aef50 authored by Kirk Webb's avatar Kirk Webb

Android support: make image loading via tbadb asynchronous.

parent 98f679c5
...@@ -664,8 +664,9 @@ sub error_exit($$$) { ...@@ -664,8 +664,9 @@ sub error_exit($$$) {
# log the error locally. # log the error locally.
warn "$message\n"; warn "$message\n";
# Send failure result back. # Send failure result back to caller and exit.
return SendRPCData($RPCOUT, EncodeError($fid, $code, $message)); SendRPCData($RPCOUT, EncodeError($fid, $code, $message));
exit 1;
} }
# Helper that does LRU on our image cache # Helper that does LRU on our image cache
......
...@@ -29,15 +29,17 @@ use POSIX ":sys_wait_h"; ...@@ -29,15 +29,17 @@ use POSIX ":sys_wait_h";
use Getopt::Std; use Getopt::Std;
use Data::Dumper; use Data::Dumper;
use IO::Socket::INET; use IO::Socket::INET;
use File::Temp qw(tempfile);
use lib "@prefix@/lib"; use lib "@prefix@/lib";
use libdb;
use libtestbed;
use libjsonrpc; use libjsonrpc;
use tbadb_rpc; use tbadb_rpc;
use EmulabConstants;
use User; use User;
use Node; use Node;
use Image; use Image;
use EmulabConstants;
# Func prototypes # Func prototypes
sub cmd_setup($@); sub cmd_setup($@);
...@@ -173,9 +175,10 @@ sub cmd_setup($@) { ...@@ -173,9 +175,10 @@ sub cmd_setup($@) {
# if necessary. The remote end keeps an LRU cache of images. # if necessary. The remote end keeps an LRU cache of images.
# #
sub cmd_loadimage($@) { sub cmd_loadimage($@) {
my ($node_id, $imagepid, $imagename) = @_; my ($node_id, $imagepid, $imagename, @extra) = @_;
my $nowait = 0;
# Check and untaint arguments. # Process and untaint arguments.
die "tbadb::cmd_loadimage: missing one or more arguments (need: <project> <image_name>)!\n" die "tbadb::cmd_loadimage: missing one or more arguments (need: <project> <image_name>)!\n"
if (!$node_id || !$imagepid || !$imagename); if (!$node_id || !$imagepid || !$imagename);
die "tbadb::cmd_loadimage: malformed project id!" die "tbadb::cmd_loadimage: malformed project id!"
...@@ -184,6 +187,16 @@ sub cmd_loadimage($@) { ...@@ -184,6 +187,16 @@ sub cmd_loadimage($@) {
die "tbadb::cmd_loadimage: malformed image id/name!" die "tbadb::cmd_loadimage: malformed image id/name!"
if ($imagename !~ /^([-\w]{$MINHLEN,$MAXHLEN})$/); if ($imagename !~ /^([-\w]{$MINHLEN,$MAXHLEN})$/);
$imagename = $1; $imagename = $1;
foreach my $arg (@extra) {
ARGS: for ($arg) {
/^nowait$/i && do {
$nowait = 1;
last ARGS;
};
# Default
die "tbadb::cmd_loadimage: unknown argument: $arg!\n";
}
}
# Lookup image and extract some info. # Lookup image and extract some info.
my $image = Image->Lookup($imagepid, $imagename); my $image = Image->Lookup($imagepid, $imagename);
...@@ -210,7 +223,17 @@ sub cmd_loadimage($@) { ...@@ -210,7 +223,17 @@ sub cmd_loadimage($@) {
die("tbadb::cmd_loadimage: You do not have permission to load an image onto $node\n") die("tbadb::cmd_loadimage: You do not have permission to load an image onto $node\n")
if (!$isroot && !$this_user->IsAdmin() && if (!$isroot && !$this_user->IsAdmin() &&
!$node->AccessCheck($this_user, TB_NODEACCESS_LOADIMAGE)); !$node->AccessCheck($this_user, TB_NODEACCESS_LOADIMAGE));
# If told not to wait, fork into the background.
my $logname;
if ($nowait) {
(undef, $logname) = tempfile("tbadb-XXXXXX", TMPDIR => 1);
die "tbadb::cmd_loadimage: Could not create temp logging file: $!\n"
if !$logname;
return 0
if (TBBackGround($logname));
}
# Grab the RPC pipe. # Grab the RPC pipe.
my ($rpcin, $rpcout) = GetRPCPipeHandles($node); my ($rpcin, $rpcout) = GetRPCPipeHandles($node);
die "tbadb::cmd_reboot: Failed to get valid SSH pipe filehandles!\n" die "tbadb::cmd_reboot: Failed to get valid SSH pipe filehandles!\n"
...@@ -316,8 +339,22 @@ sub cmd_loadimage($@) { ...@@ -316,8 +339,22 @@ sub cmd_loadimage($@) {
exit 1; exit 1;
} }
#
# Tell stated that we've finished reloading the node if the node
# is in the RELOADUE opmode.
#
my $opmode;
if (TBGetNodeOpMode($node_id,\$opmode) &&
$opmode eq TBDB_NODEOPMODE_RELOADUE) {
TBSetNodeEventState($node_id,TBDB_NODESTATE_RELOADDONE);
TBSetNodeEventState($node_id,TBDB_NODESTATE_SHUTDOWN);
}
# Done! # Done!
print "tbadb::cmd_loadimage: Successfully loaded $imagename onto $node_id\n"; print "tbadb::cmd_loadimage: Successfully loaded $imagename onto $node_id\n";
if ($nowait && $logname) {
unlink($logname);
}
return 0; return 0;
} }
......
...@@ -1275,7 +1275,7 @@ sub SetupReloadUE($) ...@@ -1275,7 +1275,7 @@ sub SetupReloadUE($)
{ {
my $reload_info = $_[0]; my $reload_info = $_[0];
my $nodeobject = $reload_info->{'nodeobj'}; my $nodeobject = $reload_info->{'nodeobj'};
my $node_id = $reload_info->{'node'}; my $node = $reload_info->{'node'};
my $image = (@{$reload_info->{'images'}})[0]; my $image = (@{$reload_info->{'images'}})[0];
my $osid = $reload_info->{'osid'}; my $osid = $reload_info->{'osid'};
...@@ -1285,58 +1285,38 @@ sub SetupReloadUE($) ...@@ -1285,58 +1285,38 @@ sub SetupReloadUE($)
my $imgpid = $image->pid(); my $imgpid = $image->pid();
my $imgname = $image->imagename(); my $imgname = $image->imagename();
#
# Grab the target adb host if specified by the user. Adjust the
# tbadb command as appropriate.
#
my $thost;
my $experiment = $nodeobject->Reservation();
if ($experiment) {
$experiment->GetVirtNodeAttribute($nodeobject->vname(),
"adb_target", \$thost);
}
my $adbcmd =
$thost ? "setup $imgpid $imgname $thost" :
"loadimage $imgpid $imgname";
# #
# Tell stated that we're about to start reloading # Tell stated that we're about to start reloading
# #
TBSetNodeNextOpMode($node_id,TBDB_NODEOPMODE_RELOADUE); TBSetNodeNextOpMode($node,TBDB_NODEOPMODE_RELOADUE);
# #
# The mote goes 'down', then starts to reload # The mote goes 'down', then starts to reload
# #
TBSetNodeEventState($node_id,TBDB_NODESTATE_SHUTDOWN); TBSetNodeEventState($node,TBDB_NODESTATE_SHUTDOWN);
TBSetNodeEventState($node_id,TBDB_NODESTATE_RELOADING); TBSetNodeEventState($node,TBDB_NODESTATE_RELOADING);
# #
# Invoke local script that calls the remote end that # Invoke local script that calls the remote end that
# actually does the work. # actually does the work.
# #
my $rv = system("$TBADB -n $node_id $adbcmd"); my $rv = system("$TBADB -n $node loadimage $imgpid $imgname nowait");
if ($rv) { if ($rv) {
tberror "$node_id: tbadb failed!"; tberror "$node: tbadb failed!";
return -1; return -1;
} }
# #
# Tell stated that we've finished reloading the node # Set the boot OSID. Not that the UEs will check in via bootinfo,
# but perhaps something else will care that this is correct/consistent.
# #
TBSetNodeEventState($node_id,TBDB_NODESTATE_RELOADDONE); my $osinfo = OSinfo->Lookup($osid);
if (!defined($osinfo) ||
system("$osselect $osid $node_id"); $nodeobject->OSSelect($osinfo, "next_boot_osid", 0)) {
if ($?) {
tberror "os_select $osid failed!"; tberror "os_select $osid failed!";
return -1; return -1;
} }
#
# 'Reboot' the node (from stated's perspective, anyway)
# has been shutdown, so that the os_select will take effect
#
TBSetNodeEventState($node_id,TBDB_NODESTATE_SHUTDOWN);
return 0; return 0;
} }
......
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