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

Add atomic updating of existing reservations.

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