mirror of https://github.com/digint/btrbk
btrbk: fix vinfo_inject_child() for raw targets
parent
a76512955a
commit
738178565c
49
btrbk
49
btrbk
|
@ -179,7 +179,9 @@ my %url_cache; # map URL to btr_tree node
|
||||||
my %fstab_cache; # map HOST to btrfs mount points
|
my %fstab_cache; # map HOST to btrfs mount points
|
||||||
my %uuid_cache; # map UUID to btr_tree node
|
my %uuid_cache; # map UUID to btr_tree node
|
||||||
my %realpath_cache; # map URL to realpath (symlink target)
|
my %realpath_cache; # map URL to realpath (symlink target)
|
||||||
|
|
||||||
my $tree_inject_id = 0; # fake subvolume id for injected nodes (negative)
|
my $tree_inject_id = 0; # fake subvolume id for injected nodes (negative)
|
||||||
|
my $fake_uuid_prefix = 'XXXXXXXX-XXXX-XXXX-XXXX-'; # plus 0-padded inject_id
|
||||||
|
|
||||||
my $dryrun;
|
my $dryrun;
|
||||||
my $loglevel = 1;
|
my $loglevel = 1;
|
||||||
|
@ -987,7 +989,6 @@ sub btrfs_send_to_file($$$$;@)
|
||||||
my $parent_path = $parent ? $parent->{PATH} : undef;
|
my $parent_path = $parent ? $parent->{PATH} : undef;
|
||||||
my $parent_uuid = $parent ? $parent->{node}{uuid} : undef ;
|
my $parent_uuid = $parent ? $parent->{node}{uuid} : undef ;
|
||||||
my $received_uuid = $source->{node}{uuid};
|
my $received_uuid = $source->{node}{uuid};
|
||||||
$received_uuid = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" if((not $received_uuid) && $dryrun);
|
|
||||||
die unless($received_uuid);
|
die unless($received_uuid);
|
||||||
die if($parent && !$parent_uuid);
|
die if($parent && !$parent_uuid);
|
||||||
|
|
||||||
|
@ -1329,7 +1330,7 @@ sub btr_tree_inject_node
|
||||||
$tree_inject_id -= 1;
|
$tree_inject_id -= 1;
|
||||||
$tree_root->{GEN_MAX} += 1;
|
$tree_root->{GEN_MAX} += 1;
|
||||||
|
|
||||||
my $uuid = "FAKE_UUID:" . $tree_inject_id;
|
my $uuid = sprintf("${fake_uuid_prefix}%012u", -($tree_inject_id));
|
||||||
my $node = {
|
my $node = {
|
||||||
%$detail, # make a copy
|
%$detail, # make a copy
|
||||||
TREE_ROOT => $top_node->{TREE_ROOT},
|
TREE_ROOT => $top_node->{TREE_ROOT},
|
||||||
|
@ -1703,8 +1704,30 @@ sub vinfo_inject_child
|
||||||
my $vinfo = shift;
|
my $vinfo = shift;
|
||||||
my $vinfo_child = shift;
|
my $vinfo_child = shift;
|
||||||
my $detail = shift;
|
my $detail = shift;
|
||||||
|
my $node;
|
||||||
|
my $subvol_list = $vinfo->{SUBVOL_LIST};
|
||||||
|
if($subvol_list)
|
||||||
|
{
|
||||||
|
# insert to a SUBVOL_LIST (raw targets)
|
||||||
|
$tree_inject_id -= 1;
|
||||||
|
my $uuid = sprintf("${fake_uuid_prefix}%012u", -($tree_inject_id));
|
||||||
|
$node = {
|
||||||
|
%$detail,
|
||||||
|
INJECTED => 1,
|
||||||
|
id => $tree_inject_id,
|
||||||
|
uuid => $uuid,
|
||||||
|
};
|
||||||
|
# NOTE: make sure to have all the flags set by _vinfo_subtree_list()
|
||||||
|
$vinfo_child->{subtree_depth} = 0;
|
||||||
|
$vinfo_child->{direct_leaf} = 1;
|
||||||
|
$vinfo_child->{btrbk_direct_leaf} = 1;
|
||||||
|
$uuid_cache{$uuid} = $node;
|
||||||
|
push @$subvol_list, $vinfo_child;
|
||||||
|
}
|
||||||
|
else {
|
||||||
my $node_subdir = $vinfo->{NODE_SUBDIR} ? $vinfo->{NODE_SUBDIR} . '/' : "";
|
my $node_subdir = $vinfo->{NODE_SUBDIR} ? $vinfo->{NODE_SUBDIR} . '/' : "";
|
||||||
my $node = btr_tree_inject_node($vinfo->{node}, $detail, $node_subdir . $vinfo_child->{SUBVOL_PATH});
|
$node = btr_tree_inject_node($vinfo->{node}, $detail, $node_subdir . $vinfo_child->{SUBVOL_PATH});
|
||||||
|
}
|
||||||
$vinfo_child->{node} = $node;
|
$vinfo_child->{node} = $node;
|
||||||
$url_cache{$vinfo_child->{URL}} = $node;
|
$url_cache{$vinfo_child->{URL}} = $node;
|
||||||
return $vinfo_child;
|
return $vinfo_child;
|
||||||
|
@ -1850,7 +1873,7 @@ sub get_receive_targets($$;@)
|
||||||
}
|
}
|
||||||
if($matched) {
|
if($matched) {
|
||||||
push(@all_receive_targets, $_);
|
push(@all_receive_targets, $_);
|
||||||
if($opts{exact_match}) {
|
if($opts{exact_match} && (not exists($_->{BTRBK_RAW}))) {
|
||||||
unless($_->{direct_leaf} && ($_->{NAME} eq $src_vol->{NAME})) {
|
unless($_->{direct_leaf} && ($_->{NAME} eq $src_vol->{NAME})) {
|
||||||
TRACE "get_receive_targets: $matched: skip non-exact match: $_->{PRINT}";
|
TRACE "get_receive_targets: $matched: skip non-exact match: $_->{PRINT}";
|
||||||
WARN "Receive target of \"$src_vol->{PRINT}\" exists at unexpected location: $_->{PRINT}" if($opts{warn_unexpected});
|
WARN "Receive target of \"$src_vol->{PRINT}\" exists at unexpected location: $_->{PRINT}" if($opts{warn_unexpected});
|
||||||
|
@ -2501,7 +2524,7 @@ sub macro_send_receive(@)
|
||||||
{
|
{
|
||||||
unless($dryrun) {
|
unless($dryrun) {
|
||||||
# make sure we know the source uuid
|
# make sure we know the source uuid
|
||||||
unless($source->{node}{uuid}) {
|
if($source->{node}{uuid} =~ /^$fake_uuid_prefix/) {
|
||||||
DEBUG "Fetching uuid of new subvolume: $source->{PRINT}";
|
DEBUG "Fetching uuid of new subvolume: $source->{PRINT}";
|
||||||
my $detail = btrfs_subvolume_show($source);
|
my $detail = btrfs_subvolume_show($source);
|
||||||
die unless($detail->{uuid});
|
die unless($detail->{uuid});
|
||||||
|
@ -3630,6 +3653,7 @@ MAIN:
|
||||||
elsif($target_type eq "raw")
|
elsif($target_type eq "raw")
|
||||||
{
|
{
|
||||||
DEBUG "Creating raw subvolume list: $droot->{PRINT}";
|
DEBUG "Creating raw subvolume list: $droot->{PRINT}";
|
||||||
|
$droot->{SUBVOL_LIST} = [];
|
||||||
my $ret = run_cmd(
|
my $ret = run_cmd(
|
||||||
cmd => [ 'find', $droot->{PATH} . '/', '-maxdepth', '1', '-type', 'f' ],
|
cmd => [ 'find', $droot->{PATH} . '/', '-maxdepth', '1', '-type', 'f' ],
|
||||||
rsh => $droot->{RSH},
|
rsh => $droot->{RSH},
|
||||||
|
@ -3643,7 +3667,6 @@ MAIN:
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
my @subvol_list;
|
|
||||||
my %child_uuid_list;
|
my %child_uuid_list;
|
||||||
foreach (split("\n", $ret))
|
foreach (split("\n", $ret))
|
||||||
{
|
{
|
||||||
|
@ -3668,18 +3691,13 @@ MAIN:
|
||||||
#
|
#
|
||||||
# NOTE: remote_parent_uuid in BTRBK_RAW is the "parent of the source subvolume", NOT the
|
# NOTE: remote_parent_uuid in BTRBK_RAW is the "parent of the source subvolume", NOT the
|
||||||
# "parent of the received subvolume".
|
# "parent of the received subvolume".
|
||||||
$subvol->{node} = { uuid => "FAKE_UUID:" . $subvol->{URL},
|
vinfo_inject_child($droot, $subvol, {
|
||||||
received_uuid => ($subvol->{BTRBK_RAW}->{incomplete} ? '-' : $subvol->{BTRBK_RAW}->{received_uuid}), # empty received_uuid is detected as incomplete backup
|
received_uuid => ($subvol->{BTRBK_RAW}->{incomplete} ? '-' : $subvol->{BTRBK_RAW}->{received_uuid}), # empty received_uuid is detected as incomplete backup
|
||||||
parent_uuid => undef, # correct value gets inserted below
|
parent_uuid => undef, # correct value gets inserted below
|
||||||
readonly => ($subvol->{BTRBK_RAW}->{incomplete} ? 0 : 1), # fake subvolume readonly flag (incomplete backups have readonly=0)
|
readonly => ($subvol->{BTRBK_RAW}->{incomplete} ? 0 : 1), # fake subvolume readonly flag (incomplete backups have readonly=0)
|
||||||
};
|
TARGET_TYPE => 'raw',
|
||||||
# NOTE: make sure to have all the flags set by _vinfo_subtree_list()
|
});
|
||||||
$subvol->{subtree_depth} = 0;
|
|
||||||
$subvol->{direct_leaf} = 1;
|
|
||||||
$subvol->{btrbk_direct_leaf} = 1;
|
|
||||||
$uuid_cache{$subvol->{node}{uuid}} = $subvol;
|
|
||||||
|
|
||||||
push @subvol_list, $subvol;
|
|
||||||
if($subvol->{BTRBK_RAW}->{remote_parent_uuid} ne '-') {
|
if($subvol->{BTRBK_RAW}->{remote_parent_uuid} ne '-') {
|
||||||
$child_uuid_list{$subvol->{BTRBK_RAW}->{remote_parent_uuid}} //= [];
|
$child_uuid_list{$subvol->{BTRBK_RAW}->{remote_parent_uuid}} //= [];
|
||||||
push @{$child_uuid_list{$subvol->{BTRBK_RAW}->{remote_parent_uuid}}}, $subvol;
|
push @{$child_uuid_list{$subvol->{BTRBK_RAW}->{remote_parent_uuid}}}, $subvol;
|
||||||
|
@ -3689,9 +3707,8 @@ MAIN:
|
||||||
WARN "Skipping target \"$droot->{PRINT}\": " . ABORTED($droot);
|
WARN "Skipping target \"$droot->{PRINT}\": " . ABORTED($droot);
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
my @subvol_list = @{vinfo_subvol_list($droot, sort => 'path')};
|
||||||
DEBUG "Found " . scalar(@subvol_list) . " raw subvolume backups of: $svol->{PRINT}";
|
DEBUG "Found " . scalar(@subvol_list) . " raw subvolume backups of: $svol->{PRINT}";
|
||||||
my @sorted = sort { $a->{SUBVOL_PATH} cmp $b->{SUBVOL_PATH} } @subvol_list;
|
|
||||||
$droot->{SUBVOL_LIST} = \@sorted;
|
|
||||||
|
|
||||||
# Make sure that incremental backup chains are never broken:
|
# Make sure that incremental backup chains are never broken:
|
||||||
foreach my $subvol (@subvol_list)
|
foreach my $subvol (@subvol_list)
|
||||||
|
|
Loading…
Reference in New Issue