Capture output in getzfsvalue and handle datasets that disappeared

Change getzfsvalue() so that if called in array context, returns the
value and the error as a two element list.  This allows the caller to
recieve the error from the zfs command.

If the dataset went away before fetching the sanoid:sync property, just
issue a warning and skip it.
This commit is contained in:
Michael Schout 2019-05-29 17:13:31 -05:00
parent 784efe2d85
commit 3892d73594
1 changed files with 18 additions and 37 deletions

55
syncoid
View File

@ -286,12 +286,18 @@ sub syncdataset {
if ($debug) { print "DEBUG: syncing source $sourcefs to target $targetfs.\n"; }
my $sync = getzfsvalue($sourcehost,$sourcefs,$sourceisroot,'syncoid:sync');
my ($sync, $error) = getzfsvalue($sourcehost,$sourcefs,$sourceisroot,'syncoid:sync');
if (!defined $sync) {
# zfs already printed the corresponding error
if (dataset_exists($sourcehost, $sourcefs, $sourceisroot) and $exitcode < 2) {
$exitcode = 2;
if ($error =~ /\bdataset does not exist\b/) {
if (!$quiet) { print "WARN Skipping dataset (dataset no longer exists): $sourcefs...\n"; }
return 0;
}
else {
# print the error out and set exit code
print "ERROR: $error\n";
if ($exitcode < 2) { $exitcode = 2 }
}
return 0;
@ -1137,47 +1143,22 @@ sub getzfsvalue {
my $mysudocmd;
if ($isroot) { $mysudocmd = ''; } else { $mysudocmd = $sudocmd; }
if ($debug) { print "$rhost $mysudocmd $zfscmd get -H $property $fsescaped\n"; }
open FH, "$rhost $mysudocmd $zfscmd get -H $property $fsescaped |";
my $value = <FH>;
close FH;
if (!defined $value) {
return undef;
}
my ($value, $error, $exit) = capture {
system("$rhost $mysudocmd $zfscmd get -H $property $fsescaped");
};
my @values = split(/\t/,$value);
$value = $values[2];
return $value;
}
sub dataset_exists {
my ($rhost, $fs, $isroot) = @_;
my $wantarray = wantarray || 0;
my $fsescaped = escapeshellparam($fs);
my $mysudocmd;
if ($isroot) {
$mysudocmd = '';
}
else {
$mysudocmd = $sudocmd;
# If we are in scalar context and there is an error, print it out.
# Otherwise we assume the caller will deal with it.
if (!$wantarray and $error) {
print "ERROR getzfsvalue $fs $property: $error\n";
}
my $command = "$rhost $mysudocmd $zfscmd get -H creation $fsescaped";
if ($debug) {
print "$command\n";
}
open my $fh, '-|', "$command 2>&1";
my $result = <$fh>;
close $fh;
if ($result =~ /dataset does not exist/) {
return 0;
}
return 1;
return $wantarray ? ($value, $error) : $value;
}
sub readablebytes {