sched_reload.in 4.04 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 | -p] <imageid> <node> [node ...]
12 13 14
#
sub usage()
{
15 16
    print STDOUT "Usage: sched_reload [-f | -p] <imageid> <node> [node ...]\n".
	"Use the -f to force reload. Fail if node cannot be reserved.\n".
17 18
	"Use the -p to pend reload for the reload daemon.\n" .
	"Use the -r use Frisbee rather than netdisk (experimental).\n";
19 20
    exit(-1);
}
21
my  $optlist = "fpr";
22 23 24 25

#
# Configure variables
#
26
my $TB     = "@prefix@";
27

28 29 30
#
# Load the Testbed support stuff. 
#
31 32
use lib "@prefix@/lib";
use libdb;
33

34
#
35
# These come from the library.
36
# 
37 38 39
my $RELOADPID	= NODERELOADING_PID;
my $RELOADEID	= NODERELOADING_EID;
my $PENDINGEID	= NODERELOADPENDING_EID;
40

41 42
my $osload      = "$TB/bin/os_load";
my $nalloc      = "$TB/bin/nalloc";
43
my $name        = "";
44 45 46
my $error       = 0;
my $debug       = 0;
my $force	= 0;
47
my $pend	= 0;
48
my $frisbee	= 0;
49
my @nodes       = ();
50
my @row;
51 52 53 54 55 56 57 58

# 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

#
59 60 61 62 63 64 65
# Parse command arguments. Once we return from getopts, all that should be
# left are the required arguments.
#
%options = ();
if (! getopts($optlist, \%options)) {
    usage();
}
66
if (@ARGV < 2) {
67
    usage();
68
}
69 70 71
if (defined($options{"f"})) {
    $force = $options{"f"};
}
72 73 74
if (defined($options{"p"})) {
    $pend = $options{"p"};
}
75 76 77 78
if (defined($options{"r"})) {
    $frisbee = 1;
	$osload .= " -r ";
}
79 80 81
if ($pend and $force) {
    usage();
}
82
my $imageid   = shift;
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103

#
# 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);
}
104

105
#
106 107
# Root and admin types can do whatever they want.
# Mere users cannot schedule reloads.
108
#
109
if ($UID && !TBAdmin($UID)) {
110 111 112 113
    die("Only root or TB administrators can schedule disk reloads.\n");
}

#
114
# A loop.
115 116 117 118
# 
my @load_list=();
foreach my $node (@nodes) {
    my $pc = $node;
119
    my $allocated = 0;
120

121
    $sth = DBQueryFatal("select * from nodes where node_id='$pc'");
122 123 124 125 126
    if ($sth->num_rows() != 1) {
      print STDERR "Node $pc doesn't exist. Skipping $pc.\n";
      next;
    }
    
127
    print STDERR "Checking if $pc is reserved...";
128
    $sth = DBQueryFatal("select * from reserved where node_id='$pc'");
129
   
130 131
    if ( ($sth->num_rows()) < 1) {
        print STDERR "Available.\nReserving and adding to list.\n";
132 133 134 135 136 137 138 139 140
	my $eid;
	if ($pend) {
	    $eid = $PENDINGEID;
	}
	else {
	    $eid = $RELOADEID;
	}
	my $cmd = "$nalloc $RELOADPID $eid $pc";

141 142 143
        if ( system($cmd) != 0 ) {
	    print STDERR "WARNING: Could not reserve $pc!\n";
	} else {
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.
	    #
148
	    DBQueryFatal("delete from last_reservation where node_id='$pc'");
149
	    push (@load_list,$pc);
150
	    $allocated = 1;
151 152 153 154
	}
    } else {
        print STDERR "Reserved.\n";      
    }
155 156 157 158 159 160 161 162 163 164

    #
    # 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.
165
    print STDERR "Scheduling reload of $imageid for $pc:\n";
166
    DBQueryFatal("replace into scheduled_reloads ".
167
		 "(node_id, image_id) values ('$pc', '$imageid')");
168 169
}

170 171 172 173 174
if ($pend) {
    print STDOUT "Reload Scheduling Done!\n";
    exit $error;
}

175 176
if (@load_list > 0) {
  print STDERR "Running os_load on ",join(", ",@load_list),":\n";
177
  $cmd = "$osload $imageid @load_list";
178 179 180 181 182 183 184
  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";
185
exit $error;