mirror of https://github.com/digint/btrbk
btrbk: parse stderr from send/receive commands (error on /^ERROR/), as "btrfs receive" returns 0 even if nothing is received.
parent
da86557b89
commit
f526d454f7
|
@ -17,6 +17,7 @@ btrbk-current
|
||||||
* Bugfix: correctly handle "incremental no" option.
|
* Bugfix: correctly handle "incremental no" option.
|
||||||
* Bugfix: return exit status 10 instead of 0 if one or more backup
|
* Bugfix: return exit status 10 instead of 0 if one or more backup
|
||||||
tasks aborted.
|
tasks aborted.
|
||||||
|
* Better error handling for send/receive commands (close: #33).
|
||||||
* Hardened ssh_filter_btrbk.sh script: fine-grained access control,
|
* Hardened ssh_filter_btrbk.sh script: fine-grained access control,
|
||||||
restrict-path option, sudo option (close: #45).
|
restrict-path option, sudo option (close: #45).
|
||||||
|
|
||||||
|
|
42
btrbk
42
btrbk
|
@ -331,7 +331,6 @@ sub run_cmd(@)
|
||||||
$cmd .= $pipe . $_->{cmd_text};
|
$cmd .= $pipe . $_->{cmd_text};
|
||||||
$pipe = ' | ';
|
$pipe = ' | ';
|
||||||
if($_->{catch_stderr}) {
|
if($_->{catch_stderr}) {
|
||||||
$cmd .= ' 2>&1';
|
|
||||||
$catch_stderr = 1;
|
$catch_stderr = 1;
|
||||||
$filter_stderr = $_->{filter_stderr};
|
$filter_stderr = $_->{filter_stderr};
|
||||||
}
|
}
|
||||||
|
@ -344,6 +343,14 @@ sub run_cmd(@)
|
||||||
}
|
}
|
||||||
DEBUG "### $cmd";
|
DEBUG "### $cmd";
|
||||||
|
|
||||||
|
if($catch_stderr) {
|
||||||
|
if(scalar(@commands) == 1) {
|
||||||
|
$cmd .= ' 2>&1';
|
||||||
|
} else {
|
||||||
|
$cmd = '{ ' . $cmd . ' ; } 2>&1';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
my $ret = "";
|
my $ret = "";
|
||||||
$ret = `$cmd`;
|
$ret = `$cmd`;
|
||||||
chomp($ret);
|
chomp($ret);
|
||||||
|
@ -1220,8 +1227,8 @@ sub btrfs_send_receive($$$$)
|
||||||
my @send_options;
|
my @send_options;
|
||||||
my @receive_options;
|
my @receive_options;
|
||||||
push(@send_options, '-p', $parent_path) if($parent_path);
|
push(@send_options, '-p', $parent_path) if($parent_path);
|
||||||
push(@send_options, '-v') if($loglevel >= 3);
|
# push(@send_options, '-v') if($loglevel >= 3);
|
||||||
push(@receive_options, '-v') if($loglevel >= 3);
|
# push(@receive_options, '-v') if($loglevel >= 3);
|
||||||
|
|
||||||
my @cmd_pipe;
|
my @cmd_pipe;
|
||||||
push @cmd_pipe, {
|
push @cmd_pipe, {
|
||||||
|
@ -1236,16 +1243,41 @@ sub btrfs_send_receive($$$$)
|
||||||
cmd => [ qw(btrfs receive), @receive_options, $target_path . '/' ],
|
cmd => [ qw(btrfs receive), @receive_options, $target_path . '/' ],
|
||||||
rsh => $target->{RSH},
|
rsh => $target->{RSH},
|
||||||
name => "btrfs receive",
|
name => "btrfs receive",
|
||||||
|
catch_stderr => 1, # hack for shell-based run_cmd()
|
||||||
|
filter_stderr => sub { $err = $_; $_ = undef }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
my $send_receive_error = 0;
|
||||||
start_transaction("send-receive",
|
start_transaction("send-receive",
|
||||||
vinfo_prefixed_keys("target", $vol_received),
|
vinfo_prefixed_keys("target", $vol_received),
|
||||||
vinfo_prefixed_keys("source", $snapshot),
|
vinfo_prefixed_keys("source", $snapshot),
|
||||||
vinfo_prefixed_keys("parent", $parent),
|
vinfo_prefixed_keys("parent", $parent),
|
||||||
);
|
);
|
||||||
my $ret = run_cmd(@cmd_pipe);
|
my $ret = run_cmd(@cmd_pipe);
|
||||||
end_transaction("send-receive", ($dryrun ? "DRYRUN" : (defined($ret) ? "success" : "ERROR")));
|
|
||||||
|
|
||||||
unless(defined($ret)) {
|
unless(defined($ret)) {
|
||||||
|
$send_receive_error = 1;
|
||||||
|
$ret = $err; # print the errors below
|
||||||
|
}
|
||||||
|
if(defined($ret)) {
|
||||||
|
# NOTE: if "btrfs send" fails, "btrfs receive" returns 0! so we need to parse the output...
|
||||||
|
foreach(split("\n", $ret)) {
|
||||||
|
if(/^ERROR: /) {
|
||||||
|
ERROR $';
|
||||||
|
$send_receive_error = 1;
|
||||||
|
}
|
||||||
|
elsif(/^WARNING: /) {
|
||||||
|
WARN "[btrfs send/receive] (send=$snapshot_path, receive=$target_path) $'";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WARN "[btrfs send/receive] (send=$snapshot_path, receive=$target_path) $_" if($send_receive_error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
end_transaction("send-receive", ($dryrun ? "DRYRUN" : ($send_receive_error ? "ERROR" : "success")));
|
||||||
|
|
||||||
|
|
||||||
|
if($send_receive_error) {
|
||||||
ERROR "Failed to send/receive btrfs subvolume: $snapshot->{PRINT} " . ($parent_path ? "[$parent_path]" : "") . " -> $target->{PRINT}";
|
ERROR "Failed to send/receive btrfs subvolume: $snapshot->{PRINT} " . ($parent_path ? "[$parent_path]" : "") . " -> $target->{PRINT}";
|
||||||
|
|
||||||
# NOTE: btrfs-progs v3.19.1 does not delete garbled received subvolume,
|
# NOTE: btrfs-progs v3.19.1 does not delete garbled received subvolume,
|
||||||
|
|
Loading…
Reference in New Issue