Commit 50d257d4 authored by Mike Hibler's avatar Mike Hibler

Move storage deallocation to Lease.pm. Add wait option (-w).

parent f8cf0085
...@@ -34,16 +34,18 @@ sub usage() ...@@ -34,16 +34,18 @@ sub usage()
print STDERR "Usage: deletelease [-fhd] lname\n"; print STDERR "Usage: deletelease [-fhd] lname\n";
print STDERR " -h This message\n"; print STDERR " -h This message\n";
print STDERR " -d Print additional debug info\n"; print STDERR " -d Print additional debug info\n";
print STDERR " -f Force destruction even if lease is in transition\n"; print STDERR " -f Force destruction even if lease is not in the correct state\n";
print STDERR " -w time Try for up to time seconds to lock lease (0 means forever)\n";
print STDERR " lname Name of lease in <pid>/<id> form\n"; print STDERR " lname Name of lease in <pid>/<id> form\n";
exit(-1); exit(-1);
} }
my $optlist = "dhf"; my $optlist = "dhfw:";
my $debug = 0; my $debug = 0;
my $force = 0; my $force = 0;
my $pid; my $pid;
my $lname; my $lname;
my $lease; my $lease;
my $waittime;
# Protos # Protos
sub fatal($); sub fatal($);
...@@ -60,7 +62,6 @@ my $BSCONTROL = "$TB/sbin/bscontrol"; ...@@ -60,7 +62,6 @@ my $BSCONTROL = "$TB/sbin/bscontrol";
use lib "@prefix@/lib"; use lib "@prefix@/lib";
use libdb; use libdb;
use Lease; use Lease;
use Blockstore;
use Project; use Project;
use User; use User;
...@@ -91,6 +92,12 @@ if (defined($options{d})) { ...@@ -91,6 +92,12 @@ if (defined($options{d})) {
if (defined($options{f})) { if (defined($options{f})) {
$force = 1; $force = 1;
} }
if (defined($options{w})) {
$waittime = $options{w};
if ($waittime !~ /^\d+$/) {
fatal("Wait time must be >= 0.");
}
}
if (@ARGV != 1) { if (@ARGV != 1) {
print STDERR "Must specify exactly one lname\n"; print STDERR "Must specify exactly one lname\n";
usage(); usage();
...@@ -121,63 +128,78 @@ if (!Project->Lookup($pid) || !($lease = Lease->Lookup($pid, $lname)) || ...@@ -121,63 +128,78 @@ if (!Project->Lookup($pid) || !($lease = Lease->Lookup($pid, $lname)) ||
# #
# Lock the lease and handle cleanup. # Lock the lease and handle cleanup.
# #
if ($lease->Lock()) {
fatal("$pid/$lname: currently locked, try again later.");
}
my $ostate = $lease->state(); my $ostate = $lease->state();
if (!$force && $ostate eq "initializing") { if (!defined($waittime)) {
fatal("$pid/$lname: currently in transition, try again later."); fatal("$pid/$lname: could not acquire lock, try again with -w")
} if ($lease->Lock());
} else {
my $rv = $lease->WaitLock($waittime, 1);
# # someone else deleted it, that is okay with us
# For an approved dataset lease, we must free up the server storage if ($rv == LEASE_ERROR_GONE()) {
# print "Someone else deleted '$pid/$lname'.\n";
if ($lease->type() =~ /dataset$/ && $ostate ne "unapproved") { exit(0);
#
# Put in initializing state and unlock since this could be
# time consuming.
#
if ($lease->UpdateState("initializing")) {
fatal("$pid/$lname: could not mark lease as in-transition.");
} }
$lease->Unlock();
my $idx = $lease->lease_idx(); # any other error is fatal (maybe not if $force is set?)
if ($rv) {
fatal("$pid/$lname: could not acquire lock after $waittime seconds");
}
# #
# For efficiency, lookup the server in the blockstores table. # Warn about state changes while waiting for the lock.
# Saves gathering info from every storage server. # Note that ValidTransition will ensure we don't do anything
# really stupid in this case (e.g., lease was un-expired at the
# last second).
# #
my $bstore = Blockstore->LookupByLease($idx); my $nstate = $lease->state();
if (!$bstore) { if ($ostate ne $nstate) {
fatal("$pid/$lname: could not find blockstore object."); print STDERR
"WARNING: lease changed state while waiting for the lock".
" ($ostate => $nstate).\n";
$ostate = $nstate;
} }
my $srv = $bstore->node_id(); }
# # if the lease is in use, disallow unless forced
# Call the blockstore control program to handle all things blockstore if ($lease->InUse()) {
# related (e.g., the actual deallocation of storage on the servers). my $expts = int(@{$lease->UsingResources()});
# if (!$force) {
if (system("$BSCONTROL -S $srv destroy lease-$idx")) { fatal("$pid/$lname is in use by $expts experiment(s) right now");
$lease->UpdateState("unapproved"); }
fatal("$pid/$lname: could not deallocate storage"); print STDERR "$pid/$lname is in use by $expts experiment(s) right now,".
" continuing anyway\n";
}
# make sure we can destroy a lease from the current state.
if (!$lease->ValidTransition("DEAD")) {
if (!$force) {
fatal("$pid/$lname: cannot destroy lease from state '$ostate'.");
} }
print STDERR
"$pid/$lname: should not destroy lease from state '$ostate', ".
"continuing anyway.\n";
}
# Dealloc will put the lease back into the unapproved state
if ($lease->DeallocResources()) {
$lease->UpdateState(LEASE_STATE_LOCKED());
fatal("$pid/$lname: could not deallocate resources, left in 'locked' state.");
} }
if ($lease->Delete()) { if ($lease->Delete()) {
fatal("Could not destroy lease $pid/$lname."); fatal("$pid/$lname: could not destroy lease.");
} }
print "Deleted lease '$pid/$lname'.\n";
exit(0); exit(0);
sub fatal($) sub fatal($)
{ {
my ($mesg) = $_[0]; my ($mesg) = $_[0];
if (defined($lease) && $lease->GotLock()) { $lease->Unlock()
$lease->Unlock(); if (defined($lease) && $lease->GotLock());
}
die("*** $0:\n". die("*** $0:\n".
" $mesg\n"); " $mesg\n");
} }
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