mirror of https://github.com/jimsalterjrs/sanoid
defer cache updates after snapshot pruning and do them after all pruning is done (waiting for the cache update lock if necessary)
This commit is contained in:
parent
06d029db68
commit
d0f1445784
74
sanoid
74
sanoid
|
|
@ -42,6 +42,7 @@ my $forcecacheupdate = 0;
|
||||||
my $cache = '/var/cache/sanoidsnapshots.txt';
|
my $cache = '/var/cache/sanoidsnapshots.txt';
|
||||||
my $cacheTTL = 900; # 15 minutes
|
my $cacheTTL = 900; # 15 minutes
|
||||||
my %snaps = getsnaps( \%config, $cacheTTL, $forcecacheupdate );
|
my %snaps = getsnaps( \%config, $cacheTTL, $forcecacheupdate );
|
||||||
|
my %pruned;
|
||||||
|
|
||||||
my %snapsbytype = getsnapsbytype( \%config, \%snaps );
|
my %snapsbytype = getsnapsbytype( \%config, \%snaps );
|
||||||
|
|
||||||
|
|
@ -233,7 +234,6 @@ sub prune_snapshots {
|
||||||
# print "found some snaps to prune!\n"
|
# print "found some snaps to prune!\n"
|
||||||
if (checklock('sanoid_pruning')) {
|
if (checklock('sanoid_pruning')) {
|
||||||
writelock('sanoid_pruning');
|
writelock('sanoid_pruning');
|
||||||
my @pruned;
|
|
||||||
foreach my $snap( @prunesnaps ){
|
foreach my $snap( @prunesnaps ){
|
||||||
if ($args{'verbose'}) { print "INFO: pruning $snap ... \n"; }
|
if ($args{'verbose'}) { print "INFO: pruning $snap ... \n"; }
|
||||||
if (iszfsbusy($path)) {
|
if (iszfsbusy($path)) {
|
||||||
|
|
@ -241,7 +241,7 @@ sub prune_snapshots {
|
||||||
} else {
|
} else {
|
||||||
if (! $args{'readonly'}) {
|
if (! $args{'readonly'}) {
|
||||||
if (system($zfs, "destroy", $snap) == 0) {
|
if (system($zfs, "destroy", $snap) == 0) {
|
||||||
push(@pruned, $snap);
|
$pruned{$snap} = 1;
|
||||||
} else {
|
} else {
|
||||||
warn "could not remove $snap : $?";
|
warn "could not remove $snap : $?";
|
||||||
}
|
}
|
||||||
|
|
@ -249,7 +249,7 @@ sub prune_snapshots {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
removelock('sanoid_pruning');
|
removelock('sanoid_pruning');
|
||||||
removecachedsnapshots(@pruned);
|
removecachedsnapshots(0);
|
||||||
} else {
|
} else {
|
||||||
print "INFO: deferring snapshot pruning - valid pruning lock held by other sanoid process.\n";
|
print "INFO: deferring snapshot pruning - valid pruning lock held by other sanoid process.\n";
|
||||||
}
|
}
|
||||||
|
|
@ -258,7 +258,9 @@ sub prune_snapshots {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# if there were any deferred cache updates,
|
||||||
|
# do them now and wait if necessary
|
||||||
|
removecachedsnapshots(1);
|
||||||
} # end prune_snapshots
|
} # end prune_snapshots
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1067,32 +1069,48 @@ sub getchilddatasets {
|
||||||
#######################################################################################################################3
|
#######################################################################################################################3
|
||||||
|
|
||||||
sub removecachedsnapshots {
|
sub removecachedsnapshots {
|
||||||
my @prunedlist = shift;
|
my $wait = shift;
|
||||||
my %pruned = map { $_ => 1 } @prunedlist;
|
|
||||||
|
|
||||||
if (checklock('sanoid_cacheupdate')) {
|
if (not %pruned) {
|
||||||
writelock('sanoid_cacheupdate');
|
return;
|
||||||
|
|
||||||
if ($args{'verbose'}) {
|
|
||||||
print "INFO: removing destroyed snapshots from cache.\n";
|
|
||||||
}
|
|
||||||
open FH, "< $cache";
|
|
||||||
my @rawsnaps = <FH>;
|
|
||||||
close FH;
|
|
||||||
|
|
||||||
open FH, "> $cache" or die 'Could not write to $cache!\n';
|
|
||||||
foreach my $snapline ( @rawsnaps ) {
|
|
||||||
my @columns = split("\t", $snapline);
|
|
||||||
my $snap = $columns[0];
|
|
||||||
print FH $snapline unless ( exists($pruned{$snap}) );
|
|
||||||
}
|
|
||||||
close FH;
|
|
||||||
|
|
||||||
removelock('sanoid_cacheupdate');
|
|
||||||
%snaps = getsnaps(\%config,$cacheTTL,$forcecacheupdate);
|
|
||||||
} else {
|
|
||||||
if ($args{'verbose'}) { print "WARN: skipping cache update (snapshot removal) - valid cache update lock held by another sanoid process.\n"; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my $unlocked = checklock('sanoid_cacheupdate');
|
||||||
|
|
||||||
|
if ($wait != 1 && not $unlocked) {
|
||||||
|
if ($args{'verbose'}) { print "INFO: deferring cache update (snapshot removal) - valid cache update lock held by another sanoid process.\n"; }
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# wait until we can get a lock to do our cache changes
|
||||||
|
while (not $unlocked) {
|
||||||
|
if ($args{'verbose'}) { print "INFO: waiting for cache update lock held by another sanoid process.\n"; }
|
||||||
|
sleep(10);
|
||||||
|
$unlocked = checklock('sanoid_cacheupdate');
|
||||||
|
}
|
||||||
|
|
||||||
|
writelock('sanoid_cacheupdate');
|
||||||
|
|
||||||
|
if ($args{'verbose'}) {
|
||||||
|
print "INFO: removing destroyed snapshots from cache.\n";
|
||||||
|
}
|
||||||
|
open FH, "< $cache";
|
||||||
|
my @rawsnaps = <FH>;
|
||||||
|
close FH;
|
||||||
|
|
||||||
|
open FH, "> $cache" or die 'Could not write to $cache!\n';
|
||||||
|
foreach my $snapline ( @rawsnaps ) {
|
||||||
|
my @columns = split("\t", $snapline);
|
||||||
|
my $snap = $columns[0];
|
||||||
|
print FH $snapline unless ( exists($pruned{$snap}) );
|
||||||
|
}
|
||||||
|
close FH;
|
||||||
|
|
||||||
|
removelock('sanoid_cacheupdate');
|
||||||
|
%snaps = getsnaps(\%config,$cacheTTL,$forcecacheupdate);
|
||||||
|
|
||||||
|
# clear hash
|
||||||
|
undef %pruned;
|
||||||
}
|
}
|
||||||
|
|
||||||
__END__
|
__END__
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue