add locking to Event moving and diskspace updating.
This commit is contained in:
parent
1fbb5bc0f8
commit
715adb5acb
|
@ -431,6 +431,14 @@ sub DiskSpace {
|
|||
sub MoveTo {
|
||||
my ( $self, $NewStorage ) = @_;
|
||||
|
||||
$ZoneMinder::Database::dbh->begin_work();
|
||||
$self->lock_and_load();
|
||||
# data is reloaded, so need to check that the move hasn't already happened.
|
||||
if ( $$self{StorageId} == $$NewStorage{Id} ) {
|
||||
$ZoneMinder::Database::dbh->commit();
|
||||
return "Event has already been moved by someone else.";
|
||||
}
|
||||
|
||||
my $OldStorage = $self->Storage();
|
||||
my ( $OldPath ) = ( $self->Path() =~ /^(.*)$/ ); # De-taint
|
||||
|
||||
|
@ -438,16 +446,21 @@ sub MoveTo {
|
|||
|
||||
my ( $NewPath ) = ( $NewStorage->Path() =~ /^(.*)$/ ); # De-taint
|
||||
if ( ! $$NewStorage{Id} ) {
|
||||
$ZoneMinder::Database::dbh->commit();
|
||||
return "New storage does not have an id. Moving will not happen.";
|
||||
} elsif ( !$NewPath ) {
|
||||
$ZoneMinder::Database::dbh->commit();
|
||||
return "New path ($NewPath) is empty.";
|
||||
} elsif ( ! -e $NewPath ) {
|
||||
$ZoneMinder::Database::dbh->commit();
|
||||
return "New path $NewPath does not exist.";
|
||||
} elsif ( ! -e $OldPath ) {
|
||||
$ZoneMinder::Database::dbh->commit();
|
||||
return "Old path $OldPath does not exist.";
|
||||
}
|
||||
( $NewPath ) = ( $self->Path(undef) =~ /^(.*)$/ ); # De-taint
|
||||
if ( $NewPath eq $OldPath ) {
|
||||
$ZoneMinder::Database::dbh->commit();
|
||||
return "New path and old path are the same! $NewPath";
|
||||
}
|
||||
Debug("Moving event $$self{Id} from $OldPath to $NewPath");
|
||||
|
@ -476,14 +489,22 @@ sub MoveTo {
|
|||
last;
|
||||
}
|
||||
} # end foreach file.
|
||||
return $error if $error;
|
||||
|
||||
if ( $error ) {
|
||||
$ZoneMinder::Database::dbh->commit();
|
||||
return $error;
|
||||
}
|
||||
|
||||
# Succeeded in copying all files, so we may now update the Event.
|
||||
$$self{StorageId} = $$NewStorage{Id};
|
||||
$$self{Storage} = $NewStorage;
|
||||
$error .= $self->save();
|
||||
return $error if $error;
|
||||
if ( $error ) {
|
||||
$ZoneMinder::Database::dbh->commit();
|
||||
return $error;
|
||||
}
|
||||
$self->delete_files( $OldStorage );
|
||||
$ZoneMinder::Database::dbh->commit();
|
||||
return $error;
|
||||
} # end sub MoveTo
|
||||
|
||||
|
|
|
@ -105,6 +105,44 @@ sub load {
|
|||
} # end if
|
||||
} # end sub load
|
||||
|
||||
sub lock_and_load {
|
||||
my ( $self ) = @_;
|
||||
my $type = ref $self;
|
||||
|
||||
no strict 'refs';
|
||||
my $table = ${$type.'::table'};
|
||||
if ( ! $table ) {
|
||||
Error( 'NO table for type ' . $type );
|
||||
return;
|
||||
} # end if
|
||||
my $primary_key = ${$type.'::primary_key'};
|
||||
if ( ! $primary_key ) {
|
||||
Error( 'NO primary_key for type ' . $type );
|
||||
return;
|
||||
} # end if
|
||||
|
||||
if ( ! $$self{$primary_key} ) {
|
||||
my ( $caller, undef, $line ) = caller;
|
||||
Error( (ref $self) . "::lock_and_load called without $primary_key from $caller:$line");
|
||||
return;
|
||||
|
||||
}
|
||||
#$log->debug("Object::load Loading from db $type");
|
||||
Debug("Loading $type from $table WHERE $primary_key = $$self{$primary_key}");
|
||||
my $data = $ZoneMinder::Database::dbh->selectrow_hashref( "SELECT * FROM $table WHERE $primary_key=? FOR UPDATE", {}, $$self{$primary_key} );
|
||||
if ( ! $data ) {
|
||||
if ( $ZoneMinder::Database::dbh->errstr ) {
|
||||
Error( "Failure to load Object record for $$self{$primary_key}: Reason: " . $ZoneMinder::Database::dbh->errstr );
|
||||
} else {
|
||||
Debug("No Results Loading $type from $table WHERE $primary_key = $$self{$primary_key}");
|
||||
} # end if
|
||||
} # end if
|
||||
if ( $data and %$data ) {
|
||||
@$self{keys %$data} = values %$data;
|
||||
} # end if
|
||||
} # end sub lock_and_load
|
||||
|
||||
|
||||
sub AUTOLOAD {
|
||||
my ( $self, $newvalue ) = @_;
|
||||
my $type = ref($_[0]);
|
||||
|
|
|
@ -320,8 +320,12 @@ sub checkFilter {
|
|||
|
||||
if ( $filter->{UpdateDiskSpace} ) {
|
||||
my $Event = new ZoneMinder::Event( $$event{Id}, $event );
|
||||
$ZoneMinder::Database::dbh->begin_work();
|
||||
$Event->lock_and_load();
|
||||
|
||||
$Event->DiskSpace(undef);
|
||||
$Event->save();
|
||||
$ZoneMinder::Database::dbh->commit();
|
||||
} # end if UpdateDiskSpace
|
||||
} # end foreach event
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue