mirror of https://github.com/digint/btrbk
btrbk: continue gracefully (skip instead of abort) when resuming subvolume having existing (possibly garbled) target; cosmetics on debug/trace log
parent
ec9dd761b8
commit
9afe17f738
42
btrbk
42
btrbk
|
@ -1871,7 +1871,7 @@ sub get_receive_targets($$;@)
|
||||||
}
|
}
|
||||||
push(@ret, $_);
|
push(@ret, $_);
|
||||||
}
|
}
|
||||||
DEBUG "Found " . scalar(@ret) . " receive targets in \"$droot->{PRINT}/\" for: $src_vol->{PRINT}";
|
TRACE "get_receive_targets: " . scalar(@ret) . " receive targets in \"$droot->{PRINT}/\" for: $src_vol->{PRINT}";
|
||||||
return @ret;
|
return @ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2679,12 +2679,11 @@ sub macro_archive_target($$$;$)
|
||||||
# return undef;
|
# return undef;
|
||||||
# }
|
# }
|
||||||
|
|
||||||
foreach my $dvol (@{vinfo_subvol_list($droot, sort => 'path')})
|
# add all present archives as informative_only: these are needed for correct results of schedule()
|
||||||
|
foreach my $dvol (@{vinfo_subvol_list($droot)})
|
||||||
{
|
{
|
||||||
next unless($dvol->{btrbk_direct_leaf} && ($dvol->{BTRBK_BASENAME} eq $snapshot_name));
|
next unless($dvol->{btrbk_direct_leaf} && ($dvol->{BTRBK_BASENAME} eq $snapshot_name));
|
||||||
next unless($dvol->{node}{readonly});
|
next unless($dvol->{node}{readonly});
|
||||||
# add all present archives to schedule, with no value.
|
|
||||||
# these are needed for correct results of schedule()
|
|
||||||
push @schedule, { informative_only => 1,
|
push @schedule, { informative_only => 1,
|
||||||
value => $dvol,
|
value => $dvol,
|
||||||
btrbk_date => $dvol->{BTRBK_DATE},
|
btrbk_date => $dvol->{BTRBK_DATE},
|
||||||
|
@ -2877,21 +2876,20 @@ sub schedule(@)
|
||||||
$count_defined++ unless($href->{informative_only});
|
$count_defined++ unless($href->{informative_only});
|
||||||
if($href->{preserve}) {
|
if($href->{preserve}) {
|
||||||
push(@preserve, $href->{value}) unless($href->{informative_only});
|
push(@preserve, $href->{value}) unless($href->{informative_only});
|
||||||
DEBUG "Schedule: $href->{name}: $href->{preserve}" if($href->{name});
|
|
||||||
push @$results_list, { %result_base,
|
push @$results_list, { %result_base,
|
||||||
action => $href->{informative_only} ? 'seen' : $result_preserve_action_text,
|
action => $href->{informative_only} ? 'seen' : $result_preserve_action_text,
|
||||||
reason => $href->{preserve},
|
reason => $href->{preserve},
|
||||||
value => $href->{value},
|
value => $href->{value},
|
||||||
} if($results_list);
|
} if($results_list);
|
||||||
|
TRACE "schedule: $href->{value}->{PRINT}: " . ($href->{informative_only} ? '(informative_only)' : '') . " $href->{preserve}" if($href->{value} && $href->{value}->{PRINT});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
push(@delete, $href->{value}) unless($href->{informative_only});
|
push(@delete, $href->{value}) unless($href->{informative_only});
|
||||||
DEBUG "Schedule: $href->{name}: delete" if($href->{name});
|
|
||||||
push @$results_list, { %result_base,
|
push @$results_list, { %result_base,
|
||||||
action => $result_delete_action_text,
|
action => $result_delete_action_text,
|
||||||
value => $href->{value},
|
value => $href->{value},
|
||||||
} if($results_list);
|
} if($results_list);
|
||||||
|
TRACE "schedule: $href->{value}->{PRINT}: delete ($result_delete_action_text)" if($href->{value} && $href->{value}->{PRINT});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DEBUG "Preserving " . @preserve . "/" . $count_defined . " items";
|
DEBUG "Preserving " . @preserve . "/" . $count_defined . " items";
|
||||||
|
@ -3594,7 +3592,7 @@ MAIN:
|
||||||
|
|
||||||
print join("\n", @out);
|
print join("\n", @out);
|
||||||
|
|
||||||
if($exit_status) {
|
if($exit_status || scalar(@unrecoverable)) {
|
||||||
print "\nNOTE: Some errors occurred, which may result in missing backups!\n";
|
print "\nNOTE: Some errors occurred, which may result in missing backups!\n";
|
||||||
print "Please check warning and error messages above.\n";
|
print "Please check warning and error messages above.\n";
|
||||||
print join("\n", @unrecoverable) . "\n" if(@unrecoverable);
|
print join("\n", @unrecoverable) . "\n" if(@unrecoverable);
|
||||||
|
@ -4515,10 +4513,9 @@ MAIN:
|
||||||
my $warning_seen = [];
|
my $warning_seen = [];
|
||||||
my @receive_targets = get_receive_targets($droot, $child, exact_match => 1, warn => 1, seen => $warning_seen );
|
my @receive_targets = get_receive_targets($droot, $child, exact_match => 1, warn => 1, seen => $warning_seen );
|
||||||
get_receive_targets_fsroot($droot, $child, exclude => $warning_seen, warn => 1); # warn on unexpected on fs
|
get_receive_targets_fsroot($droot, $child, exclude => $warning_seen, warn => 1); # warn on unexpected on fs
|
||||||
next if(scalar(@receive_targets));
|
if(scalar(@receive_targets)){
|
||||||
|
DEBUG "Found receive target of: $child->{PRINT}";
|
||||||
if(my $err_vol = vinfo_subvol($droot, $child->{NAME})) {
|
next;
|
||||||
WARN "Target subvolume \"$err_vol->{PRINT}\" exists, but is not a receive target of \"$child->{PRINT}\"";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG "Adding backup candidate: $child->{PRINT}";
|
DEBUG "Adding backup candidate: $child->{PRINT}";
|
||||||
|
@ -4532,10 +4529,8 @@ MAIN:
|
||||||
if(scalar @schedule)
|
if(scalar @schedule)
|
||||||
{
|
{
|
||||||
DEBUG "Checking schedule for backup candidates";
|
DEBUG "Checking schedule for backup candidates";
|
||||||
# add all present backups to schedule, with no value
|
# add all present backups as informative_only: these are needed for correct results of schedule()
|
||||||
# these are needed for correct results of schedule()
|
|
||||||
foreach my $vol (@{vinfo_subvol_list($droot)}) {
|
foreach my $vol (@{vinfo_subvol_list($droot)}) {
|
||||||
next unless($vol->{node}{readonly});
|
|
||||||
unless($vol->{btrbk_direct_leaf} && ($vol->{BTRBK_BASENAME} eq $snapshot_basename)) {
|
unless($vol->{btrbk_direct_leaf} && ($vol->{BTRBK_BASENAME} eq $snapshot_basename)) {
|
||||||
TRACE "Receive target does not match btrbk filename scheme, skipping: $vol->{PRINT}";
|
TRACE "Receive target does not match btrbk filename scheme, skipping: $vol->{PRINT}";
|
||||||
next;
|
next;
|
||||||
|
@ -4554,7 +4549,20 @@ MAIN:
|
||||||
|
|
||||||
foreach my $child (sort { $a->{node}{cgen} <=> $b->{node}{cgen} } @resume)
|
foreach my $child (sort { $a->{node}{cgen} <=> $b->{node}{cgen} } @resume)
|
||||||
{
|
{
|
||||||
INFO "Creating subvolume backup (send-receive) for: $child->{PRINT}";
|
# Continue gracefully (skip instead of abort) on existing (possibly garbled) target
|
||||||
|
my $err_vol = vinfo_subvol($droot, $child->{NAME});
|
||||||
|
if($err_vol) {
|
||||||
|
my $status_msg = "Please delete stray subvolume (\"btrbk clean\"): $err_vol->{PRINT}";
|
||||||
|
WARN "Target subvolume \"$err_vol->{PRINT}\" exists, but is not a receive target of \"$child->{PRINT}\"";
|
||||||
|
WARN $status_msg;
|
||||||
|
WARN "Skipping backup of: $child->{PRINT}";
|
||||||
|
$droot->{SUBVOL_RECEIVED} //= [];
|
||||||
|
push(@{$droot->{SUBVOL_RECEIVED}}, { ERROR => $status_msg, received_subvolume => $err_vol });
|
||||||
|
$droot->{CONFIG}->{UNRECOVERABLE} = $status_msg;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
INFO "Creating subvolume backup (send-receive) for: $child->{PRINT}";
|
||||||
my ($latest_common_src, $latest_common_target) = get_latest_common($sroot, $child, $droot, $snapdir);
|
my ($latest_common_src, $latest_common_target) = get_latest_common($sroot, $child, $droot, $snapdir);
|
||||||
if(macro_send_receive(source => $child,
|
if(macro_send_receive(source => $child,
|
||||||
target => $droot,
|
target => $droot,
|
||||||
|
@ -4778,7 +4786,7 @@ MAIN:
|
||||||
if($preserve_backups || $resume_only) {
|
if($preserve_backups || $resume_only) {
|
||||||
print "\nNOTE: Preserved all snapshots and backups (option -p or -r present)\n";
|
print "\nNOTE: Preserved all snapshots and backups (option -p or -r present)\n";
|
||||||
}
|
}
|
||||||
if($exit_status) {
|
if($exit_status || scalar(@unrecoverable)) {
|
||||||
print "\nNOTE: Some errors occurred, which may result in missing backups!\n";
|
print "\nNOTE: Some errors occurred, which may result in missing backups!\n";
|
||||||
print "Please check warning and error messages above.\n";
|
print "Please check warning and error messages above.\n";
|
||||||
print join("\n", @unrecoverable) . "\n" if(@unrecoverable);
|
print join("\n", @unrecoverable) . "\n" if(@unrecoverable);
|
||||||
|
|
Loading…
Reference in New Issue