X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=rt%2Flib%2FRT%2FInterface%2FWeb%2FSession.pm;h=d854130b695ad81be4902150b54426f851dfb6c1;hp=4edd9bd2e7b64c67268d725b812fc8cdc1da05b2;hb=919e930aa9279b3c5cd12b593889cd6de79d67bf;hpb=7588a4ac90a9b07c08a3107cd1107d773be1c991 diff --git a/rt/lib/RT/Interface/Web/Session.pm b/rt/lib/RT/Interface/Web/Session.pm index 4edd9bd2e..d854130b6 100644 --- a/rt/lib/RT/Interface/Web/Session.pm +++ b/rt/lib/RT/Interface/Web/Session.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -192,7 +192,7 @@ sub _ClearOldDB { die "couldn't execute query: ". $dbh->errstr unless defined $rows; } - $RT::Logger->info("successfuly deleted $rows sessions"); + $RT::Logger->info("successfully deleted $rows sessions"); return; } @@ -222,15 +222,53 @@ sub _ClearOldDir { next; } tied(%session)->delete; - $RT::Logger->info("successfuly deleted session '$id'"); + $RT::Logger->info("successfully deleted session '$id'"); } + # Apache::Session::Lock::File will clean out locks older than X, but it + # leaves around bogus locks if they're too new, even though they're + # guaranteed dead. On even just largeish installs, the accumulated number + # of them may bump into ext3/4 filesystem limits since Apache::Session + # doesn't use a fan-out tree. my $lock = Apache::Session::Lock::File->new; $lock->clean( $dir, $older_than ); + # Take matters into our own hands and clear bogus locks hanging around + # regardless of how recent they are. + $self->ClearOrphanLockFiles($dir); + return; } +=head3 ClearOrphanLockFiles + +Takes a directory in which to look for L locks +which no longer have a corresponding session file. If not provided, the +directory is taken from the session configuration data. + +=cut + +sub ClearOrphanLockFiles { + my $class = shift; + my $dir = shift || $class->Attributes->{Directory} + or return; + + if (opendir my $dh, $dir) { + for (readdir $dh) { + next unless /^Apache-Session-([0-9a-f]{32})\.lock$/; + next if -e "$dir/$1"; + + RT->Logger->debug("deleting orphaned session lockfile '$_'"); + + unlink "$dir/$_" + or warn "Failed to unlink session lockfile $dir/$_: $!"; + } + closedir $dh; + } else { + warn "Unable to open directory '$dir' for reading: $!"; + } +} + =head3 ClearByUser Checks all sessions and if user has more then one session @@ -243,6 +281,7 @@ sub ClearByUser { my $class = $self->Class; my $attrs = $self->Attributes; + my $deleted; my %seen = (); foreach my $id( @{ $self->Ids } ) { my %session; @@ -259,8 +298,10 @@ sub ClearByUser { } } tied(%session)->delete; - $RT::Logger->info("successfuly deleted session '$id'"); + $RT::Logger->info("successfully deleted session '$id'"); + $deleted++; } + $self->ClearOrphanLockFiles if $deleted; } sub TIEHASH { @@ -276,10 +317,8 @@ sub TIEHASH { eval { tie %session, $class, $id, $attrs }; eval { tie %session, $class, undef, $attrs } if $@; if ( $@ ) { - die loc("RT couldn't store your session.") . "\n" - . loc("This may mean that that the directory '[_1]' isn't writable or a database table is missing or corrupt.", - $RT::MasonSessionDir) - . "\n\n" + die "RT couldn't store your session. " + . "This may mean that that the directory '$RT::MasonSessionDir' isn't writable or a database table is missing or corrupt.\n\n" . $@; }