btrbk: find correct latest common snapshot when resuming backups. Note that we then chain the backups, assuming that the previous snapshot is automatically the parent for the next one, which is not always true

pull/30/head
Axel Burri 2015-03-31 21:45:21 +02:00
parent 679a96495a
commit 956c028435
1 changed files with 21 additions and 5 deletions

26
btrbk
View File

@ -931,18 +931,26 @@ sub get_receive_targets_by_uuid($$)
}
sub get_latest_common($$$)
sub get_latest_common($$$;$)
{
my $sroot = shift || die;
my $svol = shift || die;
my $droot = shift || die;
my $threshold_gen = shift; # skip all snapshot children with generation >= $threshold_gen
die("source subvolume info not present: $sroot") unless($vol_info{$sroot});
die("target subvolume info not present: $droot") unless($vol_info{$droot});
TRACE "get_latest_common: threshold_gen=$threshold_gen" if($threshold_gen);
# sort children of svol descending by generation
foreach my $child (sort { $b->{node}->{gen} <=> $a->{node}->{gen} } get_snapshot_children($sroot, $svol)) {
TRACE "get_latest_common: checking source snapshot: $child->{SUBVOL_PATH}";
if($threshold_gen && ($child->{node}->{gen} >= $threshold_gen)) {
TRACE "get_latest_common: skipped gen=$child->{node}->{gen} >= $threshold_gen: $child->{SUBVOL_PATH}";
next;
}
if($vol_btrfs_progs_compat{$droot}) {
# guess matches by subvolume name (node->received_uuid is not available if BTRFS_PROGS_COMPAT is set)
my $child_name = $child->{node}->{REL_PATH};
@ -1585,16 +1593,15 @@ MAIN:
WARN "Ignoring deprecated option \"receive_log\" for target: $droot"
}
my ($latest_common_src, $latest_common_target) = get_latest_common($sroot, $svol, $droot);
my $parent_snap;
$parent_snap = $latest_common_src->{FS_PATH} if($latest_common_src);
my $parent_snap = "";
# resume missing backups (resume_missing)
if(config_key($config_target, "resume_missing"))
{
INFO "Checking for missing backups of subvolume \"$sroot/$svol\" in: $droot/";
my $found_missing = 0;
foreach my $child (sort { $a->{SUBVOL_PATH} cmp $b->{SUBVOL_PATH} } get_snapshot_children($sroot, $svol))
# sort children of svol ascending by generation
foreach my $child (sort { $a->{node}->{gen} <=> $b->{node}->{gen} } get_snapshot_children($sroot, $svol))
{
last if($config_target->{ABORTED});
@ -1621,6 +1628,13 @@ MAIN:
else
{
$found_missing++;
unless($parent_snap) {
my ($latest_common_src, $latest_common_target) = get_latest_common($sroot, $svol, $droot, $child->{node}->{gen});
$parent_snap = $latest_common_src->{FS_PATH} if($latest_common_src);
DEBUG("Set latest common snapshots for: $child->{FS_PATH}: src=$parent_snap");
}
INFO "Resuming subvolume backup (send-receive) for: $child->{FS_PATH}";
if(macro_send_receive($config_target,
src => $child->{FS_PATH},
@ -1628,6 +1642,8 @@ MAIN:
parent => $parent_snap,
resume => 1, # propagated to $config_target->{subvol_received}
)) {
# NOTE: we assume that the previous snapshot is automatically the parent for the next one.
$parent_snap = $child->{FS_PATH};
DEBUG("Updated latest common snapshots for: $sroot/$svol: src=$parent_snap");
}