mirror of https://github.com/digint/btrbk
btrbk: extents-diff: calculate exclusive size; add "exclusive" option
parent
ea2ec1ceaa
commit
afd6f80739
118
btrbk
118
btrbk
|
@ -242,10 +242,10 @@ my %table_formats = (
|
||||||
raw => [ qw( host mount_source mount_subvol mount_point mount_subvolid id top_level cgen gen uuid parent_uuid received_uuid readonly path subvolume_path subvolume_rel_path ) ],
|
raw => [ qw( host mount_source mount_subvol mount_point mount_subvolid id top_level cgen gen uuid parent_uuid received_uuid readonly path subvolume_path subvolume_rel_path ) ],
|
||||||
},
|
},
|
||||||
|
|
||||||
extent_diff => { table => [ qw( total diff subvol ) ],
|
extent_diff => { table => [ qw( total diff -set subvol ) ],
|
||||||
long => [ qw( total diff subvol cgen gen ) ],
|
long => [ qw( total diff exclusive -set subvol cgen gen ) ],
|
||||||
raw => [ qw( total diff subvol cgen gen ) ],
|
raw => [ qw( total diff subvol cgen gen ) ],
|
||||||
RALIGN => { total=>1, diff=>1, cgen=>1, gen=>1 },
|
RALIGN => { total=>1, diff=>1, exclusive=>1, set=>1, cgen=>1, gen=>1 },
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -5397,8 +5397,17 @@ MAIN:
|
||||||
$action_extents_diff = 1;
|
$action_extents_diff = 1;
|
||||||
$fallback_default_config = 1;
|
$fallback_default_config = 1;
|
||||||
$args_expected_min = 1;
|
$args_expected_min = 1;
|
||||||
$subvol_args_init = "restrict_same_fs deny_root_subvol";
|
$subvol_args_init = "restrict_same_fs";
|
||||||
@subvol_args = @ARGV;
|
my $excl;
|
||||||
|
foreach(@ARGV) {
|
||||||
|
# subvol_arg... "exclusive" filter_arg...
|
||||||
|
if($_ eq "exclusive") {
|
||||||
|
$excl = 1;
|
||||||
|
} else {
|
||||||
|
push @subvol_args, $_;
|
||||||
|
push @filter_args, $_ if($excl);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
elsif ($command eq "origin") {
|
elsif ($command eq "origin") {
|
||||||
$action_origin = 1;
|
$action_origin = 1;
|
||||||
|
@ -5650,7 +5659,6 @@ MAIN:
|
||||||
|
|
||||||
# resolve related subvolumes
|
# resolve related subvolumes
|
||||||
my @resolved_vol;
|
my @resolved_vol;
|
||||||
$extents_diff_related = 1 if(scalar(@subvol_args) == 1); # single argument: implicit --related
|
|
||||||
if($extents_diff_related) {
|
if($extents_diff_related) {
|
||||||
# add all related subvolumes
|
# add all related subvolumes
|
||||||
foreach my $svol (@subvol_args) {
|
foreach my $svol (@subvol_args) {
|
||||||
|
@ -5678,46 +5686,84 @@ MAIN:
|
||||||
exit 1;
|
exit 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
my $prev_vol;
|
my $prev_data;
|
||||||
# sort descending by gen: crawl descending, but display ascending (unshift)
|
# sort descending by gen: crawl descending, but display ascending (unshift)
|
||||||
foreach (sort { ($b->{node}{readonly} ? $b->{node}{cgen} : $b->{node}{gen}) <=>
|
foreach my $vol (sort { ($b->{node}{readonly} ? $b->{node}{cgen} : $b->{node}{gen}) <=>
|
||||||
($a->{node}{readonly} ? $a->{node}{cgen} : $a->{node}{gen}) }
|
($a->{node}{readonly} ? $a->{node}{cgen} : $a->{node}{gen}) }
|
||||||
@resolved_vol) {
|
@resolved_vol) {
|
||||||
next if($prev_vol && ($prev_vol->{node}{id} == $_->{node}{id})); # skip duplicates
|
next if($prev_data && ($prev_data->{_vinfo}{node}{id} == $vol->{node}{id})); # skip duplicates
|
||||||
|
|
||||||
# read extents map
|
# read extents map
|
||||||
if($_->{EXTENTMAP} = read_extentmap_cache($_)) {
|
if($vol->{EXTENTMAP} = read_extentmap_cache($vol)) {
|
||||||
INFO "Using cached extents map for: $_->{PRINT}";
|
INFO "Using cached extents map for: $vol->{PRINT}";
|
||||||
} else {
|
} else {
|
||||||
$_->{EXTENTMAP} = filefrag_extentmap($_);
|
$vol->{EXTENTMAP} = filefrag_extentmap($vol);
|
||||||
write_extentmap_cache($_);
|
write_extentmap_cache($vol);
|
||||||
}
|
}
|
||||||
next unless($_->{EXTENTMAP});
|
next unless($vol->{EXTENTMAP});
|
||||||
|
|
||||||
if($prev_vol) {
|
if($prev_data) {
|
||||||
my $diff_map = extentmap_diff($prev_vol->{EXTENTMAP}, $_->{EXTENTMAP});
|
my $diff_map = extentmap_diff($prev_data->{_vinfo}{EXTENTMAP}, $vol->{EXTENTMAP});
|
||||||
|
$prev_data->{diff} = print_size(extentmap_size($diff_map));
|
||||||
unshift @data, {
|
|
||||||
total => print_size(extentmap_size($prev_vol->{EXTENTMAP})),
|
|
||||||
diff => print_size(extentmap_size($diff_map)),
|
|
||||||
cgen => $prev_vol->{node}{cgen},
|
|
||||||
gen => $prev_vol->{node}{gen},
|
|
||||||
subvol => $prev_vol->{PRINT},
|
|
||||||
};
|
|
||||||
|
|
||||||
$prev_vol->{EXTENTMAP} = undef; # release memory
|
|
||||||
}
|
}
|
||||||
$prev_vol = $_;
|
$prev_data = {
|
||||||
|
total => print_size(extentmap_size($vol->{EXTENTMAP})),
|
||||||
|
cgen => $vol->{node}{cgen},
|
||||||
|
gen => $vol->{node}{gen},
|
||||||
|
subvol => $vol->{PRINT},
|
||||||
|
_vinfo => $vol,
|
||||||
|
};
|
||||||
|
unshift @data, $prev_data;
|
||||||
}
|
}
|
||||||
unshift @data, {
|
|
||||||
total => print_size(extentmap_size($prev_vol->{EXTENTMAP})),
|
my @universe_set = map $_->{_vinfo}{EXTENTMAP}, @data;
|
||||||
cgen => $prev_vol->{node}{cgen},
|
unless(scalar(@universe_set)) {
|
||||||
gen => $prev_vol->{node}{gen},
|
ERROR "No extent map data, exiting";
|
||||||
subvol => $prev_vol->{PRINT},
|
exit -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
my @summary;
|
||||||
|
INFO "Calculating union of " . scalar(@data) . " subvolumes";
|
||||||
|
push @summary, {
|
||||||
|
a => "Union (" . scalar(@data) . " subvolumes):",
|
||||||
|
b => print_size(extentmap_size(extentmap_merge(@universe_set)))
|
||||||
};
|
};
|
||||||
|
|
||||||
INFO "Printing extents map difference (relative complement): (blocks \ blocks_on_prev_line) * blocksize";
|
# calculate "exclusive" column only if needed
|
||||||
print_formatted("extent_diff", \@data);
|
if(grep /^exclusive$/, @{$table_formats{extent_diff}{$output_format // "table"}}) {
|
||||||
|
INFO "Calculating exclusive extents for " . scalar(@data) . " subvolumes";
|
||||||
|
foreach my $d (@data) {
|
||||||
|
my $vol = $d->{_vinfo};
|
||||||
|
DEBUG "Calculating exclusive for: $vol->{PRINT}";
|
||||||
|
my @others = grep { $_ != $vol->{EXTENTMAP} } @universe_set;
|
||||||
|
$d->{exclusive} = print_size(extentmap_size(extentmap_diff($vol->{EXTENTMAP}, extentmap_merge(@others)))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(scalar(@filter_vf)) {
|
||||||
|
my @excl;
|
||||||
|
my @others;
|
||||||
|
foreach(@data) {
|
||||||
|
if(vinfo_match(\@filter_vf, $_->{_vinfo})) {
|
||||||
|
$_->{set} = "X";
|
||||||
|
push @excl, $_->{_vinfo}{EXTENTMAP};
|
||||||
|
} else {
|
||||||
|
$_->{set} = "A";
|
||||||
|
push @others, $_->{_vinfo}{EXTENTMAP};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
INFO "Calculating exclusive extents for " . scalar(@excl) . "/" . scalar(@data) . " subvolumes";
|
||||||
|
push @summary, {
|
||||||
|
a => "Exclusive data ( X \\ A ):",
|
||||||
|
b => print_size(extentmap_size(extentmap_diff(extentmap_merge(@excl), extentmap_merge(@others)))),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
INFO "Printing extents map difference (relative complement): (blocks \\ blocks-on-prev-line) * blocksize";
|
||||||
|
|
||||||
|
print_formatted("extent_diff", \@data, paragraph => 1);
|
||||||
|
print_formatted({ table => [ qw( a b ) ], RALIGN => { b=>1 } },
|
||||||
|
\@summary, output_format => "table", no_header => 1);
|
||||||
exit 0;
|
exit 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue