Commit 6adf504b authored by Leigh Stoller's avatar Leigh Stoller

Add -e pid,eid option to sched_reload to make it easier to schedule

reloads for nodes in an experiment.
Change os_load to schedule a default image reload whenever a mereuser
loads an image that is not the default image for that node type.
Add some support stuff in libdb (TBSetSchedReload) and some constant
definitions for sched_reload and for nodelog.
parent 9c25160c
......@@ -55,7 +55,9 @@ use Exporter;
BATCHSTATE_ACTIVATING
TBBatchState TBSetBatchState
TB_NODELOGTYPES
TB_NODELOGTYPE_MISC TB_NODELOGTYPES TB_DEFAULT_NODELOGTYPE
TB_DEFAULT_RELOADTYPE TB_RELOADTYPE_FRISBEE TB_RELOADTYPE_NETDISK
TBAdmin TBProjAccessCheck TBNodeAccessCheck TBOSIDAccessCheck
TBImageIDAccessCheck TBExptAccessCheck ExpLeader MarkNodeDown
......@@ -64,6 +66,7 @@ use Exporter;
DBQuoteSpecial UNIX2DBUID ExpState SetExpState ProjLeader
ExpNodes DBDateTime DefaultImageID GroupLeader TBGroupUnixInfo
TBValidNodeLogType TBValidNodeName TBSetNodeLogEntry
TBSetSchedReload
);
# Must come after package declaration!
......@@ -188,7 +191,14 @@ sub TB_IMAGEID_MIN() { TB_IMAGEID_READINFO; }
sub TB_IMAGEID_MAX() { TB_IMAGEID_ACCESS; }
# Node Log Types
sub TB_NODELOGTYPES() { ("misc") ; }
sub TB_NODELOGTYPE_MISC { "misc"; }
sub TB_NODELOGTYPES() { ( TB_NODELOGTYPE_MISC ) ; }
sub TB_DEFAULT_NODELOGTYPE() { TB_NODELOGTYPE_MISC; }
# Reload Types.
sub TB_RELOADTYPE_NETDISK() { "netdisk"; }
sub TB_RELOADTYPE_FRISBEE() { "frisbee"; }
sub TB_DEFAULT_RELOADTYPE() { TB_RELOADTYPE_NETDISK; }
#
# We should list all of the DB limits.
......@@ -1074,6 +1084,30 @@ sub TBValidNodeName($)
return 1;
}
#
# Set the scheduled_reloads for a node. Type is optional and defaults to
# testbed default load type. See above.
#
# usage: TBSetSchedReload(char *node, char *imageid, [char *reload_type])
# Returns 1 if okay.
# Returns 0 if failed.
#
sub TBSetSchedReload($$;$)
{
my ($node, $imageid, $type) = @_;
if (!defined($type)) {
$type = TB_DEFAULT_RELOADTYPE;
}
if (DBQueryWarn("replace into scheduled_reloads ".
"(node_id, image_id, reload_type) values ".
"('$node', '$imageid', '$type')")) {
return 1;
}
return 0;
}
#
# Issue a DB query. Argument is a string. Returns the actual query object, so
# it is up to the caller to test it. I would not for one moment view this
......
......@@ -52,6 +52,7 @@ my $NETDISKOSID = "NETDISK-STD";
my $FRISBEEPATH = "$BOSSADDR:/tftpboot/pxeboot.frisbee";
my $FRISBEELAUNCHER = "$TB/sbin/frisbeelauncher";
my $nodereboot = "$TB/bin/node_reboot";
my $schedreload = "$TB/bin/sched_reload";
my $ping = "/sbin/ping";
my $dbg = 0;
my @row;
......@@ -134,7 +135,7 @@ if ($UID && !TBAdmin($UID)) {
$mereuser = 1;
if (! TBNodeAccessCheck($UID, TB_NODEACCESS_LOADIMAGE, @nodes)) {
die("You do not have permission to load images on one (or more) ".
die("*** You do not have permission to load images on one (or more) ".
"of the nodes!\n");
}
}
......@@ -157,18 +158,23 @@ foreach my $node (@nodes) {
#
#
# Get default imageid for this node if none specified on comand line.
# Get default imageid for this node.
#
my $default_imageid;
if (! ($default_imageid = DefaultImageID($node))) {
die("*** $0:\n".
" No default imageid is defined for $node!\n");
}
if ($usedefault) {
if (! ($imageid = DefaultImageID($node))) {
die("*** No default imageid is defined for $node!\n");
}
$imageid = $default_imageid;
}
my $db_result =
DBQueryFatal("select * from images where imageid='$imageid'");
if ($db_result->numrows < 1) {
die("*** No such imageid $imageid is defined in the DB!\n");
die("*** $0:\n".
" No such imageid $imageid is defined in the DB!\n");
}
%imageid_row = $db_result->fetchhash();
......@@ -195,7 +201,8 @@ foreach my $node (@nodes) {
my $cmdline = "";
if (defined($imageid_row{'pid'})) {
if (! ($imagepath =~ /^\/proj\//)) {
die("*** Your image must reside in /proj\n");
die("*** $0:\n".
" Your image must reside in /proj\n");
}
$cmdline = "${USERADDR}:$imagepath $diskpart";
}
......@@ -215,6 +222,19 @@ foreach my $node (@nodes) {
DBQueryFatal("replace into current_reloads ".
"(node_id, image_id) values ('$node', '$imageid')");
#
# If a mereuser is loading an image (which is not the default) then
# schedule a reload for it so that when the experiment is terminated
# it will get a fresh default image before getting reallocated to
# another experiment.
#
if ($mereuser && $imageid ne $default_imageid) {
if (! TBSetSchedReload($node, $default_imageid)) {
print "*** $0:\n".
" WARNING: Could not schedule default reload for $node!";
}
}
#
# Assign partition table entries for each partition in the image.
# This is complicated by the fact that an image that covers only
......
......@@ -14,13 +14,15 @@ sub usage()
{
print STDOUT "Usage: sched_reload [-f | -p] [-r] [-i <imageid>] ".
"<node> [node ...]\n".
" sched_reload <options> -e pid,eid\n".
"Use -i to specify an imageid. Use node default otherwise.\n".
"Use -f to force reload. Fail if node cannot be reserved.\n".
"Use -p to pend reload for the reload daemon.\n".
"Use -e to schedule a reload for all nodes in an experiment.\n".
"Use -r to use Frisbee rather than netdisk (experimental).\n";
exit(-1);
}
my $optlist = "fpri:";
my $optlist = "fpri:e:";
#
# Configure variables
......@@ -53,6 +55,9 @@ my $usedefault = 1;
my $imageid;
my %imagenodes = ();
my @row;
my $eidmode = 0;
my $pid;
my $eid;
# un-taint path
$ENV{'PATH'} = '/bin:/usr/bin:/usr/local/bin';
......@@ -68,9 +73,6 @@ $| = 1; #Turn off line buffering on output
if (! getopts($optlist, \%options)) {
usage();
}
if (@ARGV < 1) {
usage();
}
if (defined($options{"f"})) {
$force = $options{"f"};
}
......@@ -95,28 +97,56 @@ if (defined($options{"i"})) {
die("Bad data in $imageid.");
}
}
if (defined($options{"e"})) {
if (@ARGV) {
usage();
}
$eidmode = $options{"e"};
if ($eidmode =~ /([-\w]*),([-\w]*)/) {
$pid = $1;
$eid = $2;
}
else {
print STDOUT "Invalid argument to -e option: $eidmode\n";
usage();
}
}
else {
if (@ARGV < 1) {
usage();
}
}
# This type will be put into the database, to allow programs
# such as nfree to figure out what kind of reload is supposed
# to occur
if ($frisbee) {
$type = "frisbee";
$type = TB_RELOADTYPE_FRISBEE;
} else {
$type = "netdisk";
$type = TB_RELOADTYPE_NETDISK;
}
#
# Untaint nodes.
#
foreach my $node ( @ARGV ) {
if ($node =~ /^([-\@\w]+)$/) {
$node = $1;
}
else {
die("Bad node name: $node.");
if ($eidmode) {
if (! (@nodes = ExpNodes($pid, $eid))) {
die("*** $0:\n".
" There are no nodes allocated to experiment $pid/$eid!");
}
}
else {
#
# Untaint nodes.
#
foreach my $node ( @ARGV ) {
if ($node =~ /^([-\@\w]+)$/) {
$node = $1;
}
else {
die("Bad node name: $node.");
}
push(@nodes, $node);
push(@nodes, $node);
}
}
#
......@@ -124,7 +154,8 @@ foreach my $node ( @ARGV ) {
# Mere users cannot schedule reloads.
#
if ($UID && !TBAdmin($UID)) {
die("*** Only root or TB administrators can schedule disk reloads.\n");
die("*** $0:\n".
" Only root or TB administrators can schedule disk reloads.\n");
}
#
......@@ -136,7 +167,8 @@ if (defined($imageid)) {
DBQueryFatal("select * from images where imageid='$imageid'");
if ($query_result->numrows < 1) {
die("*** No such imageid $imageid is registered in the DB!");
die("*** $0:\n".
" No such imageid $imageid is registered in the DB!");
}
}
......@@ -159,7 +191,8 @@ foreach my $node (@nodes) {
#
if ($usedefault) {
if (! ($imageid = DefaultImageID($node))) {
die("*** No default imageid is defined for $node!\n");
die("*** $0:\n".
" No default imageid is defined for $node!\n");
}
}
......@@ -200,11 +233,11 @@ foreach my $node (@nodes) {
}
# Put it in the reloads table so TMCD knows to free it.
print STDERR "Scheduling reload of $imageid for $pc:\n";
DBQueryFatal("replace into scheduled_reloads ".
"(node_id, image_id, reload_type) values ".
"('$pc', '$imageid','$type')");
if (! TBSetSchedReload($pc, $imageid, $type)) {
die("*** $0:\n".
" Could not set scheduled reload for $pc!");
}
#
# The point of this hash table is so that we can gather up all the
# nodes per imageid and issue single requests to os_load, so that it
......
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