summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNiko Tyni <ntyni@iki.fi>2008-03-17 20:53:09 +0100
committerNiko Tyni <ntyni@iki.fi>2008-03-17 20:53:09 +0100
commit1d4de6409ce490f5b33b2187372de7ea9c9ed307 (patch)
treea4be042be25906e5e84c7ab682c96a19de849a97
parent3236c4eea1ba9de7e1dc0d2cdf232d6c9c9c728f (diff)
downloadsmokeping-1d4de6409ce490f5b33b2187372de7ea9c9ed307.tar.gz
smokeping-1d4de6409ce490f5b33b2187372de7ea9c9ed307.tar.xz
* change the slave update locking code so that reading works without
write access to the temporary storage file --niko
-rw-r--r--CHANGES3
-rw-r--r--lib/Smokeping/Master.pm32
2 files changed, 22 insertions, 13 deletions
diff --git a/CHANGES b/CHANGES
index a19f86f..79a8e80 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+* 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 f359998..f910c09 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);
@@ -105,13 +105,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 {
@@ -119,16 +122,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: $!";
}
}
};
@@ -145,10 +149,12 @@ sub get_slaveupdates {
my $file = $name . "." . $slave. ".slave_cache";
my $empty = [];
my $data;
- 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;
@@ -156,7 +162,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;