implemented timeout for pre/post script execution and made sure environment is cleaned up after script failure

This commit is contained in:
Christoph Klaffl 2018-10-16 10:48:04 +02:00
parent 84213216ec
commit fb6608bf47
No known key found for this signature in database
GPG Key ID: FC1C525C2A47CC28
1 changed files with 42 additions and 8 deletions

50
sanoid
View File

@ -458,17 +458,21 @@ sub take_snapshots {
my $dataset = (split '@', $snap)[0];
my $snapname = (split '@', $snap)[1];
my $presnapshotfailure = 0;
my $timeout = 5;
if ($config{$dataset}{'pre_snapshot_script'} and !$args{'readonly'}) {
$ENV{'SANOID_TARGET'} = $dataset;
$ENV{'SANOID_SNAPNAME'} = $snapname;
if ($args{'verbose'}) { print "executing pre_snapshot_script '".$config{$dataset}{'pre_snapshot_script'}."' on dataset '$dataset'\n"; }
if (system($config{$dataset}{'pre_snapshot_script'}) != 0) {
warn "WARN: pre_snapshot_script failed, $?";
my $ret = runscript('pre_snapshot_script',$dataset,$timeout);
delete $ENV{'SANOID_TARGET'};
delete $ENV{'SANOID_SNAPNAME'};
if ($ret != 0) {
# warning was already thrown by runscript function
$config{$dataset}{'no_inconsistent_snapshot'} and next;
$presnapshotfailure = 1;
}
delete $ENV{'SANOID_TARGET'};
delete $ENV{'SANOID_SNAPNAME'};
}
if ($args{'verbose'}) { print "taking snapshot $snap\n"; }
if (!$args{'readonly'}) {
@ -482,10 +486,8 @@ sub take_snapshots {
$ENV{'SANOID_TARGET'} = $dataset;
$ENV{'SANOID_SNAPNAME'} = $snapname;
if ($args{'verbose'}) { print "executing post_snapshot_script '".$config{$dataset}{'post_snapshot_script'}."' on dataset '$dataset'\n"; }
if (system($config{$dataset}{'post_snapshot_script'}) != 0) {
warn "WARN: post_snapshot_script failed, $?";
$config{$dataset}{'no_inconsistent_snapshot'} and next;
}
runscript('post_snapshot_script',$dataset,$timeout);
delete $ENV{'SANOID_TARGET'};
delete $ENV{'SANOID_SNAPNAME'};
}
@ -1337,6 +1339,38 @@ sub removecachedsnapshots {
undef %pruned;
}
#######################################################################################################################3
#######################################################################################################################3
#######################################################################################################################3
sub runscript {
my $key=shift;
my $dataset=shift;
my $timeout=shift;
my $ret;
eval {
local $SIG{ALRM} = sub { die "alarm\n" };
alarm $timeout;
$ret = system($config{$dataset}{$key});
alarm 0;
};
if ($@) {
if ($@ eq "alarm\n") {
warn "WARN: $key didn't finish in the allowed time!";
} else {
warn "CRITICAL ERROR: $@";
}
return -1;
} else {
if ($ret != 0) {
warn "WARN: $key failed, $?";
}
}
return $ret;
}
__END__
=head1 NAME