...
 
Commits (2)
......@@ -446,9 +446,9 @@ sub LookupAll($$)
return $cache{$type};
}
sub IsFeasible($$;$)
sub IsFeasible($$;$$)
{
my ($class, $reservations, $error) = @_;
my ($class, $reservations, $error, $conflicttime) = @_;
my @timeline = ();
my $free;
......@@ -511,6 +511,9 @@ sub IsFeasible($$;$)
$$error = "Insufficient free nodes at $time " .
"($needed more needed).";
}
if( ref( $conflicttime ) ) {
$$conflicttime = $event->{'t'};
}
return 0;
}
......@@ -519,6 +522,22 @@ sub IsFeasible($$;$)
return 1;
}
sub ExptTypes($) {
my ($exptidx) = @_;
my $query_result = DBQueryFatal( "SELECT DISTINCT( n.type ) FROM " .
"reserved AS r, nodes AS n WHERE " .
"r.node_id=n.node_id AND " .
"r.exptidx='$exptidx'" );
my @types;
while( my($type) = $query_result->fetchrow_array() ) {
push( @types, $type );
}
return @types;
}
#
# Attempt to adjust the expiration time of an existing slice.
#
......@@ -552,14 +571,7 @@ sub ExtendSlice($$$;$$$) {
my $exptidx = $slice->exptidx();
my $expt = Experiment->Lookup( $exptidx );
my @types;
my $query_result = DBQueryFatal( "SELECT DISTINCT( n.type ) FROM " .
"reserved AS r, nodes AS n WHERE " .
"r.node_id=n.node_id AND " .
"r.exptidx='$exptidx'" );
while( my($type) = $query_result->fetchrow_array() ) {
push( @types, $type );
}
my @types = ExptTypes( $exptidx );
while( 1 ) {
my $version = GetVersion( $class );
......@@ -592,5 +604,52 @@ sub ExtendSlice($$$;$$$) {
return $forced ? -1 : 0;
}
#
# Compute a maximum length for the time a slice could be extended.
#
# Reservation->MaxSliceExtension( $slice, $max, $error )
#
# Will put the unix time stamp in $$max and return 0 if the slice can be
# extended, or -1 with $$error set.
#
# Of course, this comes with no guarantees... for instance, somebody else
# could make a conflicting reservation/extension before this call returns,
# or before the caller has a chance to do anything useful with the result...
sub MaxSliceExtension($$$;$) {
my ($class, $slice, $max, $error) = @_;
my $cur_expire = str2time( $slice->expires() );
my $max_expire = $cur_expire + 60 * 24 * 180;
my $exptidx = $slice->exptidx();
my $expt = Experiment->Lookup( $exptidx );
my @types = ExptTypes( $exptidx );
foreach my $type ( @types ) {
my $reservations = LookupAll( $class, $type );
foreach my $res ( @$reservations ) {
if( defined( $res->pid() ) && defined( $res->eid() ) &&
$res->pid() eq $expt->pid() &&
$res->eid() eq $expt->eid() ) {
$res->{'END'} = $max_expire;
last;
}
}
IsFeasible( $class, $reservations, undef, $max_expire );
}
if( $max_expire <= $cur_expire ) {
if( ref( $error ) ) {
$$error = "No extension possible.";
}
return -1;
} else {
$$max = $max_expire;
return 0;
}
}
# _Always_ make sure that this 1 is at the end of the file...
1;
......@@ -34,13 +34,15 @@ use Getopt::Std;
#
sub usage()
{
print("Usage: nalloc [-d] [-p] <pid> <eid> <node> <node> <...>\n".
print("Usage: nalloc [-d] [-f] [-p] <pid> <eid> <node> <node> <...>\n".
" -p enables partial allocation mode\n".
" -f forces allocation, overriding admission control\n" .
" -d enables debugging output\n");
exit(-1);
}
my $optlist = "dp";
my $optlist = "dfp";
my $debug = 0;
my $force = 0;
my $partial = 0;
#
......@@ -84,6 +86,9 @@ if (! getopts($optlist, \%options)) {
if (defined($options{"d"})) {
$debug = 1;
}
if (defined($options{"f"})) {
$force = 1;
}
if (defined($options{"p"})) {
$partial = 1;
}
......@@ -262,6 +267,13 @@ foreach my $type ( keys( %types ) ) {
}
if( !Reservation->IsFeasible( $reservations, \$error ) ) {
print "Admission control violation for type $type: $error\n";
if( $force ) {
print "Forcing allocation anyway...\n";
print STDERR "WARNING: SCHEDULED RESERVATIONS ARE NOW INFEASIBLE!\n";
# FIXME notify admins about violation
} else {
# FIXME once we enforce admission control, we will abort here!
}
goto admissionfailure;
}
}
......
......@@ -5305,7 +5305,7 @@ sub AllocNodes($)
tberror("Could not move nodes to old reserved holding\n");
return -1;
}
system("$NALLOC $pid $eid @nodeids");
system("$NALLOC -f $pid $eid @nodeids");
if ($?) {
tberror("Could not move nodes back from old reserved holding\n");
return -1;
......
......@@ -309,7 +309,7 @@ foreach my $node (@nodes) {
else {
$eid = $RELOADEID;
}
my $cmd = "$nalloc $RELOADPID $eid $pc";
my $cmd = "$nalloc -f $RELOADPID $eid $pc";
if ( system($cmd) != 0 ) {
print STDERR "WARNING: Could not reserve $pc!\n";
......
......@@ -541,7 +541,7 @@ NODE: foreach my $node_id (@node_ids) {
# Put it into hwdown for now - I would put them in reloading, but I'm
# afraid the reload_daemon might do the wrong thing to them
#
system "$nalloc $pid $eid $node_id";
system "$nalloc -f $pid $eid $node_id";
#
# Remove the node from the new_ tables
......