mirror of https://github.com/digint/btrbk
btrbk: fixed btr_tree, use it for "diff" command
parent
a5fec23a15
commit
f6c134ea1b
57
btrbk
57
btrbk
|
@ -289,50 +289,35 @@ sub btr_subvolume_find_new($$)
|
||||||
sub btr_tree($)
|
sub btr_tree($)
|
||||||
{
|
{
|
||||||
my $vol = shift;
|
my $vol = shift;
|
||||||
my $detail = btr_subvolume_detail($vol);
|
|
||||||
unless($detail && $detail->{is_root}) {
|
|
||||||
ERROR "\"$vol\" is not btrfs root!";
|
|
||||||
return undef;
|
|
||||||
}
|
|
||||||
my %tree;
|
my %tree;
|
||||||
my %id;
|
my %id;
|
||||||
foreach my $node (btr_subvolume_list($vol, subvol_only => 0))
|
foreach my $node (btr_subvolume_list($vol, subvol_only => 0))
|
||||||
{
|
{
|
||||||
TRACE "btr_tree: processing subvolid=$node->{id}";
|
TRACE "btr_tree: processing subvolid=$node->{id}";
|
||||||
|
|
||||||
# set FS_PATH
|
|
||||||
#
|
|
||||||
# NOTE: these substitutions are only valid if $root is a
|
|
||||||
# absolute path to a btrfs root volume (mounted with
|
|
||||||
# subvolumeid=0)
|
|
||||||
TRACE "btr_tree: original path: $node->{path}";
|
|
||||||
$node->{FS_PATH} = $node->{path};
|
|
||||||
if($node->{FS_PATH} =~ s/^<FS_TREE>\///) {
|
|
||||||
TRACE "btr_tree: removed <FS_TREE> portion subvolume path: $node->{FS_PATH}";
|
|
||||||
}
|
|
||||||
|
|
||||||
$node->{SUBVOL_PATH} = $node->{FS_PATH};
|
|
||||||
TRACE "btr_tree: set SUBVOL_PATH: $node->{FS_PATH}";
|
|
||||||
|
|
||||||
$node->{FS_PATH} = $vol . "/" . $node->{FS_PATH};
|
|
||||||
TRACE "btr_tree: set FS_PATH: $node->{FS_PATH}";
|
|
||||||
|
|
||||||
$id{$node->{id}} = $node;
|
$id{$node->{id}} = $node;
|
||||||
$tree{$node->{SUBVOL_PATH}} = $node;
|
|
||||||
$uuid_info{$node->{uuid}} = $node;
|
$uuid_info{$node->{uuid}} = $node;
|
||||||
|
|
||||||
if($node->{top_level} != 5)
|
if($node->{top_level} == 5)
|
||||||
{
|
{
|
||||||
# man btrfs-subvolume:
|
# man btrfs-subvolume:
|
||||||
# Also every btrfs filesystem has a default subvolume as its initially
|
# Also every btrfs filesystem has a default subvolume as its initially
|
||||||
# top-level subvolume, whose subvolume id is 5(FS_TREE).
|
# top-level subvolume, whose subvolume id is 5(FS_TREE).
|
||||||
|
|
||||||
# set child/parent node
|
$tree{$node->{id}} = $node;
|
||||||
die unless exists($id{$node->{top_level}});
|
|
||||||
die if exists($id{$node->{top_level}}->{SUBVOLUME}->{$node->{SUBVOL_PATH}});
|
|
||||||
$id{$node->{top_level}}->{SUBVOLUME}->{$node->{SUBVOL_PATH}} = $node;
|
|
||||||
$node->{TOP_LEVEL_NODE} = $id{$node->{top_level}};
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
# set SUBVOLUME / TOP_LEVEL node
|
||||||
|
die unless exists($id{$node->{top_level}});
|
||||||
|
die if exists($id{$node->{top_level}}->{SUBVOLUME}->{$node->{id}});
|
||||||
|
$id{$node->{top_level}}->{SUBVOLUME}->{$node->{id}} = $node;
|
||||||
|
$node->{TOP_LEVEL} = $id{$node->{top_level}};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# set PARENT node
|
||||||
|
foreach (values %id){
|
||||||
|
$_->{PARENT} = $uuid_info{$_->{parent_uuid}} if($_->{parent_uuid} ne "-");
|
||||||
}
|
}
|
||||||
return \%tree;
|
return \%tree;
|
||||||
}
|
}
|
||||||
|
@ -563,6 +548,20 @@ MAIN:
|
||||||
if($detail->{is_root}) { ERROR "subvolume at \"$vol\" is btrfs root!"; exit 1; }
|
if($detail->{is_root}) { ERROR "subvolume at \"$vol\" is btrfs root!"; exit 1; }
|
||||||
unless($detail->{cgen}) { ERROR "subvolume at \"$vol\" does not provide cgen"; exit 1; }
|
unless($detail->{cgen}) { ERROR "subvolume at \"$vol\" does not provide cgen"; exit 1; }
|
||||||
if($detail->{parent_uuid} eq "-") { ERROR "subvolume at \"$vol\" has no parent, aborting."; exit 1; }
|
if($detail->{parent_uuid} eq "-") { ERROR "subvolume at \"$vol\" has no parent, aborting."; exit 1; }
|
||||||
|
|
||||||
|
my $info = btr_tree($vol);
|
||||||
|
my $node = $uuid_info{$detail->{uuid}};
|
||||||
|
my $parent = $uuid_info{$detail->{parent_uuid}};
|
||||||
|
print "--------------------------------------------------------------------------------\n";
|
||||||
|
print "Showing diff for: $node->{path}\n";
|
||||||
|
print "Parent is at : $parent->{path}\n";
|
||||||
|
print "--------------------------------------------------------------------------------\n";
|
||||||
|
die unless($node->{cgen} == $detail->{cgen}); # my paranoia
|
||||||
|
unless($node->{cgen} == $parent->{gen}) { # this should always match as far as i understand btrfs send -p
|
||||||
|
WARN "generation mismatch: cgen=$node->{cgen} != parent_gen=$parent->{gen}";
|
||||||
|
}
|
||||||
|
|
||||||
|
# dump files, sorted and unique
|
||||||
my $ret = btr_subvolume_find_new($vol, $detail->{cgen});
|
my $ret = btr_subvolume_find_new($vol, $detail->{cgen});
|
||||||
my %files;
|
my %files;
|
||||||
foreach (split(/\n/, $ret)) {
|
foreach (split(/\n/, $ret)) {
|
||||||
|
|
Loading…
Reference in New Issue