btrbk: implemented "diff" command (print snapshot diffs)

pull/30/head
Axel Burri 2014-12-14 21:29:22 +01:00
parent 04b595a7ce
commit a5fec23a15
1 changed files with 44 additions and 4 deletions

48
btrbk
View File

@ -83,9 +83,10 @@ sub HELP_MESSAGE
print STDERR " -l LEVEL set loglevel (1=warn, 2=info, 3=debug, 4=trace)\n"; print STDERR " -l LEVEL set loglevel (1=warn, 2=info, 3=debug, 4=trace)\n";
print STDERR "\n"; print STDERR "\n";
print STDERR "commands:\n"; print STDERR "commands:\n";
print STDERR " info shows information\n"; print STDERR " info shows information\n";
print STDERR " execute perform all backups\n"; print STDERR " execute perform all backups\n";
print STDERR " dryrun don't run btrfs commands, just show what would be executed\n"; print STDERR " dryrun don't run btrfs commands, just show what would be executed\n";
print STDERR " diff <subvol> shows new files for subvol\n";
print STDERR "\n"; print STDERR "\n";
print STDERR "For additional information, see $PROJECT_HOME\n"; print STDERR "For additional information, see $PROJECT_HOME\n";
} }
@ -277,6 +278,13 @@ sub btr_subvolume_list($;@)
return @nodes; return @nodes;
} }
sub btr_subvolume_find_new($$)
{
my $vol = shift;
my $lastgen = shift;
my $ret = run_cmd("/sbin/btrfs subvolume find-new $vol $lastgen");
}
sub btr_tree($) sub btr_tree($)
{ {
@ -521,6 +529,7 @@ MAIN:
my $action_execute; my $action_execute;
my $action_info; my $action_info;
my $action_diff;
if(($command eq "execute") || ($command eq "dryrun")) { if(($command eq "execute") || ($command eq "dryrun")) {
$action_execute = 1; $action_execute = 1;
$dryrun = 1 if($command eq "dryrun"); $dryrun = 1 if($command eq "dryrun");
@ -528,12 +537,43 @@ MAIN:
elsif($command eq "info") { elsif($command eq "info") {
$action_info = 1; $action_info = 1;
} }
elsif($command eq "diff") {
$action_diff = shift @ARGV;
unless($action_diff) {
ERROR "Missing subvolume argument for \"diff\" command";
HELP_MESSAGE(0);
exit 1;
}
}
else { else {
ERROR "Unrecognized command: $command"; ERROR "Unrecognized command: $command";
HELP_MESSAGE(0); HELP_MESSAGE(0);
exit 1; exit 1;
} }
#
# print snapshot diff
#
if($action_diff)
{
my $vol = $action_diff;
my $detail = btr_subvolume_detail($vol);
unless($detail) { 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; }
if($detail->{parent_uuid} eq "-") { ERROR "subvolume at \"$vol\" has no parent, aborting."; exit 1; }
my $ret = btr_subvolume_find_new($vol, $detail->{cgen});
my %files;
foreach (split(/\n/, $ret)) {
/\S+ \S+ \S+ \S+ \S+ \S+ \S+ \S+ \S+ \S+ \S+ \S+ \S+ \S+ \S+ \S+ (\S+)/;
$files{$1} = 1;
}
print "$_\n" foreach(sort keys %files);
exit 0;
}
# #
# check jobs, fill vol_info hash # check jobs, fill vol_info hash
# #
@ -595,7 +635,7 @@ MAIN:
next unless(($_->{sroot} eq $sroot) && ($_->{svol} eq $svol)); next unless(($_->{sroot} eq $sroot) && ($_->{svol} eq $svol));
my $match = "$_->{droot}/$snapshot"; my $match = "$_->{droot}/$snapshot";
foreach (sort { $a->{FS_PATH} cmp $b->{FS_PATH} } (values $vol_info{$_->{droot}})) { foreach (sort { $a->{FS_PATH} cmp $b->{FS_PATH} } (values $vol_info{$_->{droot}})) {
print "| | # $_->{FS_PATH}\n" if($_->{FS_PATH} eq $match); print "| | |== $_->{FS_PATH}\n" if($_->{FS_PATH} eq $match);
} }
} }
} }