added ==0 or die to all system calls in sanoid and syncoid that didn't already have them

This commit is contained in:
Jim Salter 2016-05-23 18:55:42 -04:00
parent 9a6bbb350f
commit 546bfabf6d
5 changed files with 55 additions and 20 deletions

View File

@ -1,3 +1,9 @@
1.4.6 added a mollyguard to syncoid to help newbies who try to zfs create a new target dataset
before doing an initial replication, instead of letting the replication itself create
the target.
added "==0 or die" to all system() calls in syncoid.
1.4.5 altered shebang to '#!/usr/bin/env perl' for enhanced FreeBSD compatibility 1.4.5 altered shebang to '#!/usr/bin/env perl' for enhanced FreeBSD compatibility
1.4.4 merged pull requests from jjlawren for OmniOS compatibility, added --configdir=/path/to/configs CLI option to sanoid at jjlawrens' request presumably for same 1.4.4 merged pull requests from jjlawren for OmniOS compatibility, added --configdir=/path/to/configs CLI option to sanoid at jjlawrens' request presumably for same
@ -5,16 +11,18 @@
1.4.3 added SSH persistence to syncoid - using socket speeds up SSH overhead 300%! =) 1.4.3 added SSH persistence to syncoid - using socket speeds up SSH overhead 300%! =)
one extra commit to get rid of the "Exit request sent." SSH noise at the end. one extra commit to get rid of the "Exit request sent." SSH noise at the end.
1.4.2 removed -r flag for zfs destroy of pruned snapshots in sanoid, which unintentionally caused same-name child snapshots to be deleted - thank you Lenz Weber! 1.4.2 removed -r flag for zfs destroy of pruned snapshots in sanoid, which unintentionally caused same-name
child snapshots to be deleted - thank you Lenz Weber!
1.4.1 updated check_zpool() in sanoid to parse zpool list properly both pre- and post- ZoL v0.6.4 1.4.1 updated check_zpool() in sanoid to parse zpool list properly both pre- and post- ZoL v0.6.4
1.4.0 added findoid tool - find and list all versions of a given file in all available ZFS snapshots. use: findoid /path/to/file 1.4.0 added findoid tool - find and list all versions of a given file in all available ZFS snapshots.
use: findoid /path/to/file
1.3.1 whoops - prevent process_children_only from getting set from blank value in defaults 1.3.1 whoops - prevent process_children_only from getting set from blank value in defaults
1.3.0 changed monitor_children_only to process_children_only. which keeps sanoid from messing around with empty parent datasets at all. 1.3.0 changed monitor_children_only to process_children_only. which keeps sanoid from messing around with
also more thoroughly documented features in default config files. empty parent datasets at all. also more thoroughly documented features in default config files.
1.2.0 added monitor_children_only parameter to sanoid.conf for use with recursive definitions - in cases where container dataset is kept empty 1.2.0 added monitor_children_only parameter to sanoid.conf for use with recursive definitions - in cases where container dataset is kept empty

View File

@ -1 +1 @@
1.4.5 1.4.6

View File

@ -11,7 +11,7 @@ use warnings;
my $zfs = '/sbin/zfs'; my $zfs = '/sbin/zfs';
my %args = getargs(@ARGV); my %args = getargs(@ARGV);
my $progversion = '1.4.5'; my $progversion = '1.4.6';
if ($args{'version'}) { print "$progversion\n"; exit 0; } if ($args{'version'}) { print "$progversion\n"; exit 0; }

5
sanoid
View File

@ -4,7 +4,7 @@
# from http://www.gnu.org/licenses/gpl-3.0.html on 2014-11-17. A copy should also be available in this # from http://www.gnu.org/licenses/gpl-3.0.html on 2014-11-17. A copy should also be available in this
# project's Git repository at https://github.com/jimsalterjrs/sanoid/blob/master/LICENSE. # project's Git repository at https://github.com/jimsalterjrs/sanoid/blob/master/LICENSE.
my $version = '1.4.5'; my $version = '1.4.6';
use strict; use strict;
use Config::IniFiles; # read samba-style conf file use Config::IniFiles; # read samba-style conf file
@ -332,7 +332,8 @@ sub take_snapshots {
foreach my $snap ( @newsnaps ) { foreach my $snap ( @newsnaps ) {
if ($args{'verbose'}) { print "taking snapshot $snap\n"; } if ($args{'verbose'}) { print "taking snapshot $snap\n"; }
if (!$args{'readonly'}) { if (!$args{'readonly'}) {
system($zfs, "snapshot", "$snap"); system($zfs, "snapshot", "$snap") == 0
or die "CRITICAL ERROR: $zfs snapshot $snap failed, $?";
# make sure we don't end up with multiple snapshots with the same ctime # make sure we don't end up with multiple snapshots with the same ctime
sleep 1; sleep 1;
} }

50
syncoid
View File

@ -4,7 +4,7 @@
# from http://www.gnu.org/licenses/gpl-3.0.html on 2014-11-17. A copy should also be available in this # from http://www.gnu.org/licenses/gpl-3.0.html on 2014-11-17. A copy should also be available in this
# project's Git repository at https://github.com/jimsalterjrs/sanoid/blob/master/LICENSE. # project's Git repository at https://github.com/jimsalterjrs/sanoid/blob/master/LICENSE.
my $version = '1.4.5'; my $version = '1.4.6';
use strict; use strict;
use Data::Dumper; use Data::Dumper;
@ -56,7 +56,9 @@ my %avail = checkcommands();
my %snaps; my %snaps;
## break here to call replication individually so that we can loop across children separately, for recursive replication ## ## break here to call replication individually so that we ##
## can loop across children separately, for recursive ##
## replication ##
if (! $args{'recursive'}) { if (! $args{'recursive'}) {
syncdataset($sourcehost, $sourcefs, $targethost, $targetfs); syncdataset($sourcehost, $sourcefs, $targethost, $targetfs);
@ -167,7 +169,8 @@ sub syncdataset {
if (iszfsbusy($targethost,$targetfs,$targetisroot)) { if (iszfsbusy($targethost,$targetfs,$targetisroot)) {
die "Cannot sync now: $targetfs is already target of a zfs receive process.\n"; die "Cannot sync now: $targetfs is already target of a zfs receive process.\n";
} }
system($synccmd); system($synccmd) == 0
or die "CRITICAL ERROR: $synccmd failed: $?";
# now do an -I to the new sync snapshot, assuming there were any snapshots # now do an -I to the new sync snapshot, assuming there were any snapshots
# other than the new sync snapshot to begin with, of course # other than the new sync snapshot to begin with, of course
@ -190,7 +193,8 @@ sub syncdataset {
print "INFO: Updating new target filesystem with incremental $sourcefs\@$oldestsnap ... $newsyncsnap (~ $disp_pvsize):\n"; print "INFO: Updating new target filesystem with incremental $sourcefs\@$oldestsnap ... $newsyncsnap (~ $disp_pvsize):\n";
if ($debug) { print "DEBUG: $synccmd\n"; } if ($debug) { print "DEBUG: $synccmd\n"; }
system($synccmd); system($synccmd) == 0
or die "CRITICAL ERROR: $synccmd failed: $?";
# restore original readonly value to target after sync complete # restore original readonly value to target after sync complete
setzfsvalue($targethost,$targetfs,$targetisroot,'readonly',$originaltargetreadonly); setzfsvalue($targethost,$targetfs,$targetisroot,'readonly',$originaltargetreadonly);
@ -202,8 +206,9 @@ sub syncdataset {
# get current readonly status of target, then set it to on during sync # get current readonly status of target, then set it to on during sync
$originaltargetreadonly = getzfsvalue($targethost,$targetfs,$targetisroot,'readonly'); $originaltargetreadonly = getzfsvalue($targethost,$targetfs,$targetisroot,'readonly');
setzfsvalue($targethost,$targetfs,$targetisroot,'readonly','on'); setzfsvalue($targethost,$targetfs,$targetisroot,'readonly','on');
my $targetsize = getzfsvalue($targethost,$targetfs,$targetisroot,'-p used');
my $matchingsnap = getmatchingsnapshot(\%snaps); my $matchingsnap = getmatchingsnapshot($targetsize, \%snaps);
# make sure target is (still) not currently in receive. # make sure target is (still) not currently in receive.
if (iszfsbusy($targethost,$targetfs,$targetisroot)) { if (iszfsbusy($targethost,$targetfs,$targetisroot)) {
@ -229,7 +234,8 @@ sub syncdataset {
print "Sending incremental $sourcefs\@$matchingsnap ... $newsyncsnap (~ $disp_pvsize):\n"; print "Sending incremental $sourcefs\@$matchingsnap ... $newsyncsnap (~ $disp_pvsize):\n";
if ($debug) { print "DEBUG: $synccmd\n"; } if ($debug) { print "DEBUG: $synccmd\n"; }
system("$synccmd"); system("$synccmd") == 0
or die "CRITICAL ERROR: $synccmd failed: $?";
# restore original readonly value to target after sync complete # restore original readonly value to target after sync complete
setzfsvalue($targethost,$targetfs,$targetisroot,'readonly',$originaltargetreadonly); setzfsvalue($targethost,$targetfs,$targetisroot,'readonly',$originaltargetreadonly);
@ -489,7 +495,8 @@ sub setzfsvalue {
my $mysudocmd; my $mysudocmd;
if ($isroot) { $mysudocmd = ''; } else { $mysudocmd = $sudocmd; } if ($isroot) { $mysudocmd = ''; } else { $mysudocmd = $sudocmd; }
if ($debug) { print "$rhost $mysudocmd $zfscmd set $property=$value $fs\n"; } if ($debug) { print "$rhost $mysudocmd $zfscmd set $property=$value $fs\n"; }
system("$rhost $mysudocmd $zfscmd set $property=$value $fs"); system("$rhost $mysudocmd $zfscmd set $property=$value $fs") == 0
or die "CRITICAL ERROR: $rhost $mysudocmd $zfscmd set $property=$value $fs died: $?";
return; return;
} }
@ -628,7 +635,8 @@ sub pruneoldsyncsnaps {
if ($rhost ne '') { $prunecmd = '"' . $prunecmd . '"'; } if ($rhost ne '') { $prunecmd = '"' . $prunecmd . '"'; }
if ($debug) { print "DEBUG: pruning up to $maxsnapspercmd obsolete sync snapshots...\n"; } if ($debug) { print "DEBUG: pruning up to $maxsnapspercmd obsolete sync snapshots...\n"; }
if ($debug) { print "DEBUG: $rhost $prunecmd\n"; } if ($debug) { print "DEBUG: $rhost $prunecmd\n"; }
system("$rhost $prunecmd"); system("$rhost $prunecmd") == 0
or die "CRITICAL ERROR: $rhost $prunecmd failed: $?";
$prunecmd = ''; $prunecmd = '';
$counter = 0; $counter = 0;
} }
@ -640,19 +648,36 @@ sub pruneoldsyncsnaps {
if ($rhost ne '') { $prunecmd = '"' . $prunecmd . '"'; } if ($rhost ne '') { $prunecmd = '"' . $prunecmd . '"'; }
if ($debug) { print "DEBUG: pruning up to $maxsnapspercmd obsolete sync snapshots...\n"; } if ($debug) { print "DEBUG: pruning up to $maxsnapspercmd obsolete sync snapshots...\n"; }
if ($debug) { print "DEBUG: $rhost $prunecmd\n"; } if ($debug) { print "DEBUG: $rhost $prunecmd\n"; }
system("$rhost $prunecmd"); system("$rhost $prunecmd") == 0
or die "CRITICAL ERROR: $rhost $prunecmd failed: $?";
} }
return; return;
} }
sub getmatchingsnapshot { sub getmatchingsnapshot {
my $snaps = shift; my ($targetsize, $snaps) = shift;
foreach my $snap ( sort { $snaps{'source'}{$b}{'ctime'}<=>$snaps{'source'}{$a}{'ctime'} } keys %{ $snaps{'source'} }) { foreach my $snap ( sort { $snaps{'source'}{$b}{'ctime'}<=>$snaps{'source'}{$a}{'ctime'} } keys %{ $snaps{'source'} }) {
if ($snaps{'source'}{$snap}{'ctime'} == $snaps{'target'}{$snap}{'ctime'}) { if ($snaps{'source'}{$snap}{'ctime'} == $snaps{'target'}{$snap}{'ctime'}) {
return $snap; return $snap;
} }
} }
print "UNEXPECTED ERROR: target exists but has no matching snapshots!\n";
# if we got this far, we failed to find a matching snapshot.
print "\n";
print "CRITICAL ERROR: Target exists but has no matching snapshots!\n";
print " Replication to target would require destroying existing\n";
print " target. Cowardly refusing to destroy your existing target.\n\n";
# experience tells me we need a mollyguard for people who try to
# zfs create targetpool/targetsnap ; syncoid sourcepool/sourcesnap targetpool/targetsnap ...
if ( $targetsize < (64*1024*1024) ) {
print " NOTE: Target dataset is < 64MB used - did you mistakenly run\n";
print " \`zfs create $args{'target'}\` on the target? ZFS initial\n";
print " replication must be to a NON EXISTENT DATASET, which will\n";
print " then be CREATED BY the initial replication process.\n\n";
}
exit 256; exit 256;
} }
@ -665,7 +690,8 @@ sub newsyncsnap {
my %date = getdate(); my %date = getdate();
my $snapname = "syncoid\_$hostid\_$date{'stamp'}"; my $snapname = "syncoid\_$hostid\_$date{'stamp'}";
my $snapcmd = "$rhost $mysudocmd $zfscmd snapshot $fs\@$snapname\n"; my $snapcmd = "$rhost $mysudocmd $zfscmd snapshot $fs\@$snapname\n";
system($snapcmd); system($snapcmd) == 0
or die "CRITICAL ERROR: $snapcmd failed: $?";
return $snapname; return $snapname;
} }