mirror of https://github.com/digint/btrbk
btrbk: make related_nodes and correlated_nodes functions operate on nodes only
parent
dd5991099a
commit
42dd296ce7
54
btrbk
54
btrbk
|
@ -3445,7 +3445,7 @@ sub get_related_snapshots($$;$)
|
||||||
my $svol = shift // die;
|
my $svol = shift // die;
|
||||||
my $btrbk_basename = shift; # if set, also filter by direct_leaf
|
my $btrbk_basename = shift; # if set, also filter by direct_leaf
|
||||||
my @ret = map( { vinfo_resolved($_, $snaproot, btrbk_direct_leaf => $btrbk_basename) // () }
|
my @ret = map( { vinfo_resolved($_, $snaproot, btrbk_direct_leaf => $btrbk_basename) // () }
|
||||||
@{get_related_nodes($svol, readonly => 1, omit_self => 1)} );
|
@{_related_nodes($svol->{node}, readonly => 1, omit_self => 1)} );
|
||||||
|
|
||||||
if($do_trace) { TRACE "get_related_snapshots: found: $_->{PRINT}" foreach(@ret); }
|
if($do_trace) { TRACE "get_related_snapshots: found: $_->{PRINT}" foreach(@ret); }
|
||||||
DEBUG "Found " . scalar(@ret) . " related snapshots of \"$svol->{PRINT}\" in: $snaproot->{PRINT}" . (defined($btrbk_basename) ? "/$btrbk_basename.*" : "");
|
DEBUG "Found " . scalar(@ret) . " related snapshots of \"$svol->{PRINT}\" in: $snaproot->{PRINT}" . (defined($btrbk_basename) ? "/$btrbk_basename.*" : "");
|
||||||
|
@ -3455,26 +3455,26 @@ sub get_related_snapshots($$;$)
|
||||||
|
|
||||||
sub _correlated_nodes($$)
|
sub _correlated_nodes($$)
|
||||||
{
|
{
|
||||||
my $droot = shift || die;
|
my $dnode = shift || die; # any node on target filesystem
|
||||||
my $src_vol = shift || die;
|
my $snode = shift || die;
|
||||||
my @ret;
|
my @ret;
|
||||||
|
|
||||||
if($src_vol->{node}{is_root}) {
|
if($snode->{is_root}) {
|
||||||
DEBUG "Skip search for correlated targets: source subvolume is btrfs root: $src_vol->{PRINT}";
|
TRACE "Skip search for correlated targets: source subvolume is btrfs root: " . _fs_path($snode) if($do_trace);
|
||||||
return @ret;
|
return @ret;
|
||||||
}
|
}
|
||||||
unless($src_vol->{node}{readonly}) {
|
unless($snode->{readonly}) {
|
||||||
DEBUG "Skip search for correlated targets: source subvolume is not read-only: $src_vol->{PRINT}";
|
TRACE "Skip search for correlated targets: source subvolume is not read-only: " . _fs_path($snode) if($do_trace);
|
||||||
return @ret;
|
return @ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
# find matches by comparing uuid / received_uuid
|
# find matches by comparing uuid / received_uuid
|
||||||
my $uuid = $src_vol->{node}{uuid};
|
my $uuid = $snode->{uuid};
|
||||||
my $received_uuid = $src_vol->{node}{received_uuid};
|
my $received_uuid = $snode->{received_uuid};
|
||||||
$received_uuid = undef if($received_uuid eq '-');
|
$received_uuid = undef if($received_uuid eq '-');
|
||||||
|
|
||||||
my $received_uuid_hash = $droot->{node}{TREE_ROOT}{RECEIVED_UUID_HASH};
|
my $received_uuid_hash = $dnode->{TREE_ROOT}{RECEIVED_UUID_HASH};
|
||||||
my $uuid_hash = $droot->{node}{TREE_ROOT}{UUID_HASH};
|
my $uuid_hash = $dnode->{TREE_ROOT}{UUID_HASH};
|
||||||
|
|
||||||
# match uuid/received_uuid combinations
|
# match uuid/received_uuid combinations
|
||||||
my @match;
|
my @match;
|
||||||
|
@ -3485,7 +3485,7 @@ sub _correlated_nodes($$)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ret = grep($_->{readonly}, @match);
|
@ret = grep($_->{readonly}, @match);
|
||||||
TRACE "correlated_nodes: droot=\"$droot->{PRINT}/\", src_vol=\"$src_vol->{PRINT}\": [" . join(", ", map _fs_path($_),@ret) . "]" if($do_trace);
|
TRACE "correlated_nodes: dst=\"" . _fs_path($dnode) . "\", src=\"" . _fs_path($snode) . "\": [" . join(", ", map _fs_path($_),@ret) . "]" if($do_trace);
|
||||||
return @ret;
|
return @ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3498,7 +3498,7 @@ sub get_receive_targets($$;@)
|
||||||
my %opts = @_;
|
my %opts = @_;
|
||||||
my @ret;
|
my @ret;
|
||||||
|
|
||||||
my @correlated = _correlated_nodes($droot, $src_vol);
|
my @correlated = _correlated_nodes($droot->{node}, $src_vol->{node});
|
||||||
foreach (@correlated) {
|
foreach (@correlated) {
|
||||||
my $vinfo = vinfo_resolved($_, $droot); # returns undef if not below $droot
|
my $vinfo = vinfo_resolved($_, $droot); # returns undef if not below $droot
|
||||||
if(exists($_->{BTRBK_RAW})) {
|
if(exists($_->{BTRBK_RAW})) {
|
||||||
|
@ -3532,7 +3532,7 @@ sub get_best_correlated($$;@)
|
||||||
my %opts = @_;
|
my %opts = @_;
|
||||||
my $inaccessible_nodes = $opts{push_inaccessible_nodes};
|
my $inaccessible_nodes = $opts{push_inaccessible_nodes};
|
||||||
|
|
||||||
my @correlated = _correlated_nodes($droot, $src_vol); # all matching src_vol, from droot->TREE_ROOT
|
my @correlated = _correlated_nodes($droot->{node}, $src_vol->{node}); # all matching src_vol, from droot->TREE_ROOT
|
||||||
foreach (@correlated) {
|
foreach (@correlated) {
|
||||||
my $vinfo = vinfo_resolved($_, $droot); # $vinfo is within $droot
|
my $vinfo = vinfo_resolved($_, $droot); # $vinfo is within $droot
|
||||||
return [ $src_vol, $vinfo ] if($vinfo);
|
return [ $src_vol, $vinfo ] if($vinfo);
|
||||||
|
@ -3549,17 +3549,17 @@ sub get_best_correlated($$;@)
|
||||||
|
|
||||||
|
|
||||||
# returns all related readonly nodes (by parent_uuid relationship), unsorted.
|
# returns all related readonly nodes (by parent_uuid relationship), unsorted.
|
||||||
sub get_related_nodes($;@)
|
sub _related_nodes($;@)
|
||||||
{
|
{
|
||||||
my $vol = shift // die;
|
my $snode = shift // die;
|
||||||
my %opts = @_;
|
my %opts = @_;
|
||||||
TRACE "related_nodes: resolving related subvolumes of: $vol->{PATH}" if($do_trace);
|
TRACE "related_nodes: resolving related subvolumes of: " . _fs_path($snode) if($do_trace);
|
||||||
|
|
||||||
# iterate parent chain
|
# iterate parent chain
|
||||||
my @related_nodes;
|
my @related_nodes;
|
||||||
my $uuid_hash = $vol->{node}{TREE_ROOT}{UUID_HASH};
|
my $uuid_hash = $snode->{TREE_ROOT}{UUID_HASH};
|
||||||
my $parent_uuid_hash = $vol->{node}{TREE_ROOT}{PARENT_UUID_HASH};
|
my $parent_uuid_hash = $snode->{TREE_ROOT}{PARENT_UUID_HASH};
|
||||||
my $node = $vol->{node};
|
my $node = $snode;
|
||||||
my $uuid = $node->{uuid};
|
my $uuid = $node->{uuid};
|
||||||
my $abort_distance = 4096;
|
my $abort_distance = 4096;
|
||||||
|
|
||||||
|
@ -3572,7 +3572,7 @@ sub get_related_nodes($;@)
|
||||||
$distance++;
|
$distance++;
|
||||||
}
|
}
|
||||||
if($distance >= $abort_distance) {
|
if($distance >= $abort_distance) {
|
||||||
my $logmsg = "Parent UUID chain exceeds depth=$abort_distance, ignoring related parents of uuid=$uuid for: $vol->{PATH}";
|
my $logmsg = "Parent UUID chain exceeds depth=$abort_distance, ignoring related parents of uuid=$uuid for: " . _fs_path($snode);
|
||||||
DEBUG $logmsg;
|
DEBUG $logmsg;
|
||||||
WARN_ONCE $logmsg unless($opts{nowarn});
|
WARN_ONCE $logmsg unless($opts{nowarn});
|
||||||
}
|
}
|
||||||
|
@ -3587,7 +3587,7 @@ sub get_related_nodes($;@)
|
||||||
my $children = $parent_uuid_hash->{$uuid};
|
my $children = $parent_uuid_hash->{$uuid};
|
||||||
if($children) {
|
if($children) {
|
||||||
if($distance >= $abort_distance) {
|
if($distance >= $abort_distance) {
|
||||||
my $logmsg = "Parent/child relations exceed depth=$abort_distance, ignoring related children of uuid=$uuid for: $vol->{PATH}";
|
my $logmsg = "Parent/child relations exceed depth=$abort_distance, ignoring related children of uuid=$uuid for: " . _fs_path($snode);
|
||||||
DEBUG $logmsg;
|
DEBUG $logmsg;
|
||||||
WARN_ONCE $logmsg unless($opts{nowarn});
|
WARN_ONCE $logmsg unless($opts{nowarn});
|
||||||
} else {
|
} else {
|
||||||
|
@ -3621,8 +3621,8 @@ sub get_related_nodes($;@)
|
||||||
}
|
}
|
||||||
|
|
||||||
if($opts{omit_self}) {
|
if($opts{omit_self}) {
|
||||||
my $vol_node_id = $vol->{node}{id};
|
my $snode_id = $snode->{id};
|
||||||
my @filtered = grep { $_->{id} != $vol_node_id } @related_nodes;
|
my @filtered = grep { $_->{id} != $snode_id } @related_nodes;
|
||||||
TRACE "related_nodes: found total=" . scalar(@filtered) . " related readonly subvolumes" if($do_trace);
|
TRACE "related_nodes: found total=" . scalar(@filtered) . " related readonly subvolumes" if($do_trace);
|
||||||
return \@filtered;
|
return \@filtered;
|
||||||
}
|
}
|
||||||
|
@ -3671,7 +3671,7 @@ sub get_best_parent($$$;@)
|
||||||
# improvements, as this only affects extra clones.
|
# improvements, as this only affects extra clones.
|
||||||
my %c_rel_id; # map id to c_related
|
my %c_rel_id; # map id to c_related
|
||||||
my @c_related; # candidates for parent (correlated + related), unsorted
|
my @c_related; # candidates for parent (correlated + related), unsorted
|
||||||
foreach (@{get_related_nodes($svol, readonly => 1, omit_self => 1, nowarn => 1)}) {
|
foreach (@{_related_nodes($svol->{node}, readonly => 1, omit_self => 1, nowarn => 1)}) {
|
||||||
my $vinfo = vinfo_resolved($_, $resolve_sroot);
|
my $vinfo = vinfo_resolved($_, $resolve_sroot);
|
||||||
if((not $vinfo) && $source_fallback_all_mountpoints) { # related node is not under $resolve_sroot
|
if((not $vinfo) && $source_fallback_all_mountpoints) { # related node is not under $resolve_sroot
|
||||||
$vinfo = vinfo_resolved_all_mountpoints($_, $svol);
|
$vinfo = vinfo_resolved_all_mountpoints($_, $svol);
|
||||||
|
@ -3691,7 +3691,7 @@ sub get_best_parent($$$;@)
|
||||||
my @c_related_newer = sort { ($a->[0]{node}{cgen} - $cgen_ref) <=> ($b->[0]{node}{cgen} - $cgen_ref) }
|
my @c_related_newer = sort { ($a->[0]{node}{cgen} - $cgen_ref) <=> ($b->[0]{node}{cgen} - $cgen_ref) }
|
||||||
grep { $_->[0]{node}{cgen} > $cgen_ref } @c_related;
|
grep { $_->[0]{node}{cgen} > $cgen_ref } @c_related;
|
||||||
|
|
||||||
# NOTE: While get_related_nodes() returns deep parent_uuid
|
# NOTE: While _related_nodes() returns deep parent_uuid
|
||||||
# relations, there is always a chance that these relations get
|
# relations, there is always a chance that these relations get
|
||||||
# broken.
|
# broken.
|
||||||
#
|
#
|
||||||
|
@ -5755,7 +5755,7 @@ MAIN:
|
||||||
foreach my $svol (@subvol_args) {
|
foreach my $svol (@subvol_args) {
|
||||||
my $svol_gen = $svol->{node}{readonly} ? $svol->{node}{cgen} : $svol->{node}{gen};
|
my $svol_gen = $svol->{node}{readonly} ? $svol->{node}{cgen} : $svol->{node}{gen};
|
||||||
my @related = map({ vinfo_resolved_all_mountpoints($_, $svol->{VINFO_MOUNTPOINT}) // () }
|
my @related = map({ vinfo_resolved_all_mountpoints($_, $svol->{VINFO_MOUNTPOINT}) // () }
|
||||||
@{get_related_nodes($svol)}); # includes $svol
|
@{_related_nodes($svol->{node})}); # includes $svol
|
||||||
push @resolved_vol, @related;
|
push @resolved_vol, @related;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue