sched_reload.in 4.17 KB
Newer Older
1 2
#!/usr/bin/perl -wT
use English;
3
use Getopt::Std;
4 5 6 7 8 9 10
   
#
# Schedule the reloading of a disk partition on a node. If the node is
# currently not reserved, start the loading now after reserving it to 
# testbed:reloading. Otherwise, put the right info into the database, and 
# nfree will do it when the node gets freed.
# 
11
# usage: sched_reload [-f] <imageid> <node> [node ...]
12 13 14
#
sub usage()
{
15
    print STDOUT "Usage: sched_reload [-f] <imageid> <node> [node ...]\n".
16 17 18 19
	"Use the -f to force reload. Fail if node cannot be reserved.\n";
    exit(-1);
}
my  $optlist = "f";
20 21 22 23

#
# Configure variables
#
24
my $TB     = "@prefix@/bin";
25 26
my $DBNAME = "@TBDBNAME@";

27 28 29
my $osload      = "$TB/os_load";
my $name        = "";
my $mereuser    = 0;
30 31 32
my $error       = 0;
my $debug       = 0;
my $force	= 0;
33
my @nodes       = ();
34
my @row;
35 36 37 38 39 40 41 42

# un-taint path
$ENV{'PATH'} = '/bin:/usr/bin:/usr/local/bin';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};

$| = 1; #Turn off line buffering on output

#
43 44 45 46 47 48 49
# Parse command arguments. Once we return from getopts, all that should be
# left are the required arguments.
#
%options = ();
if (! getopts($optlist, \%options)) {
    usage();
}
50
if (@ARGV < 2) {
51
    usage();
52
}
53 54 55
if (defined($options{"f"})) {
    $force = $options{"f"};
}
56
my $imageid   = shift;
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77

#
# Untaint args.
#
if ($imageid =~ /^([-\@\w.\+]+)$/) {
    $imageid = $1;
}
else {
    die("Bad data in $imageid.");
}

foreach my $node ( @ARGV ) {
    if ($node =~ /^([-\@\w]+)$/) {
	$node = $1;
    }
    else {
	die("Bad node name: $node.");
    }
    
    push(@nodes, $node);
}
78

79 80 81 82 83 84
#
# Set up for querying the database.
# 
use Mysql;
my $DB = Mysql->connect("localhost", $DBNAME, "script", "none");

85 86 87 88 89 90 91
#
# Figure out who called us. Root and admin types can do whatever they
# want. Normal users can only change nodes in experiments in their
# own projects.
#
if ($UID != 0) {
    ($name) = getpwuid($UID)
92
	or die "$UID not in passwd file\n";
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108

    $db_result = $DB->query("select admin from users where uid='$name'");
    @row = $db_result->fetchrow_array();
    if ($row[0] != 1) {
	$mereuser = 1;
    }
}

#
# Mere Users cannot schedule reloads.
#
if ($mereuser) {
    die("Only root or TB administrators can schedule disk reloads.\n");
}

#
109
# A loop.
110 111 112 113 114
# 
my @load_list=();
foreach my $node (@nodes) {
    my $pc = $node;

115 116
    $sth = $DB->query("select * from nodes where node_id='$pc'");
    if ($sth == 0) {
117
	die("Database lookup failed (exists). Aborted...\n");
118 119 120 121 122 123
    }
    if ($sth->num_rows() != 1) {
      print STDERR "Node $pc doesn't exist. Skipping $pc.\n";
      next;
    }
    
124
    print STDERR "Checking if $pc is reserved...";
125
    $sth = $DB->query("select * from reserved where node_id='$pc'");
126 127 128
    if ($sth == 0) {
	die("Database lookup failed (reserved). Aborted...\n");
    }
129 130 131

    my $allocated = 0;
   
132 133
    if ( ($sth->num_rows()) < 1) {
        print STDERR "Available.\nReserving and adding to list.\n";
134 135 136 137
	#
	# XXX If you change testbed/reloading, be sure to update the
	#     test in doreboot() in tmcd/tmcd.c.
	# 
138 139 140 141
	my $cmd = "$TB/nalloc testbed reloading $pc";
        if ( system($cmd) != 0 ) {
	    print STDERR "WARNING: Could not reserve $pc!\n";
	} else {
142 143 144 145 146 147
	    #
	    # Kill the last_reservation so that whoever gets the node next
	    # won't be fooled into thinking a reload is required.
	    #
	    $sth = $DB->query("delete from last_reservation ".
			      "where node_id='$pc'");
148
	    push (@load_list,$pc);
149
	    $allocated = 1;
150 151 152 153
	}
    } else {
        print STDERR "Reserved.\n";      
    }
154 155 156 157 158 159 160 161 162 163

    #
    # If force and not able to reserve, do not pend a reload.
    # 
    if ($force && !$allocated) {
	$error++;
	next;
    }

    # Put it in the reloads table so TMCD knows to free it.
164
    print STDERR "Scheduling reload of $imageid for $pc:\n";
165
    $sth = $DB->query("replace into reloads ".
166
		      "(node_id, image_id) values ('$pc', '$imageid')");
167 168 169
    if ($sth == 0) {
      die("Database update failed (reloads). Aborted...\n");
    }
170 171 172 173
}

if (@load_list > 0) {
  print STDERR "Running os_load on ",join(", ",@load_list),":\n";
174
  $cmd = "$osload $imageid @load_list";
175 176 177 178 179 180 181
  print STDERR "Calling '$cmd'\n";
  if ( system($cmd) != 0 ) {
    print STDERR "WARNING: OS_LOAD FAILED ON @load_list!\n";
  }
}

print STDOUT "Reload Scheduling Done!\n";
182
exit $error;