Commit 21413c23 authored by Gary Wong's avatar Gary Wong

Add atomic updating of existing reservations.

parent 0e3d8b99
......@@ -212,6 +212,27 @@ sub Stringify($)
return "[Reservation: $pid, ${nodes}x${type}, ${start}-${end}]";
}
sub SetStart($$)
{
my ($self, $start) = @_;
$self->{'START'} = $start;
}
sub SetEnd($$)
{
my ($self, $end) = @_;
$self->{'END'} = $end;
}
sub SetNodes($$)
{
my ($self, $nodes) = @_;
$self->{'NODES'} = $nodes;
}
sub SetNotes($$)
{
my ($self, $notes) = @_;
......@@ -281,9 +302,9 @@ sub EndTransaction($)
# consistency requirements, this is permitted ONLY inside a
# BeginTransaction()/EndTransaction() pair, following either
# admission control satisfaction or admin override.
sub Book($)
sub Book($;$)
{
my ($self) = @_;
my ($self,$idx) = @_;
my $pid = $self->pid();
my $pid_idx = $self->pid_idx();
......@@ -296,9 +317,7 @@ sub Book($)
my $notes = DBQuoteSpecial( $self->notes() );
my $admin_notes = DBQuoteSpecial( $self->admin_notes() );
my $query_result =
DBQueryWarn( "INSERT INTO future_reservations SET " .
"pid='$pid', " .
my $base_query = "SET pid='$pid', " .
"pid_idx='$pid_idx', " .
"nodes='$nodes', " .
"type='$type', " .
......@@ -308,8 +327,13 @@ sub Book($)
"uid_idx='$uid_idx' " .
( defined( $notes ) ? ", notes=$notes" : "" ) .
( defined( $admin_notes ) ?
", admin_notes=$admin_notes" : "" ) )
or return -1;
", admin_notes=$admin_notes" : "" );
my $query_result =
DBQueryWarn( defined( $idx ) ? "UPDATE future_reservations " .
$base_query . " WHERE idx='$idx'" :
"INSERT INTO future_reservations " . $base_query )
or return -1;
$self->{'IDX'} = $query_result->insertid();
$self->{'CREATED'} = time();
......@@ -506,11 +530,12 @@ sub LookupAll($$)
}
$query_result = DBQueryWarn( "SELECT pid, uid, UNIX_TIMESTAMP( start ), " .
"UNIX_TIMESTAMP( end ), nodes FROM " .
"UNIX_TIMESTAMP( end ), nodes, idx FROM " .
"future_reservations WHERE type='$type'" );
while( my ($pid, $uid, $start, $end, $nodes) =
while( my ($pid, $uid, $start, $end, $nodes, $idx) =
$query_result->fetchrow_array() ) {
my $res = Create( $class, $pid, $uid, $start, $end, $type, $nodes );
$res->{'IDX'} = $idx;
push( @reservations, $res );
}
......
......@@ -48,6 +48,8 @@ sub usage()
print STDERR "Usage: reserve [-C] [-f] [-n] -t type [-s start] [-e end]\n" .
" [-u] [-U uid] [-N file] [-A file] pid count\n";
print STDERR " reserve -c idx\n";
print STDERR " reserve [-f] [-n] [-s start] [-e end] [-u]\n" .
" [-U uid] [-N file] [-A file] [-S size] -m idx \n";
print STDERR " reserve [-u] -i pid\n";
print STDERR " reserve [-u] -l\n";
print STDERR " -h This message\n";
......@@ -63,10 +65,12 @@ sub usage()
print STDERR " -l List all existing reservations\n";
print STDERR " -s Start time when reservation begins\n";
print STDERR " -e End time when reservation expires\n";
print STDERR " -m Modify existing reservation\n";
print STDERR " -S Specify new size of modified reservation\n";
exit( -1 );
}
my $optlist = "c:de:fhilns:t:uA:CN:U:T:";
my $optlist = "c:de:fhilm:ns:t:uA:CN:S:U:T:";
my $debug = 0;
my $info = 0;
my $list = 0;
......@@ -74,6 +78,7 @@ my $clear = 0;
my $clear_idx = undef;
my $force = 0;
my $impotent = 0;
my $modify_idx = undef;
my $starttime = time; # default to starting immediately
my $endtime = time + 24 * 60 * 60; # default to ending tomorrow
my $notes = undef;
......@@ -143,6 +148,12 @@ if (defined($options{c})) {
fatal( "Invalid reservation index." );
}
}
if (defined($options{m})) {
$modify_idx = $options{m};
unless( $modify_idx =~ /^[0-9]+$/ ) {
fatal( "Invalid reservation index." );
}
}
if (defined($options{C})) {
$clear = 1;
}
......@@ -203,6 +214,12 @@ if (defined($options{"U"})) {
fatal("No such user")
if (!defined($target_user));
}
if (defined($options{S})) {
$count = $options{S};
unless( $count =~ /^[0-9]+$/ ) {
fatal( "Invalid reservation size." );
}
}
if ($info) {
usage() if( @ARGV != 1 );
......@@ -215,11 +232,26 @@ elsif( defined( $clear_idx ) ) {
usage() if(@ARGV);
}
else {
usage() if( @ARGV < 2 || !defined( $type ) );
$pid = shift(@ARGV);
$count = shift(@ARGV);
if( defined( $modify_idx ) ) {
usage() if( @ARGV || defined( $type ) );
my $oldres = Reservation->Lookup( $modify_idx );
if( !defined( $oldres ) ) {
fatal( "Could not find existing reservation." );
}
$pid = $oldres->pid();
$type = $oldres->type();
$count = $oldres->nodes() unless( defined( $count ) );
$starttime = $oldres->start() unless( defined( $starttime ) );
$endtime = $oldres->end() unless( defined( $endtime ) );
} else {
usage() if( @ARGV < 2 || !defined( $type ) );
$pid = shift(@ARGV);
$count = shift(@ARGV);
}
if( $count < 1 ) {
fatal( "Must reserve at least one node." );
}
......@@ -370,8 +402,16 @@ if ($UID == 0) {
my $uid = $target_user->uid();
my $uid_idx = $target_user->uid_idx();
my $res = Reservation->Create( $pid, $uid, $starttime, $endtime, $type,
$count );
my $res;
if( defined( $modify_idx ) ) {
$res = Reservation->Lookup( $modify_idx );
$res->SetStart( $starttime );
$res->SetEnd( $endtime );
$res->SetNodes( $count );
} else {
$res = Reservation->Create( $pid, $uid, $starttime, $endtime, $type,
$count );
}
$res->SetNotes( $notes ) if( defined( $notes ) );
$res->SetAdminNotes( $adminnotes ) if( defined( $adminnotes ) );
......@@ -380,7 +420,20 @@ print "$res\n" if( $debug );
while( 1 ) {
my $version = Reservation->GetVersion();
my $reservations = Reservation->LookupAll( $type );
push( @$reservations, $res );
if( defined( $modify_idx ) ) {
my $i;
for( $i = 0; $i < @$reservations; $i++ ) {
my $r = $$reservations[ $i ];
if( defined( $r->idx() ) && $r->idx() == $modify_idx ) {
$$reservations[ $i ] = $res;
last;
}
}
} else {
push( @$reservations, $res );
}
my $error;
if( !Reservation->IsFeasible( $reservations, \$error ) ) {
print STDERR "reserve: $error\n";
......@@ -396,7 +449,7 @@ while( 1 ) {
}
exit( 0 ) if( $impotent );
next if( !defined( Reservation->BeginTransaction( $version ) ) );
$res->Book();
$res->Book( $modify_idx );
Reservation->EndTransaction();
last;
}
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