Manage corrupted file sessions (#557)

This commit is contained in:
Clément Oudot 2012-10-30 15:22:36 +00:00
parent c9d4a11022
commit ea916ecdce
2 changed files with 59 additions and 8 deletions

View File

@ -12,7 +12,7 @@ use AutoLoader 'AUTOLOAD';
use Apache::Session;
use base qw(Apache::Session);
our $VERSION = '1.0.2';
our $VERSION = '1.2.3';
sub _load {
my $backend = shift;
@ -176,15 +176,24 @@ sub _FileGKFAS {
open F, "$args->{Directory}/$f";
my $row = join '', <F>;
if ( ref($data) eq 'CODE' ) {
$res{$f} = &$data( Storable::thaw($row), $f );
eval { $res{$f} = &$data( Storable::thaw($row), $f ); };
if ($@) {
$res{$f} = &$data( undef, $f );
}
}
elsif ($data) {
$data = [$data] unless ( ref($data) );
my $tmp = Storable::thaw($row);
$res{$f}->{$_} = $tmp->{$_} foreach (@$data);
my $tmp;
eval { $tmp = Storable::thaw($row); };
if ($@) {
$res{$f}->{$_} = undef foreach (@$data);
}
else {
$res{$f}->{$_} = $tmp->{$_} foreach (@$data);
}
}
else {
$res{$f} = Storable::thaw($row);
eval { $res{$f} = Storable::thaw($row); };
}
}
return \%res;

View File

@ -14,11 +14,17 @@ use Lemonldap::NG::Common::Apache::Session;
use strict;
use Getopt::Std;
# Options
# -d: debug mode
# -f: force delete of corrupted sessions
our $opt_d;
getopts('d');
our $opt_f;
getopts('df');
my $debug = $opt_d;
my $force = $opt_f;
my $nb_purged = 0;
my $nb_error = 0;
#=============================================================================
# Load configuration
@ -99,6 +105,13 @@ for my $options (@backends) {
print "Check session $id\n" if $debug;
# Empty session need to be removed
unless ($entry) {
push @t, $id;
print "Session $id is empty (corrupted?), delete forced\n"
if $debug;
}
# Do net check sessions without _utime
return undef unless $entry->{_utime};
@ -121,16 +134,23 @@ for my $options (@backends) {
);
# Delete sessions
my @errors;
for my $id (@t) {
my %h;
eval { tie %h, "Lemonldap::NG::Common::Apache::Session", $id, $options };
if ($@) {
print "Error while opening session $id: $@\n" if $debug;
print STDERR "Error on session $id\n";
$nb_error++;
push @errors, $id;
next;
}
eval { tied(%h)->delete; };
if ($@) {
print "Error while deleting session $id: $@\n" if $debug;
print STDERR "Error on session $id\n";
$nb_error++;
push @errors, $id;
next;
}
print "Session $id has been purged\n" if $debug;
@ -144,10 +164,32 @@ for my $options (@backends) {
my $lock_directory = $options->{LockDirectory} || $options->{Directory};
$l->clean( $lock_directory, $conf->{timeout} );
}
# Force deletion of corrupted sessions for File backend
if ( $options->{backend} =~ /^Apache::Session::(?:Browseable::)?File$/i
and $force )
{
foreach (@errors) {
my $id = $_;
eval { unlink $options->{Directory} . "/$id"; };
if ($@) {
print STDERR "Unable to remove session $id\n";
}
else {
print STDERR "Session $id removed with force\n";
$nb_error--;
}
}
}
}
#=============================================================================
# Exit with success
# Exit
#=============================================================================
print "$nb_purged sessions have been purged\n" if $debug;
exit 0;
print STDERR
"$nb_error sessions remaining, try to purge them with force (option -f)\n"
if $nb_error;
my $exit = $nb_error ? 1 : 0;
exit $exit;