diff options
author | Niko Tyni <ntyni@iki.fi> | 2008-03-19 13:36:25 +0100 |
---|---|---|
committer | Niko Tyni <ntyni@iki.fi> | 2008-03-19 13:36:25 +0100 |
commit | 2944cb07be67d87e1a93ca6abf058dd6ce23d276 (patch) | |
tree | 49853ea809a652f8412ac126d8e1a7c6401f2acd | |
parent | 3ed78f950e7bf1c1af00ab497fbf8da1959848e2 (diff) | |
download | smokeping-2944cb07be67d87e1a93ca6abf058dd6ce23d276.tar.gz smokeping-2944cb07be67d87e1a93ca6abf058dd6ce23d276.tar.xz |
unrevert the locking change, LOCK_SH should work
-rw-r--r-- | CHANGES | 3 | ||||
-rw-r--r-- | lib/Smokeping/Master.pm | 32 |
2 files changed, 22 insertions, 13 deletions
@@ -20,6 +20,9 @@ * store the slave updates in 'dyndir', defaulting to 'datadir' --niko +* change the slave update locking code so that reading works without + write access to the temporary storage file --niko + * allow SSH probe to config rsa1 key -- Walery Kokarev * make zooming work properly even for graphs generated with the diff --git a/lib/Smokeping/Master.pm b/lib/Smokeping/Master.pm index bbe5a24..7114b00 100644 --- a/lib/Smokeping/Master.pm +++ b/lib/Smokeping/Master.pm @@ -1,7 +1,7 @@ # -*- perl -*- package Smokeping::Master; use Data::Dumper; -use Storable qw(nstore dclone retrieve); +use Storable qw(nstore_fd dclone fd_retrieve); use strict; use warnings; use Fcntl qw(:flock); @@ -118,13 +118,16 @@ sub save_updates { warn "Skipping update for ${name}.${slave}.slave_cache since ". "you seem to try todo some directory magic here. Don't!"; } - elsif ( open (my $lock, '>>' , "$file.lock") ) { + else { for (my $i = 3; $i > 0; $i--){ - if ( flock($lock, LOCK_EX) ){ + my $fh; + if ( open ($fh, '+>>' , $file) and flock($fh, LOCK_EX) ){ my $existing = []; - if ( -r $file ){ - my $in = eval { retrieve $file }; + next if ! -e $file; # the reader unlinked it from under us + seek $fh, 0, 0; + if ( -s _ ){ + my $in = eval { fd_retrieve $fh }; if ($@) { #error warn "Loading $file: $@"; } else { @@ -132,16 +135,17 @@ sub save_updates { }; }; push @{$existing}, [ $slave, $time, $updatestring ]; - nstore($existing, $file); + nstore_fd($existing, $fh); + flock($fh, LOCK_UN); + close $fh; last; } else { warn "Could not lock $file ($!). Trying again for $i rounds.\n"; sleep rand(2); } + warn "Could not update $file, giving up for now."; + close $fh; } - close $lock; - } else { - warn "Could not update $file: $!"; } } }; @@ -164,10 +168,12 @@ sub get_slaveupdates { my $dir = slavedatadir($cfg); $file =~ s/^\Q$datadir\E/$dir/; - if ( -r $file and open (my $lock, '>>', "$file.lock") ) { - if ( flock $lock, LOCK_EX ){ - eval { $data = retrieve $file }; + my $fh; + if ( open ($fh, '<', $file) ) { + if ( flock $fh, LOCK_SH ){ + eval { $data = fd_retrieve $fh }; unlink $file; + flock $fh, LOCK_UN; if ($@) { #error warn "Loading $file: $@"; return $empty; @@ -175,7 +181,7 @@ sub get_slaveupdates { } else { warn "Could not lock $file. Will skip and try again in the next round. No harm done!\n"; } - close $lock; + close $fh; return $data; } return $empty; |